diff --git a/.github/workflows/ambarella-s3l_images.yml b/.github/workflows/ambarella-s3l_images.yml
new file mode 100644
index 00000000..b41aad8c
--- /dev/null
+++ b/.github/workflows/ambarella-s3l_images.yml
@@ -0,0 +1,141 @@
+name: "Ambarella-S3L"
+
+on:
+  push:
+    branches:
+      - production
+    tags:
+      - "v*"
+  # schedule:
+  #     - cron: "00 03 * * *"
+  workflow_dispatch:
+
+jobs:
+  build_core:
+    name: OpenIPC firmware for Ambarella-s3l
+    runs-on: ubuntu-latest
+
+    steps:
+
+      - name: Checkout
+        id: checkout
+        uses: actions/checkout@v2
+
+      - name: Install build dependencies
+        id: install
+        run: |
+          make install-deps
+          mkdir -p tmp
+
+      - name: Free disk space
+        id: freshing
+        run: |
+          sudo swapoff -a
+          sudo rm -f /swapfile
+          sudo apt clean
+          docker rmi $(docker image ls -aq)
+          df -h
+
+      - name: Prepare buildroot
+        id: prepare
+        run: |
+          HEAD_TAG=$(git tag --points-at HEAD)
+          GIT_HASH=$(git rev-parse --short $GITHUB_SHA)
+          BRANCH_NAME=$(echo $GITHUB_REF | cut -d'/' -f 3)
+          if [ -z "$HEAD_TAG" ]; then
+            TAG_NAME="latest"
+            RELEASE_NAME="Development Build"
+            PRERELEASE=true
+          else
+            TAG_NAME=${{ github.ref }}
+            RELEASE_NAME="Release ${{ github.ref }}"
+            PRERELEASE=false
+          fi
+          echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV
+          echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV
+          echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
+          echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV
+          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
+          cd $GITHUB_WORKSPACE
+          make prepare
+
+      - name: Build Ambarella-s3l firmware
+        id: build-ambarella-s3l-firmware
+        continue-on-error: true
+        run: |
+          ARCHIVE_FW="${GITHUB_WORKSPACE}/output/images/openipc.ambarella-s3l-br.tgz"
+          echo "ARCHIVE_FW=$ARCHIVE_FW" >> $GITHUB_ENV
+          cd $GITHUB_WORKSPACE
+          make PLATFORM=ambarella BOARD=unknown_unknown_s3l_openipc all
+          [[ $(stat --printf="%s" ${GITHUB_WORKSPACE}/output/images/uImage) -gt 2097152 ]] && echo "TG_NOTIFY=Warning, kernel size exceeded : $(stat --printf="%s" ${GITHUB_WORKSPACE}/output/images/uImage) vs 2097152... AMBARELLA-S3L" >> $GITHUB_ENV && exit 1
+          # [[ $(stat --printf="%s" ${GITHUB_WORKSPACE}/output/images/rootfs.squashfs) -gt 5242880 ]] && echo "TG_NOTIFY=Warning, rootfs size exceeded - $(stat --printf="%s" ${GITHUB_WORKSPACE}/output/images/rootfs.squashfs) vs 5242880... AMBARELLA-S3L" >> $GITHUB_ENV && exit 1
+          cd ${GITHUB_WORKSPACE}/output/images
+          mv uImage uImage.s3l
+          mv rootfs.squashfs rootfs.squashfs.s3l
+          mv rootfs.ubi rootfs.ubi.s3l
+          md5sum rootfs.squashfs.s3l > rootfs.squashfs.s3l.md5sum
+          md5sum rootfs.ubi.s3l > rootfs.ubi.s3l.md5sum
+          md5sum uImage.s3l > uImage.s3l.md5sum
+          tar -cvzf $ARCHIVE_FW *s3l*
+
+      - name: Build Ambarella S3L SDK
+        id: build-ambarella-s3l-sdk
+        continue-on-error: true
+        run: |
+          ARCHIVE_SDK="${GITHUB_WORKSPACE}/output/images/arm-openipc-linux-musleabi_sdk-buildroot.tar.gz"
+          echo "ARCHIVE_SDK=$ARCHIVE_SDK" >> $GITHUB_ENV
+          cd $GITHUB_WORKSPACE/output
+          make sdk
+
+      - name: Send warning message to telegram channel
+        env:
+          TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }}
+          TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }}
+        if: steps.build-ambarella-s3l-firmware.outcome != 'success' || steps.build-ambarella-s3l-sdk.outcome != 'success'
+        run: |
+          TG_OPTIONS="-s --connect-timeout 30 --max-time 30"
+          TG_NOTIFY="${TG_NOTIFY:=Warning, Buildroot compiling error... AMBARELLA-S3L}"
+          TG_HEADER=$(echo -e "\r\n$TG_NOTIFY \r\n\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9A\xA0 GitHub Actions")
+          curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendMessage \
+            -F chat_id=$TG_CHANNEL -F text="$TG_HEADER"
+
+      - name: Create release
+        uses: actions/create-release@v1
+        continue-on-error: true
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          tag_name: ${{ env.TAG_NAME }}
+          release_name: ${{ env.RELEASE_NAME }}
+          draft: false
+          prerelease: ${{ env.PRERELEASE }}
+
+      - name: Upload FW to release
+        uses: svenstaro/upload-release-action@v2
+        continue-on-error: true
+        with:
+          repo_token: ${{ secrets.GITHUB_TOKEN }}
+          file: ${{ env.ARCHIVE_FW }}
+          asset_name: "openipc.ambarella-s3l-br.tgz"
+          tag: ${{ env.TAG_NAME }}
+          overwrite: true
+
+      - name: Upload SDK to release
+        uses: svenstaro/upload-release-action@v2
+        continue-on-error: true
+        with:
+          repo_token: ${{ secrets.GITHUB_TOKEN }}
+          file: ${{ env.ARCHIVE_SDK }}
+          asset_name: "arm-openipc-ambarella-s3l-linux-musleabi_sdk-buildroot.tar.gz"
+          tag: ${{ env.TAG_NAME }}
+          overwrite: true
+
+      - name: Send binary file to telegram channel
+        env:
+          TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }}
+          TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }}
+        run: |
+          TG_OPTIONS="-s --connect-timeout 30 --max-time 30"
+          TG_HEADER=$(echo -e "\r\nCommit: $GIT_HASH \r\nBranch: $BRANCH_NAME \r\nTag: $TAG_NAME \r\n\r\n\xE2\x9C\x85 GitHub Actions")
+          curl $TG_OPTIONS -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot$TG_TOKEN/sendDocument \
+            -F chat_id=$TG_CHANNEL -F document="@$ARCHIVE_FW" -F caption="$TG_HEADER"
diff --git a/br-ext-chip-ambarella/Config.in b/br-ext-chip-ambarella/Config.in
index 6e35c9c0..15a23ef0 100644
--- a/br-ext-chip-ambarella/Config.in
+++ b/br-ext-chip-ambarella/Config.in
@@ -1,4 +1,5 @@
 source "$BR2_EXTERNAL_AMBARELLA_PATH/linux/Config.ext.in"
+source "$BR2_EXTERNAL_AMBARELLA_PATH/package/ambarella-osdrv-s3l/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/ambarella_patcher/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/aura-httpd/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/dropbear-openipc/Config.in"
@@ -15,7 +16,7 @@ source "$BR2_EXTERNAL_AMBARELLA_PATH/package/libsrt-openipc/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/libwebsockets-openipc/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/linux-firmware-openipc/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/majestic-fonts/Config.in"
-source "$BR2_EXTERNAL_AMBARELLA_PATH/package/majestic/Config.in"
+#source "$BR2_EXTERNAL_AMBARELLA_PATH/package/majestic/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/mbedtls-openipc/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/microbe-web/Config.in"
 source "$BR2_EXTERNAL_AMBARELLA_PATH/package/motors/Config.in"
diff --git a/br-ext-chip-ambarella/board/s3l/kernel/patches/0000-ambarella-s3l-linux-3.10.104.patch b/br-ext-chip-ambarella/board/s3l/kernel/patches/0000-ambarella-s3l-linux-3.10.104.patch
new file mode 100644
index 00000000..590bf77a
--- /dev/null
+++ b/br-ext-chip-ambarella/board/s3l/kernel/patches/0000-ambarella-s3l-linux-3.10.104.patch
@@ -0,0 +1,137647 @@
+diff --git a/Documentation/arm/ambarella/self-refresh.txt b/Documentation/arm/ambarella/self-refresh.txt
+new file mode 100644
+index 00000000..209b8eea
+--- /dev/null
++++ b/Documentation/arm/ambarella/self-refresh.txt
+@@ -0,0 +1,140 @@
++
++Copyright (C) 2016-2019, Ambarella, Inc.
++Author: Cao Rongrong <rrcao@ambarella.com>
++
++
++Introduction
++============
++
++The kernel supports up to four system sleep states generically.
++From shallowest to deepest, they are:
++1) freeze:   Suspend-To-Idle / ACPI S0
++2) standby:  Standby / Power-On Suspend / ACPI S1
++3) mem:      Suspend-To-RAM / Self-Refresh / STR / ACPI S3
++4) disk:     Suspend-To-Disk / STD / ACPI S4
++
++For details, pelase see Documentation/powr/states.txt
++
++Here we just talk about "mem", i.e., Self-Refresh (abbreviated as SR).
++
++In short words, when system is in SR, all the HWs except for DRAM and PWC are
++powered off.
++
++
++
++SR and DRAM
++============
++
++At present we can support SR with DDR3 and LPDDR3, other DRAM types are not
++tested, yet.
++
++One of the differences between DDR3 and LPDDR3 is that DDR3 has a "RESET" pin
++while LPDDR3 doesn't have. When entering into SR, the "RESET" pin must be pulled
++high. Unfortunately, when in SR state, the SoC will be powered off and pull the
++the "RESET" pin low, so we have to add a workaround with the help of HW design,
++i.e., using a GPIO to control the triode to cut off the "RESET" signal to DRAM.
++
++Different boards design may use different GPIO, and both BST and Kernel need to
++know which GPIO is used to cut off the "RESET" signal.
++1) For BST, we define the GPIO in .ini file by "DRAM_RESET_CTRL_GPIO",
++   please see "ini" section below.
++2) For Kernel, we define the GPIO in .dts file by "ambarella,dram-reset-ctrl",
++   please see "Device Tree" section below.
++
++Note:
++  Although LPDDR3 doesn't have the "RESET" pin, you also need to define the GPIO
++  in .ini file, because this GPIO definition, i.e., "DRAM_RESET_CTRL_GPIO", also
++  acts as another role, that is, tell BST to support SR.
++  In other words, if "DRAM_RESET_CTRL_GPIO" is NOT defined in .ini file, BST will
++  boot system directly, but not check if it's cold boot or resume from SR when
++  powered on.
++  For LPDDR3, you can define "DRAM_RESET_CTRL_GPIO" as any meaningful GPIO as
++  long as this GPIO does not affect system booting.
++
++[!!!IMPORTANT!!!]
++  IF SELF-REFRESH IS NOT USED, "DRAM_RESET_CTRL_GPIO" MUST BE REMOVED FROM .ini
++  FILE, OTHERWISE SYSTEM MAY NOT BOOT UP OR REBOOT SUCCESSFULLY.
++
++
++
++SR and PWC (Power Control)
++==========================
++
++SR must co-work with PWC, and there are two options to use PWC:
++1) internal PWC, but not all SoCs have internal PWC
++2) external PWC (MCU)
++PS: for those SoCs without internal PWC, you have to use external MCU.
++
++If the board design is to use external MCU for power sequence control, the SoC
++needs to communicate with the MCU through a GPIO, and the protocol is:
++1) SoC keeps the GPIO high 100ms to notify MCU to enter self-refresh. After
++100ms, SoC should keep the GPIO low.
++2) MCU notifies SoC the state after powered up:
++2.1) if cold boot, MCU keeps the GPIO high.
++2.2) if resume from SR, MCU keeps the GPIO low.
++
++Different boards design may use different GPIO, and both BST and Kernel need to
++know which GPIO is used to communicate with the external MCU.
++1) For BST, we define the GPIO in .ini file by "MCU_NOTIFY_GPIO",
++   please see "ini" section below.
++2) For Kernel, we define the GPIO in .dts file by "ambarella,gpio-notify-mcu",
++   please see "Device Tree" section below.
++
++Note:
++  It's allowed to either use two separate GPIOs or use one GPIO to communicate
++  between SoC and MCU, it's determined by the MCU firmware.
++
++
++
++Driver Configuration
++====================
++
++Power management options  --->
++         [*] Suspend to RAM and standby
++         [*] User space wakeup sources interface
++         (100) Maximum number of user space wakeup sources (0 = no limit)
++         -*- Device power management core functionality
++
++
++
++Device Tree
++===========
++
++Please see Documentation/devicetree/bindings/arm/ambarella.txt
++               -> 2) - Informational node -> ii) /chosen
++
++
++
++ini
++===
++
++In .ini file, there are two fields related to SR:
++
++1) "DRAM_RESET_CTRL_GPIO", e.g., <DRAM_RESET_CTRL_GPIO value="5"/>
++   No matter DDR3 or LPDDR3, this field has to be set as long as SR is used.
++   Please see the "Note" in "SR and DRAM" section.
++
++2) "MCU_NOTIFY_GPIO", e.g., <MCU_NOTIFY_GPIO value="33"/>
++   This filed need to be set only when external MCU is used. If using internal
++   PWC, this filed must NOT be set.
++
++
++
++Usage
++=====
++
++1) Entering into SR
++root@/#echo mem > /sys/power/state
++
++2) Resume from SR by power button
++Press the button directly
++
++3) Resume from SR by RTC
++root@/#echo enabled > /sys/class/rtc/rtc0/device/power/wakeup
++root@/#rtcwake -s 10 -m mem
++PS: 
++  a) this is available only when using internal PWC.
++  b) rtc,wakeup has to be added into rtc node in DTS.
++
++
++
+diff --git a/Documentation/devicetree/bindings/arm/ambarella.txt b/Documentation/devicetree/bindings/arm/ambarella.txt
+new file mode 100644
+index 00000000..64a25fbf
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/ambarella.txt
+@@ -0,0 +1,1434 @@
++Ambarella Platforms Device Tree Bindings
++----------------------------------------
++
++(c) 2013 Cao Rongrong <rrcao@ambarella.com>, Ambarella,Inc.
++
++
++Table of Contents
++=================
++
++  I  - Introduction
++
++  II - Ambarella Node definiton
++    1)  - Root node
++    2)  - Informational node
++    3)  - CPUS node
++    4)  - TWD node
++    5)  - APB/AHB/AXI/RCT node
++    6)  - TIMER node
++    7)  - INTERRUPT node
++    8)  - DMA node
++    9)  - NAND node
++    10) - SPINOR node
++    11) - I2S node
++    12) - UDC node
++    13) - EHCI/OHCI node
++    14) - SD/MMC node
++    15) - ETHERNET node
++    16) - SPI node
++    17) - SLAVE SPI node
++    18) - USBPHY node
++    19) - PINCTRL node
++    20) - GPIO node
++    21) - UART node
++    22) - I2C node
++    23) - I2CMUX node
++    24) - PWM node
++    25) - ADC node
++    26) - IR node
++    27) - WDT node
++    28) - RTC node
++    29) - CRYPTO node
++    30) - IAV node
++    31) - SOUND node
++
++  III - Misc Node definition
++    1)  - BOGUS BUS node
++    2)  - GPIO KEY node
++    3)  - ADC KEY node
++    4)  - PWM BACKLIGHT node
++
++
++
++I - Introduction
++++++++++++++++++
++
++
++1) Reference
++------------
++   a) Documentation/devicetree/booting-without-of.txt
++   b) Documentation/devicetree/usage-model.txt
++   c) http://devicetree.org/Device_Tree_Usage
++   d) https://wiki.freebsd.org/FlattenedDeviceTree
++   e) http://xillybus.com/tutorials/device-tree-zynq-1
++
++2) Abbreviations
++----------------
++   a) FDT: Flattened Device Tree
++   b) OF:  Open Firmware
++   c) DTS: Device Tree Source
++   d) DTB: Device Tree Blob
++   e) DTC: Device Tree Compiler
++
++3) Summary
++----------
++Device Tree is essentially a data structure in byte code format (that is, not
++human-readable) which contains information that is helpful to the kernel when
++booting up. The boot loader copies that chunk of data into a known address in
++the RAM before jumping to the kernel's entry point.
++
++The device tree comes in three forms:
++   DTS: the source of FDT, which is a plain txt file.
++   DTB: the binary blob of FDT, which will be copied to RAM.
++   /proc/device-tree: a file system in a running Linux, normally for debug.
++
++In a normal flow, the DTS file is edited and compiled into a DTB file using a
++special compiler named DTC. You can find DTC in the Linux kernel sources, or
++download it by "git clone git://www.jdl.com/software/dtc.git dtc".
++
++For Ambarella, the DTS for specific board is:
++   $PROJECT/ambarella/boards/$BOARD/bsp/$BOARD.dts
++which will include the DTS for specific ambarella SoC chip:
++   arch/arm/boot/dts/ambarella-$SoC.dtsi
++Normally, it's NOT recommended to modify the DTS for ambarella SoC chip.
++
++
++II - Node definiton
+++++++++++++++++++++
++
++
++1) - Root node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- model: "Ambarella <SoC> <BOARD>", can be modified according to the board.
++- compatible: should be "ambarella,<SoC>";
++- interrupt-parent: <&intc>, or <&gic>, See Interrupt below for more detail.
++
++ii) Example
++----------
++/ {
++	model = "Ambarella S2L Hawthorn Board";
++	compatible = "ambarella,hawthorn", "ambarella,s2l";
++	interrupt-parent = <&intc>;
++  }
++
++
++2) - Informational node
++========================
++
++
++i) /aliases
++-----------
++Please see http://devicetree.org/Device_Tree_Usage#aliases_Node
++
++ii) /chosen
++-----------
++Please see http://devicetree.org/Device_Tree_Usage#chosen_Node
++           Documentation/devicetree/booting-without-of.txt
++
++iii) /memory
++------------
++   Please see Documentation/devicetree/booting-without-of.txt
++   For Ambarella, the /memory node will be overwritten in Amboot.
++
++iv) Example
++-----------
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		nand = &nand0;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		spinor = &spinor0;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		bootargs = "console=ttyS0 ubi.mtd=lnx root=ubi0:rootfs rw rootfstype=ubifs init=/linuxrc";
++	};
++
++
++3) - CPUS node
++==============
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/arm/cpus.txt
++
++ii) Properties
++- amb,core-div: this prop should be 1 or 2, this specified the divide of gclk_core from pll_out_core,
++  for s2e and s5, this value should be 1; and for s2l, s3l, this should be 2. If you don't add this prop,
++  the divide for gclk_core is 2 as default.
++- cpufreq_tbl: Table of frequencies gclk_cortex and gclk_core could be transitioned
++  into, in the unit of nanoseconds.
++- clock-latency: Specify the possible maximum transition latency for clock, in
++  unit of nanoseconds.
++
++
++4) - TWD node
++=============
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/arm/twd.txt
++
++ii) Description
++---------------
++This node is only available for SoC chip that supports per-cpu local timer,
++i.e., S2.
++
++
++5) - APB/AHB/AXI/RCT node
++=========================
++
++
++i) Summary
++----------
++The apb/ahb/axi/rct nodes represent the BUS inside the SoC, each node may
++contain many device nodes which connect to the corresponding bus.
++PS: RCT is not a real bus, just means a serial of registers address space.
++
++ii) Properties
++--------------
++Required properties:
++- compatible: should be "simple-bus".
++- #address-cells: should be 1.
++- #size-cells: should be 1.
++- reg: address range of the registers in each bus.
++- ranges:
++
++
++6) - TIMER node
++===============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be
++  a) "ambarella,clock-source": for timer used as clock source.
++  b) "ambarella,clock-event":  for timer used as clock event.
++- reg : specifies base physical address and size of the registers. The last
++  pair for the timer-ctrl register which is shared by all of the timers.
++- interrupts: the interrupt for this timer.
++- ctrl-offset: bit offset in timer-ctrl reg for this timer.
++
++ii) Example
++-----------
++	timer7: timer@e800b064 {
++		compatible = "ambarella,clock-source";
++		reg = <0xe800b064 0x10 0xe800b030 0x4>;
++		interrupts = <62 0x1>;
++		ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++	};
++
++
++7) - INTERRUPT node
++===================
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/interrupt-control/interrupts.txt
++
++ii) Properties
++--------------
++a) Ambarella VIC:
++Required properties:
++- compatible: should be "ambarella,vic".
++- interrupt-controller: marks the node as an interrupt controller
++- #interrupt-cells: should be 2, specifies the number of cells to define the
++  interrupts. The first cell defines the index of the interrupt within the
++  controller, while the second cell is used to specify any of the following
++  flags:
++    1 = low-to-high edge triggered.
++    2 = high-to-low edge triggered.
++    4 = active high level-sensitive.
++    8 = active low level-sensitive.
++- reg: specifies base physical address and size of the registers.
++
++b) GIC:
++Please see Documentation/devicetree/bindings/arm/gic.txt
++
++iii) Example
++------------
++a) Ambarella VIC:
++	intc: interrupt-controller@e0003000 {
++		compatible = "ambarella,vic";
++		interrupt-controller;
++		#interrupt-cells = <2>;
++		reg = <0xe0003000 0x1000>,
++		      <0xe0010000 0x1000>,
++		      <0xe001c000 0x1000>;
++	};
++
++b) GIC:
++	gic: interrupt-controller@f0001000 {
++		compatible = "arm,cortex-a9-gic";
++		interrupt-controller;
++		#interrupt-cells = <3>;
++		reg = <0xf0001000 0x1000>,
++			  <0xf0000100 0x0100>;
++	};
++
++
++8) - DMA node
++=============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,dma".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the DMA controller.
++- #dma-cells: Must be at least 1. Used to provide DMA controller
++			specific information. See DMA client binding below for
++			more details.
++- dma-channels: 	Number of DMA channels supported by the controller.
++- dma-requests: 	Number of DMA requests signals supported by the
++			controller.
++- dma-trans-type:   specifies the dma channel use type.
++					0 for memcpy, 1 for slave.
++
++Optional properties:
++- amb,copy-align: specifies alignment requirement for previous chips.
++- amb,support-prs: should be specified for SoC that supports PAUSE/RESUME/STOP.
++- dma-channel-sel: should be specified for Soc that support dma channel sel.
++  different value is used for selecting the device.
++  e.g., 0 for ssi0_tx, 1 for ssi0_rx, 10 for i2s_tx, 11 for i2s_rx.
++
++ii) Example
++-----------
++	dma@e0005000 {
++		compatible = "ambarella,dma";
++		reg = <0xe0005000 0x1000>;
++		interrupts = <15 0x4>;
++		#dma-cells = <2>;
++		dma-channels = <8>;
++		dma-requests = <12>;
++		dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
++		dma-channel-sel = <4 5 0 0 8 9 11 10>;
++	};
++
++
++9) - NAND node
++==============
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/mtd/nand.txt
++
++ii) Properties
++--------------
++Required properties:
++- compatible: should be "ambarella,nand".
++- #address-cells: should be 1.
++- #size-cells: should be 1.
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the NAND controller.
++
++Optional properties:
++- nand-on-flash-bbt: please see Reference.
++- amb,enable-wp: specifies to enable write protection
++- amb,no-bch: should be specified for SoC without BCH supported.
++- amb,use-2x-pll: should be specified only for A5S.
++- amb,soft-ecc: specifies to use software ECC instead of hardware ECC, the
++  value should be as:
++    1 = 1 bit software ECC
++    6 = 6 bit software ECC
++    8 = 8 bit software ECC
++- amb,timing: an integer array with size 6, the array is used to specify the
++  NAND timing, like tcls/tals/tcs/..., which can be found in NAND datasheet.
++  Please note that this property is provided by Amboot in runtime.
++
++iii) Subnode
++------------
++Please see Documentation/devicetree/bindings/mtd/partition.txt, and please
++note that the subnodes for partitions are provided by Amboot in runtime.
++
++iv) Example
++-----------
++	nand0: nand@e0001000 {
++		compatible = "ambarella,nand";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe0001000 0x1000>, /* fio reg address */
++		      <0xe0012000 0x1000>, /* fdma reg address */
++		      <0xe0000000 0x4>;    /* fifo base */
++		interrupts = <16 0x4>,	/* fio_cmd_irq */
++			     <17 0x4>,	/* fio_dma_irq */
++			     <33 0x4>;	/* fdma_irq */
++		nand-on-flash-bbt;
++		/* amb,soft-ecc = <1>; */
++		/* amb,enable-wp; */
++	};
++
++
++10) - SPINOR node
++=================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,spinor".
++- reg: specifies base physical address and size of the registers.
++
++ii) Example
++-----------
++	spinor0: spinor@e0031000 {
++		compatible = "ambarella,spinor";
++		reg = <0xe0031000 0x2ff>, /* spi nor controller */
++		      <0xe0005300 0x20>;  /* dma reg */
++	};
++
++
++11) - I2S node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,i2s".
++- reg: specifies base physical address and size of the registers.
++- pinctrl-names: should contain only one value - "default".
++- pinctrl-0: pin control group to be used for this controller.
++- amb,i2s-channels: should be one of these values: 2, 4, 6.
++- amb,default-mclk: specifies the initial mclk frequency in HZ.
++
++ii) Example
++-----------
++	i2s0: i2s@e001a000 {
++		compatible = "ambarella,i2s";
++		reg = <0xe001a000 0x1000>;
++		pinctrl-names = "default";
++		pinctrl-0 = <&i2s0_pins>;
++		amb,i2s-channels = <2>;
++		amb,default-mclk = <12288000>;
++	};
++
++
++12) - UDC node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,udc".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the UDC controller.
++- amb,usbphy: specifies the phandle to USB PHY.
++
++Optional properties:
++- amb,dma-addr-fix: should be specified only for S2.
++
++ii) Example
++-----------
++	udc@e0006000 {
++		compatible = "ambarella,udc";
++		reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
++		interrupts = <4 0x4>;
++		amb,usbphy = <&usbphy>;
++	};
++
++
++13) - EHCI/OHCI node
++====================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,ehci", or "ambarella,ohci".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the EHCI/OHCI controller.
++- amb,usbphy: specifies the phandle to USB PHY.
++
++Optional properties:
++- amb,dma-addr-fix: should be specified only for S2.
++
++ii) Example
++-----------
++	ehci@e0018000 {
++		compatible = "ambarella,ehci";
++		reg = <0xe0018000 0x1000>;
++		interrupts = <39 0x4>;
++		amb,usbphy = <&usbphy>;
++	};
++
++	ohci@e0019000 {
++		compatible = "ambarella,ohci";
++		reg = <0xe0019000 0x1000>;
++		interrupts = <44 0x4>;
++		amb,usbphy = <&usbphy>;
++		status = "disabled";
++	};
++
++
++14) - SD/MMC node
++=================
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/mmc/mmc.txt
++
++ii) Properties
++--------------
++Required properties:
++- compatible: should be "ambarella,sdmmc".
++- reg: specifies base physical address and size of the registers.
++- #address-cells: should be 1.
++- #size-cells: should be 0.
++- interrupts: the interrupt for the SD controller.
++- amb,clk-name: specifies the PLL name of this SD controller, should be one
++  of these strings: "gclk_sd", "gclk_sdio", "gclk_sdxc".
++- amb,wait-tmo: specifies the timeout in millisecond to wait for CMD complete.
++- amb,switch-vol-tmo: specifies the timeout to enable clk after switch voltage
++  from 3.3v to 1.8v.
++- amb,max-blk-size: specifies the maximal block size, should be multiple of 4k.
++
++Optional properties:
++- amb,dma-addr-fix: should be specified only for S2.
++- amb,soft-phy: should be specified for SD controllers to adjust timing base on
++  SD phy.
++- amb,phy-timing: an integer array which is used to specify the SD phy timing,
++  the size of the array is different according to corresponding phy register
++  for each chips or SD controllers, and the values are gotten by SD shmoo in
++  Amboot.
++  For the SD controller to ajust timing base on SD controller, like S3L and later
++  chip, the array is orgnized as: <mode SD_DELAY_SEL_L SD_DELAY_SEL_H>;
++  For the SD controller to ajust timing base on SD phy, like S2E SD0, S2L, S3L, the
++  array is orgnized as: <mode phy_ctrl0_val latency_ctrl_val>;
++  For the SD controller only supporting ms delay mux, like S2E SD1, the array
++  is orgnized as: <mode ms_delay_ctrl_mask ms_delay_ctrl_val>;
++  Here mode is the ORed value of SD card working modes like sdr104, ddr50 and
++  etc., and the later 2 items are values written to corresponding phy registers.
++  Following is the definition of each bits for mode:
++  bit0: specify the default phy timing setting, so bit0 must be reserved as 1, and
++  followed by default phy timing setting. PS: it's a MUST to define the default phy
++  timing setting with bit0 set, and it MUST be placed in the first row.
++  bit1: MMC HS; bit2: SD HS;
++  bit3: SDR12; bit4: SDR25; bit5: SDR50; bit6: SDR104; bit7: DDR50
++  bit8: MMC HS200
++  In fact, the definition for each bit of mode comes from the following
++  definition which are defined in include/linux/mmc/host.h:
++    #define MMC_TIMING_LEGACY	0
++    #define MMC_TIMING_MMC_HS	1
++    #define MMC_TIMING_SD_HS	2
++    #define MMC_TIMING_UHS_SDR12	3
++    #define MMC_TIMING_UHS_SDR25	4
++    #define MMC_TIMING_UHS_SDR50	5
++    #define MMC_TIMING_UHS_SDR104	6
++    #define MMC_TIMING_UHS_DDR50	7
++    #define MMC_TIMING_MMC_HS200	8
++
++Example for ajusting timing base sd controller on s3l platform:
++		sdmmc0: sdmmc0@e0002000 {
++			compatible = "ambarella,sdmmc";
++			reg = <0xe0002000 0x1000>,
++			      <0xe0001000 0x80>;/* fio reg address */
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			amb,soft-phy;
++			amb,phy-timing = <0x00000007 0x00000000 0x00000000>,/*HS 50M and 25M*/
++					/*sdr25 50M,sdr50 100M,sdr104 120M*/
++					<0x00000078 0x10410400 0x00904104>,
++					<0x00000080 0x38E38E00 0x0238E38E>;/*DDR50 50M*/
++			slot@0 {
++
++			};
++		};
++
++
++Example for ajusting timing base sd phy on s3l platform:
++		sdmmc0: sdmmc0@e0002000 {
++			compatible = "ambarella,sdmmc";
++			reg = <0xe0002000 0x1000>,
++			      <0xe0001000 0x80>;/* fio reg address */
++			      <0xec1704c0 0x8>;/*should specify the phy register*/
++
++			amb,soft-phy;
++			amb,phy-timing = <0x00000001 0x04070000 0x00000000>,
++					/*sdr12 24M,sdr25 50M,sdr50 100M*/
++					<0x00000038 0x00000003 0x00001111>,
++					<0x00000040 0x00000005 0x00002222>,/*sdr104 200M*/
++					<0x00000080 0x000C0005 0x00000000>;/*ddr50 50M*/
++			slot@0 {
++
++			};
++		};
++
++iii) Subnode
++------------
++The SD/MMC node should contain subnodes which represent the slot belong to
++this controller.
++
++The unit address of subnodes should be its index of the slot. And the subnode
++should contain the following properties.
++- reg: index of the slot, normally the same as the unit address.
++- global-id: specify the global id for each slot, it should be unique for all
++  of the slots.
++- amb,fixed-cd: should be specified if no cd pin, 0: no sd card, 1: sd card is
++always present
++- amb,fixed-wp: should be specified if no wp pin, 0: write-able, 1: read-only
++- amb,caps-adma: should be specified if hardware supports ADMA.
++- amb,caps-ddr: should be specified if hardware supports DDR.
++- no-1-8-v: should be specified if the slot don't have 1.8V circuit.
++- v18-gpios: specifies the GPIO to switch to the 1.8V power if existed.
++- pwr-gpios: specifies the GPIO to turn on/off the power for the SD/MMC card.
++- amb,force-gpio: force the SD/MMC pins to switch to GPIO mode when in idle,
++  should be specified only for A5S SDIO slot.
++- pinctrl-names: should contain only one value - "default".
++- pinctrl-0: pin control group to be used for this controller.
++- properties provided by Kernel, please see Reference above.
++
++iv) Example
++-----------
++	sdmmc0@e0002000 {
++		compatible = "ambarella,sdmmc";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		reg = <0xe0002000 0x1000>,
++		      <0xe0001000 0x80>; /* fio reg address */
++		interrupts = <18 0x4>;
++		amb,clk-name = "gclk_sd";
++		amb,wait-tmo = <2500>; /* in millisecond */
++		amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++
++		slot@0 {
++			reg = <0>;
++			max-frequency = <48000000>;
++			bus-width = <8>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc1_pins_8bit>;
++			amb,caps-adma;
++			cap-sdio-irq;
++		};
++	};
++
++
++15) - ETHERNET node
++===================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,eth".
++- #address-cells: should be 1.
++- #size-cells: should be 0.
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the ethernet controller.
++
++Optional properties:
++- pwr-gpios: specifies the GPIO to control PHY power.
++- rst-gpios: specifies the GPIO to reset PHY.
++- amb,support-gmii: should be specified if hardware supports GMII.
++- amb,tx-ring-size: specifies the Tx ring buffer size.
++- amb,rx-ring-size: specifies the Rx ring buffer size.
++- amb,fixed-speed: should be specified if connecting without PHY.
++- amb,ipc-tx: should be specified if hardware supports Tx checksum.
++- amb,ipc-rx: should be specified if hardware supports Rx checksum.
++- amb,dump-tx: specifies to dump Tx buffer, for debug purpose.
++- amb,dump-rx: specifies to dump Rx buffer, for debug purpose.
++- amb,dump-rx-free: specifies to free buffer after dumped.
++- amb,dump-rx-all: specifies to dump all buffers without filter.
++- amb,mdio-gpio: specifies using mdio gpio to access phy.
++- amb,clk-src: specifies the clk source for gtx_clk, 0:external clk, 1:internal clk.
++- amb,clk-invert: specifies to invert the clk for ethernet, 0: no invert, 1: invert
++- amb,clk-dir: specifies the ref clk direction from PHY, 1: set direction of xx_enet_clk_rx as output from ambarella chip,
++  0: set direction of xx_enet_clk_rx as output from external phy.
++ii) Example
++-----------
++	mac0: ethernet@e000e000 {
++		compatible = "ambarella,eth";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		reg = <0xe000e000 0x2000>;
++		interrupts = <27 0x4>;
++		amb,tx-ring-size = <32>;
++		amb,rx-ring-size = <64>;
++		amb,ipc-tx;
++		amb,ipc-rx;
++	};
++
++
++16) - SPI node
++===============
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/spi/spi-bus.txt
++
++
++ii) Properties
++--------------
++Required properties:
++- compatible: should be "ambarella,spi".
++- #address-cells: should be 1.
++- #size-cells: should be 0.
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the SPI controller.
++- amb,clk-freq: specifies the PLL frequence in HZ.
++- amb,msb-first-only: HW only supports msb first tx/rx, for A5S/S2/S2E, please
++  set this flag.
++- cs-gpios: gpios chip select. Please see Reference for detailed.
++
++Optional properties:
++- amb,dma-used: use dma for TX/RX, only can be specified if SPI channel
++  supports dma mode.
++- dmas: specify dma channel
++- dma-names: specify dma channel name.
++
++iii) Subnode
++------------
++The SPI node can contain subnodes which represent the spi devices connected
++to this SPI controller. If any valid subnode are available, the SPI drivers
++will proble them automatically.
++
++The subnodes should contain the following properties.
++- compatible: name of the SPI device, should match the name of its drivers.
++- reg: index of the SPI device, normally the same as the unit address.
++- properties provided by Kernel: please see Reference.
++
++iv) Example
++-----------
++	spi0: spi@e0020000 {
++		compatible = "ambarella,spi";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		reg = <0xe0020000 0x1000>;
++		interrupts = <35 0x4>;
++		amb,clk-name = "gclk_ssi_ahb";
++		amb,clk-freq = <54000000>;
++		cs-gpios = <&gpio 37 0>, <&gpio 38 0>, <&gpio 23 0>;
++
++		sensor: sensor@0 {
++			compatible = "ambarella,sensor";
++			reg = <0>;
++			spi-max-frequency = <1000000>;
++			spi-cpha;
++			spi-cpol;
++		};
++	};
++
++
++17) - SLAVE SPI node
++====================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,spi-slave".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for the slave spi controller.
++
++ii) Example
++-----------
++	spi_slave@e0026000 {
++		compatible = "ambarella,spi-slave";
++		reg = <0xe0026000 0x1000>;
++		interrupts = <38 0x4>;
++	};
++
++
++18) - USBPHY node
++=================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,usbphy".
++- reg: specifies base physical address and size of the registers.
++
++Optional properties:
++- amb,host-phy-num: specifies the PHY number used for host.
++- amb,owner-mask: Mask IDDIG0, should be specified for S2L.
++- amb,owner-invert: the owner bit for USB PHY is inverted, should be specified
++  for S2L.
++- amb,ocp-polarity: specifies the polarity of over current protection pin.
++- id-gpios: specifies the input GPIO used for OTG detection.
++- md-gpios: specifies the output GPIO to control external circuit to switch to
++  host mode or device mode.
++- hub-gpios: specifies the GPIO to reset the usb hub.
++
++ii) Example
++-----------
++	usbphy: usbphy@ec170050 {
++		compatible = "ambarella,usbphy";
++		reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
++		amb,host-phy-num = <2>;
++		amb,owner-offset = <0x1001>;
++	};
++
++
++19) - PINCTRL node
++==================
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
++
++ii) Description
++---------------
++The pins controlled by Ambarella SoC chip are organized in banks, each bank
++has 32 pins.  Each pin has at least 2 multiplexing functions, and generally,
++the first function is GPIO.
++
++The PINCTRL node acts as a container for an arbitrary number of subnodes. And
++these subnodes will fall into two categories.
++One is for GPIO, please see the "GPIO node" section for detail, and another one
++is to set up a group of pins for a function, both pin configurations(TODO) and
++mux selection, and it's called group node in the binding document.
++
++
++iii) Properties
++---------------
++Required properties:
++- compatible: should be "ambarella,pinctrl", "simple-bus".
++- #address-cells: should be 1.
++- #size-cells: should be 0.
++- reg: specifies base physical address and size of the registers.
++- #gpio-range-cells: should be 3.
++
++Optional properties:
++- reg-names: "gpio0", "gpio1", ... , "gpioN", ["iomux"], should be specified
++  if the SoC supports IOMUX, e.g., S2L.
++
++
++iv) Subnode
++-----------
++On Ambarella SoC chip, there is no hardware pin group. The pin group in this
++binding only means a group of pins put together for particular peripheral to
++work in particular function.  That said, the group node should include all the
++pins needed for one function rather than having these pins defined in several
++group nodes.  It also means each of "pinctrl-*" phandle in client device node
++should only have one group node pointed in there.
++
++Required subnode-properties:
++- reg: Should be the index of the group nodes for same function.
++- amb,pinmux-ids: an integer array. Each integer in the array specifies a pin
++  with given mux function, with pin id and mux packed as:
++    mux << 12 | pin id
++  Here mux means function of this pin, and pin id is identical to gpio id. For
++  the SoC supporting IOMUX, like S2L, the maximal value of mux is 5. However,
++  for the SoC not supporting IOMUX, like A5S, S2, the third or fourth function
++  is selected by other "virtual pins" setting. Here the "virtual pins" means
++  there is no real hardware pins mapping to the corresponding register address.
++  So the registers for the "virtual pins" can be used for the selection of 3rd
++  or 4th function for other real pins.
++- amb,pinconf-ids: an integer array. Each integer in the array specifies a pin
++  with given configuration, with pin id and config packed as:
++    config << 16 | pin id
++  Here config is used to configure pull up/down and drive strength of the pin,
++  and it's orgnization is:
++  bit1~0: 00: pull down, 01: pull up, 1x: clear pull up/down
++  bit2:   reserved
++  bit3:   0: leave pull up/down as default value, 1: config pull up/down
++  bit5~4: drive strength value, 0: 2mA, 1: 4mA, 2: 8mA, 3: 12mA
++  bit6:   reserved
++  bit7:   0: leave drive strength as default value, 1: config drive strength
++
++v) Example
++----------
++	pinctrl: pinctrl@e8009000 {
++		compatible = "ambarella,pinctrl", "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		reg = <0xe8009000 0x1000>,
++		      <0xe800a000 0x1000>,
++		      <0xe800e000 0x1000>,
++		      <0xe8010000 0x1000>,
++		      <0xe8016000 0x1000>;
++		reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "iomux";
++		#gpio-range-cells = <3>;
++
++		uart0_pins: uart0@0 {
++			reg = <0>;
++			amb,pinmux-ids = <0x1027 0x1028>;
++		};
++
++		sdmmc0_pins_4bit: sdmmc0@1 {
++			reg = <1>;
++			amb,pinmux-ids = <0x2039 0x203a 0x203b 0x203c
++							  0x2049 0x204a 0x204b 0x204c>;
++			amb,pinconf-ids = <0x090039 0xb0003a 0xaa003b 0x00003c>;
++		};
++	}
++
++In this example, uart0_pins defines a group of pins used by uart0 controller,
++according to the definition, uart0 uses 2 pins which are pin39(0x27) and
++pin40(0x28), i.e., GPIO39 and GPIO40. And, pin39/pin40 use function 1.
++And, sdmmc0_pins_4bit defines a group of pins used by sd0 controller, according
++to the definition, sd0 uses 8 pins. And pin57 enables pull up, pin58 configure
++drive strength to 12mA, pin59 clear pull up/down and configure drive strength
++to 8mA, pin60 leave pull up/down and drive strength as default value.
++
++
++20) - GPIO node
++===============
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/gpio/gpio.txt
++
++ii) Description
++---------------
++The Ambarella GPIO controller is part of Ambarella PIN controller. The GPIOs
++are organized in bank. Each port consists of 32 GPIOs.
++
++As the GPIO controller is embedded in the PIN controller and all the GPIO
++ports share the same IO space with PIN controller, the GPIO node will be
++represented as sub-nodes of Ambarella PINCTRL node.
++
++iii) Properties
++---------------
++Required properties:
++- compatible: should be "ambarella,gpio".
++- interrupts: the interrupts for each GPIO bank.
++- gpio-controller : marks the device node as a gpio controller.
++- #gpio-cells : should be two. The first cell is the pin number and the second
++  cell is used to specify the gpio polarity:
++    0 = active high.
++    1 = active low.
++- gpio-ranges: speicify the ranges that may be handled by the pin controller.
++- interrupt-controller: marks the device node as an interrupt controller.
++- #interrupt-cells : should be 2. The first cell is the GPIO number. The second
++  cell bits[3:0] is used to specify trigger type and level flags:
++    1 = low-to-high edge triggered.
++    2 = high-to-low edge triggered.
++    4 = active high level-sensitive.
++    8 = active low level-sensitive.
++
++iv) Example
++-----------
++	gpio: gpio@0 {
++		compatible = "ambarella,gpio";
++		/* gpio interrupts to vic */
++		interrupts = <10 0x4 11 0x4 30 0x4 29 0x4>;
++		gpio-controller;
++		#gpio-cells = <2>;
++		gpio-ranges = <&pinctrl 0 0 128>;
++		interrupt-controller;
++		#interrupt-cells = <2>;
++	};
++
++v) GPIO user nodes example
++--------------------------
++	spi0: spi@e0020000 {
++		......
++		cs-gpios = <&gpio 37 0>, <&gpio 38 0>, <&gpio 23 0>;
++		......
++	};
++
++  DESCRIPTION:
++    cs-gpios = GPIO properties name;
++    &gpio    = phandle to the GPIO controller node;
++    37/38/39 = the GPIO id;
++    0        = normal polarity.
++  Please see Reference for detailed.
++
++
++21) - UART node
++===============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,uart".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for this uart.
++- pinctrl-names: should contain only one value - "default".
++- pinctrl-0: pin control group to be used for this controller.
++
++Optional properties:
++- amb,tx-fifo-fix: should be specified for A7L, iONE and A8
++- amb,msr-used: use Modem Status Register, should be specified for non-UART0.
++- amb,less-reg: registers like FIFO status register are NOT provided, should be
++  specified for A5S.
++- amb,txdma-used: use dma for transmitting, should be specified if uart hardware
++  supports dma mode.
++- amb,rxdma-used: use dma for receiving, should be specified if uart hardware
++  supports dma mode.
++
++ii) Example
++-----------
++	uart0: uart@e8005000 {
++		compatible = "ambarella,uart";
++		reg = <0xe8005000 0x1000>;
++		interrupts = <9 0x4>;
++		pinctrl-names = "default";
++		pinctrl-0 = <&uart0_pins>;
++		status = "ok";
++		/* amb,tx-fifo-fix; */
++	};
++
++
++22) - I2C node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,i2c".
++- #address-cells: should be 1.
++- #size-cells: should be 0.
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for this i2c.
++- pinctrl-names: should contain only one value - "default".
++- pinctrl-0: pin control group to be used for this controller.
++- clock-frequency: desired I2C bus clock frequency in Hz, [1000, 400000].
++- amb,i2c-class:
++  a) 0x81: normal I2C controller
++  b) 0x08: I2C controller dedicated to HDMI
++- amb,turbo-mode: use turbo(FIFO) write mode, batched data will be write into FIFO
++directly, but there're 2 restriction for this mode:
++  1) FIFO mode will ignore device ACK.
++  2) FIFO mode can only write less than or equal to 61 data(FIFO depth) into FIFO at a time.
++- amb,duty-cycle: the duty cycle of clock, and the value can be:
++    0 = duty cycle 1:1, this is the default setting.
++    1 = duty cycle 2:3.
++    2 = duty cycle 1:2.
++- amb,stretch-scl: extend the SCL clock to tune START/STOP setup and hold timing,
++  the default value is 1 if this option is not specified.
++
++ii) Subnode
++-----------
++The I2C node can contain subnodes which represent the I2C devices connected
++to this I2C controller. If any valid subnode are available, the I2C drivers
++will proble them automatically.
++
++The unit address of subnodes should be its device address in I2C bus. And the
++subnode should contain the following properties.
++- compatible: name of I2C device, should match the name of its drivers.
++- reg: device address in the I2C bus, normally the same as the unit address.
++
++iii) Example
++------------
++	i2c0: i2c@e8003000 {
++		compatible = "ambarella,i2c";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		reg = <0xe8003000 0x1000>;
++		interrupts = <19 0x4>;
++		pinctrl-names = "default";
++		pinctrl-0 = <&i2c0_pins>;
++		clock-frequency = <100000>;
++		amb,i2c-class = <0x81>;
++		amb,turbo-mode;
++		amb,duty-cycle = <0>;
++		amb,stretch-scl = <1>;
++		status = "ok";
++
++		ak4642: codec@12 {
++			compatible = "ambarella,ak4642";
++			reg = <0x12>;
++			gpios = <&pca9539 4 0x0>;
++		};
++	};
++
++
++23) - I2CMUX node
++=================
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt
++
++ii) Description
++---------------
++This node is only available for SoC chip that supports I2C Mux, i.e., A5S.
++
++
++24) - PWM node
++==============
++
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/pwm/pwm.txt
++
++ii) Properties
++--------------
++Required properties:
++- compatible: should be "ambarella,pwm".
++- reg: specifies base physical address and size of the registers.
++- #pwm-cells: should be 3.
++
++iii) Example
++----------
++	pwm: pwm@e8008000 {
++		compatible = "ambarella,pwm";
++		reg = <0xe8008000 0x1000>;
++		#pwm-cells = <3>;
++	};
++
++iv) PWM user nodes example
++--------------------------
++	backlight {
++		......
++		pwms = <&pwm 2 40000 0>;
++		......
++	};
++
++  DESCRIPTION:
++    pwms = PWM properties name;
++    &pwm = phandle to the PWM controller node;
++    2    = the PWM number or channel;
++    4000 = the PWM period in nanoseconds.
++    0    = normal polarity
++  Please see Reference for detailed.
++
++
++25) - ADC node
++==============
++
++
++i) Properties
++-------------
++
++Required properties:
++- compatible: should be "ambarella,adc".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for adc.
++- clock-frequency: desired ADC clock frequency in Hz.
++- amb,polling-mode: specified if ADC is working in polling mode, must be
++  specified for A5S.
++
++Optional properties:
++- amb,print-key: print Key code when key is pressed, for debug purpose.
++
++ii) Example
++-----------
++	adc@e801d000 {
++		compatible = "ambarella,adc";
++		reg = <0xe801d000 0x1000>;
++		interrupts = <34 0x4>;
++		clock-frequency = <3000000>;
++	};
++
++iii) Note
++---------
++For coding easily purpose, we re-order the channel number for A5S.
++Please see the ADC address definition in PRM for details.
++
++26) - IR node
++=============
++
++
++i) Properties
++-------------
++- compatible: should be "ambarella,ir".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for ir.
++- pinctrl-names: should contain only one value - "default".
++- pinctrl-0: pin control group to be used for this controller.
++- amb,keymap: the key-code to be reported when the key is pressed. Each entry
++  is organized as <IRcode Keycode>.
++
++Optional properties:
++- amb,protocol: ir protocol, use NEC protocol if not specified.
++  a) 0: NEC protocol
++  b) 1: PANASONIC protocol
++  c) 2: SONY protocol
++  d) 3: PHILIPS protocol
++- amb,print-key: print IR code when key is pressed, for debug purpose.
++
++ii) Example
++-----------
++	ir@e8006000 {
++		compatible = "ambarella,ir";
++		reg = <0xe8006000 0x1000>;
++		interrupts = <22 0x4>;
++		pinctrl-names = "default";
++		pinctrl-0 = <&ir_pins>;
++		amb,keymap =
++			<0x0100bcbd 116>, /* KEY_POWER */
++			<0x01000405 115>, /* KEY_VOLUMEUP */
++			<0x01008485 114>; /* KEY_VOLUMEDOWN */
++		/* amb,print-key; */
++	};
++
++
++27) - WDT node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,wdt".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for wdt, normally not used.
++- timeout-sec: the watchdog timeout in seconds.
++- amb,non-bootstatus: don't support to report boot status, should be
++  specified only for A5S.
++
++ii) Example
++-----------
++	wdt@e800c000 {
++		compatible = "ambarella,wdt";
++		reg = <0xe800c000 0x1000>;
++		/* interrupts = <21 0x4>; */
++		timeout-sec = <15>;
++	};
++
++
++28) - RTC node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,rtc".
++- reg: specifies base physical address and size of the registers.
++
++Optional properties:
++- amb,is-limited: should be specified only for A5S.
++
++ii) Example
++-----------
++	rtc@e8015000 {
++		compatible = "ambarella,rtc-v2";
++		reg = <0xe8015000 0x1000>;
++	};
++
++
++29) - CRYPTO node
++=================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,crypto".
++- reg: specifies base physical address and size of the registers.
++- interrupts: the interrupt for crypto.
++- interrupt-names: the name for each interrupt.
++
++Optional properties:
++- amb,cap-md5-sha1: should be specified if hardwar supports md5 and sha1.
++- amb,data-swap: should be specified if hardware needs to swap data.
++- amb,reg-64bit: should be specified if hardware has 64bit register.
++- amb,binary-mode: should be specified if hardware needs binary mode.
++
++ii) Example
++-----------
++	crypto@f0020000 {
++		compatible = "ambarella,crypto";
++		reg = <0xf0020000 0x8000>;
++		interrupts = <88 0x1>, <87 0x1>, <86 0x1>, <89 0x1>;
++		interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++		amb,cap-md5-sha1;
++		amb,data-swap;
++		amb,reg-64bit;
++	};
++
++
++30) - IAV node
++==============
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: should be "ambarella,iav".
++
++ii) Subnode
++-----------
++The IAV node may contain subnodes which represent the VIN controller, whose
++name must be vincN (N = 0, 1).
++
++And the optional properties of subnodes:
++- vinrst-gpios: specifies the GPIO to reset VIN.
++- vinpwr-gpios: specifies the GPIO to control the power of VIN.
++
++iii) Example
++------------
++	iav {
++		compatible = "ambarella,iav";
++
++		/* node for vin controller */
++		vinc0 {
++			vinrst-gpios = <&pca9539 7 0>;
++			vinpwr-gpios = <&gpio 8 1>, <&gpio 9 1>, <&gpio 10 1>;/
++	};
++
++
++31) - SOUND node
++================
++
++
++i) Properties
++-------------
++Required properties:
++- compatible: board name, should match the name in ALSA board driver.
++- amb,model: board description.
++- amb,i2s-controllers: specifies the phandle to I2S controller.
++- amb,audio-codec: specifies the phandle to audio codec.
++- amb,dai_fmt: specifies the mode of codec and cpu. If it is 0, the mode is I2S, otherwise it is DSP mode.
++- amb,clk_fmt:
++	0 : mclk, bclk provided by cpu
++	1 : bclk provide by cpu, mclk is not used
++	2 : mclk provided by cpu, bclk is provided by codec
++There are four type of connection:
++clk_fmt=0:
++cpu :                   codec:
++	MCLK    ------>  MCKI
++	BCLK    ------>  BICK
++	LRCK    ------>  LRCK
++clk_fmt=1:
++cpu :                   codec:
++	MCLK   is not used
++	BCLK    ------> BICK
++	LRCK    ------> LRCK
++clk_fmt=2:
++cpu :                   codec:
++	MCLK   ------> MCKI
++	BCLK   <------ BICK
++	LRCK   <------ LRCK
++There are one connection we are not used, it is like clk_fmt=0,but power on the codec PLL.
++It is a waster of power, so we do not use it.
++
++- amb,codec-name: specifies the name of the codec.
++- amb,stream-name: specifies the name of the stream.
++- amb,codec-dai-name: specifies the DAI name within the codec, it must be consistent with the codec driver.
++- amb,audio-routing: specifies the route map for audio codec.
++usage:
++	amb,audio-routing = "sink", source",	/*This is route 0*/
++			    "sink", "source";	/*This is route 1*/
++	sink and source dapm widget should be based on codec driver and our board.
++	dapm widget on board:
++	"Mic internal": board internal Mic, used to connect Mic of codec.
++	"Mic external": used to connect Mic of codec with the external Mic of our board.
++	"Line In": used to connect to line in of codec dapm widget.
++	"Line Out": used to connect line out of codec dapm widget.
++	"HP Jack": used to connect the headphone of codec dapm widget.
++	"Speaker": used to connect the speaker of codec dapm widget.
++
++ii) Example
++-----------
++	sound {
++		compatible = "ambarella,audio-board";
++		amb,model = "ak4642 @ Ambarella";
++		amb,i2s-controllers = <&i2s0>;
++		amb,audio-codec = <&ak4642>;
++		amb,dai_fmt = <0>;
++		amb,codec-name = "ak4642";
++		amb,stream-name = "ak4642 PCM";
++		amb,codec-dai-name = "ak4642-hifi";
++		amb,audio-routing = "LIN1",	"Mic internal",
++				    "RIN1",	"Mic internal",
++				    "LIN2",	"Line In",
++				    "RIN2",	"Line In",
++				    "Line Out",	"LOUT",
++				    "Line Out",	"ROUT",
++				    "HP Jack",	"HPL",
++				    "HP Jack",	"HPR",
++				    "Speaker",	"SPP",
++				    "Speaker",	"SPN";
++	};
++
++
++III - Misc Node definition
++++++++++++++++++++++++++++
++
++
++1)  - BOGUS BUS node
++====================
++
++i) Purpose
++----------
++No real meaning, just make the name of devices under bogus bus more reasonable.
++
++
++
++2)  - GPIO KEY node
++===================
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/gpio/gpio_keys.txt
++
++
++
++3)  - ADC KEY node
++====================
++
++
++i) Properties
++-------------
++
++Required properties:
++- compatible: should be "ambarella,input_adckey".
++- amb,keymap: the key-code to be reported when the key is pressed. Each entry
++  is organized as <ADC Keycode>, where ADC is packed as:
++    channel << 28 | high_level << 16 | low_level
++  Note: the resolution of ADC is 12 bits. And please see the "Note" in "ADC node".
++
++ii) Example
++-----------
++	input_adckey {
++		compatible = "ambarella,input_adckey";
++		amb,keymap =
++			/* channel 1 */
++			<0x1fff0c1c 0>,   /* KEY_RESERVED */
++			<0x1c1c0a8c 373>, /* KEY_MODE */
++			<0x19600708 111>, /* KEY_DELETE */
++			<0x154603e8 167>, /* KEY_RECORD */
++			<0x1320012c 211>, /* KEY_HP */
++			<0x10c80000 212>, /* KEY_CAMERA */
++			/* channel 3 */
++			<0x3fff0c1c 0>,   /* KEY_RESERVED */
++			<0x3c1c0af0 139>, /* KEY_MENU */
++			<0x3af007d0 106>, /* KEY_RIGHT */
++			<0x37d003e8 105>, /* KEY_LEFT */
++			<0x33e80190 108>, /* KEY_DOWN */
++			<0x31900000 103>; /* KEY_UP */
++	};
++
++
++
++4)  - PWM BACKLIGHT node
++========================
++
++i) Reference
++------------
++Please see Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
++
++ii) Properties
++--------------
++Required properties:
++- reg: specifies the pwm channel, no real meaning, just make the device name
++  more reasonable. It take effect only when putting the PWM BACKLIGHT node under
++  bogus_bus node.
++
+diff --git a/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt b/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt
+new file mode 100644
+index 00000000..d63194a2
+--- /dev/null
++++ b/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt
+@@ -0,0 +1,71 @@
++* PCF857x-compatible I/O expanders
++
++The PCF857x-compatible chips have "quasi-bidirectional" I/O lines that can be
++driven high by a pull-up current source or driven low to ground. This combines
++the direction and output level into a single bit per line, which can't be read
++back. We can't actually know at initialization time whether a line is configured
++(a) as output and driving the signal low/high, or (b) as input and reporting a
++low/high value, without knowing the last value written since the chip came out
++of reset (if any). The only reliable solution for setting up line direction is
++thus to do it explicitly.
++
++Required Properties:
++
++  - compatible: should be one of the following.
++    - "maxim,max7328": For the Maxim MAX7378
++    - "maxim,max7329": For the Maxim MAX7329
++    - "nxp,pca8574": For the NXP PCA8574
++    - "nxp,pca8575": For the NXP PCA8575
++    - "nxp,pca9670": For the NXP PCA9670
++    - "nxp,pca9671": For the NXP PCA9671
++    - "nxp,pca9672": For the NXP PCA9672
++    - "nxp,pca9673": For the NXP PCA9673
++    - "nxp,pca9674": For the NXP PCA9674
++    - "nxp,pca9675": For the NXP PCA9675
++    - "nxp,pcf8574": For the NXP PCF8574
++    - "nxp,pcf8574a": For the NXP PCF8574A
++    - "nxp,pcf8575": For the NXP PCF8575
++    - "ti,tca9554": For the TI TCA9554
++
++  - reg: I2C slave address.
++
++  - gpio-controller: Marks the device node as a gpio controller.
++  - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
++    cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
++    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
++
++Optional Properties:
++
++  - lines-initial-states: Bitmask that specifies the initial state of each
++  line. When a bit is set to zero, the corresponding line will be initialized to
++  the input (pulled-up) state. When the  bit is set to one, the line will be
++  initialized the the low-level output state. If the property is not specified
++  all lines will be initialized to the input state.
++
++  The I/O expander can detect input state changes, and thus optionally act as
++  an interrupt controller. When the expander interrupt line is connected all the
++  following properties must be set. For more information please see the
++  interrupt controller device tree bindings documentation available at
++  Documentation/devicetree/bindings/interrupt-controller/interrupts.txt.
++
++  - interrupt-controller: Identifies the node as an interrupt controller.
++  - #interrupt-cells: Number of cells to encode an interrupt source, shall be 2.
++  - interrupt-parent: phandle of the parent interrupt controller.
++  - interrupts: Interrupt specifier for the controllers interrupt.
++
++
++Please refer to gpio.txt in this directory for details of the common GPIO
++bindings used by client devices.
++
++Example: PCF8575 I/O expander node
++
++	pcf8575: gpio@20 {
++		compatible = "nxp,pcf8575";
++		reg = <0x20>;
++		interrupt-parent = <&irqpin2>;
++		interrupts = <3 0>;
++		gpio-controller;
++		#gpio-cells = <2>;
++		interrupt-controller;
++		#interrupt-cells = <2>;
++	};
+diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
+new file mode 100644
+index 00000000..011679f1
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
+@@ -0,0 +1,18 @@
++* AsahiKASEI AK8975 magnetometer sensor
++
++Required properties:
++
++  - compatible : should be "asahi-kasei,ak8975"
++  - reg : the I2C address of the magnetometer
++
++Optional properties:
++
++  - gpios : should be device tree identifier of the magnetometer DRDY pin
++
++Example:
++
++ak8975@0c {
++        compatible = "asahi-kasei,ak8975";
++        reg = <0x0c>;
++        gpios = <&gpj0 7 0>;
++};
+diff --git a/Documentation/devicetree/bindings/mfd/tps6507x.txt b/Documentation/devicetree/bindings/mfd/tps6507x.txt
+old mode 100755
+new mode 100644
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index d4195124..ec41ea75 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -221,6 +221,7 @@ config ARM_PATCH_PHYS_VIRT
+ 	default y
+ 	depends on !XIP_KERNEL && MMU
+ 	depends on !ARCH_REALVIEW || !SPARSEMEM
++	depends on !PLAT_AMBARELLA || PLAT_AMBARELLA_A8
+ 	help
+ 	  Patch phys-to-virt and virt-to-phys translation functions at
+ 	  boot and module load time according to the position of the
+@@ -298,6 +299,20 @@ config ARCH_MULTIPLATFORM
+ 	select SPARSE_IRQ
+ 	select USE_OF
+ 
++config ARCH_AMBARELLA
++	bool "Ambarella"
++	depends on MMU
++	select ARCH_HAS_CPUFREQ
++	select NEED_MACH_GPIO_H
++	select NEED_MACH_IO_H
++	select NEED_MACH_MEMORY_H
++	select PLAT_AMBARELLA
++	select USE_OF
++	select PINCTRL
++	select PINCTRL_AMB
++	help
++	  Support for Ambarella Media Processor.
++
+ config ARCH_INTEGRATOR
+ 	bool "ARM Ltd. Integrator family"
+ 	select ARCH_HAS_CPUFREQ
+@@ -917,6 +932,8 @@ endmenu
+ #
+ source "arch/arm/mach-mvebu/Kconfig"
+ 
++source "arch/arm/mach-ambarella/Kconfig"
++
+ source "arch/arm/mach-at91/Kconfig"
+ 
+ source "arch/arm/mach-bcm/Kconfig"
+@@ -1603,6 +1620,7 @@ config HZ
+ 		ARCH_S5PV210 || ARCH_EXYNOS4
+ 	default AT91_TIMER_HZ if ARCH_AT91
+ 	default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
++	default AMBARELLA_TIMER_HZ if PLAT_AMBARELLA
+ 	default 100
+ 
+ config SCHED_HRTICK
+@@ -2229,6 +2247,9 @@ config ARCH_SUSPEND_POSSIBLE
+ config ARM_CPU_SUSPEND
+ 	def_bool PM_SLEEP
+ 
++config ARCH_HIBERNATION_POSSIBLE
++	def_bool y
++
+ endmenu
+ 
+ source "net/Kconfig"
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index 1d41908d..c9b909ac 100644
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -81,6 +81,10 @@ choice
+ 	prompt "Kernel low-level debugging port"
+ 	depends on DEBUG_LL
+ 
++	config AMBARELLA_DEBUG_LL_UART0
++		bool "Kernel low-level debugging on Ambarella UART0"
++		depends on ARCH_AMBARELLA
++
+ 	config AT91_DEBUG_LL_DBGU0
+ 		bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
+ 		depends on HAVE_AT91_DBGU0
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index 7d4ce431..3d8fbe28 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -25,6 +25,9 @@ GZFLAGS		:=-9
+ # Never generate .eh_frame
+ KBUILD_CFLAGS	+= $(call cc-option,-fno-dwarf2-cfi-asm)
+ 
++# Never enable unaligned-access in kernel
++KBUILD_CFLAGS += $(call cc-option,-mno-unaligned-access)
++
+ # Do not use arch/arm/defconfig - it's always outdated.
+ # Select a platform tht is kept up-to-date
+ KBUILD_DEFCONFIG := versatile_defconfig
+@@ -143,8 +146,11 @@ textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
+ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
+ textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
+ 
++textofs-$(CONFIG_PLAT_AMBARELLA)	:= $(CONFIG_AMBARELLA_TEXTOFS)
++
+ # Machine directory name.  This list is sorted alphanumerically
+ # by CONFIG_* macro name.
++machine-$(CONFIG_ARCH_AMBARELLA)	+= ambarella
+ machine-$(CONFIG_ARCH_AT91)		+= at91
+ machine-$(CONFIG_ARCH_BCM)		+= bcm
+ machine-$(CONFIG_ARCH_BCM2835)		+= bcm2835
+diff --git a/arch/arm/boot/dts/ambarella-a5s.dtsi b/arch/arm/boot/dts/ambarella-a5s.dtsi
+new file mode 100644
+index 00000000..9c191189
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-a5s.dtsi
+@@ -0,0 +1,483 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,a5s";
++	interrupt-parent = <&intc>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		nand = &nand0;
++		emmc = &sdmmc0;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0xc0200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		cpu@0 {
++			device_type = "cpu";
++			compatible = "arm,arm1136";
++			reg = <0>;
++		};
++	};
++
++	apb@70000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x70000000 0x01000000>;
++		ranges;
++
++		timer2: timer@7000b010 {
++			compatible = "ambarella,clock-source";
++			reg = <0x7000b010 0x10 0x7000b030 0x4>;
++			interrupts = <13 0x1>;
++			ctrl-offset = <4>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer3: timer@7000b020 {
++			compatible = "ambarella,clock-event";
++			reg = <0x7000b020 0x10 0x7000b030 0x4>;
++			interrupts = <14 0x1>;
++			ctrl-offset = <8>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@70005000 {
++			compatible = "ambarella,uart";
++			reg = <0x70005000 0x1000>;
++			interrupts = <9 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			amb,less-reg;
++			status = "ok";
++		};
++
++		uart1: uart@7001f000 {
++			compatible = "ambarella,uart";
++			reg = <0x7001f000 0x1000>;
++			interrupts = <25 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart1_pins>;
++			amb,less-reg;
++			amb,msr-used;	/* use Modem Status Register */
++			status = "disabled";
++		};
++
++		i2c0: i2c@70003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70003000 0x1000>;
++			interrupts = <19 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		i2c1: i2c@70007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70007000 0x1000>;
++			interrupts = <36 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			status = "disabled";
++	        };
++
++		i2cmux {
++			compatible = "i2c-mux-pinctrl";
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			i2c-parent = <&i2c0>;
++
++			pinctrl-names = "i2c2", "idle";
++			pinctrl-0 = <&i2c2_pins>;
++			pinctrl-1 = <&i2c2_pins_idle>;
++
++			i2c@0 {
++				reg = <0>;
++				#address-cells = <1>;
++				#size-cells = <0>;
++			};
++		};
++
++		spi0: spi@70002000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70002000 0x1000>;
++			interrupts = <20 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <13500000>;
++			amb,msb-first-only;
++		};
++
++		spi1: spi@7000f000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x7000f000 0x1000>;
++			interrupts = <41 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi1_pins>;
++			amb,clk-freq = <13500000>;
++			amb,msb-first-only;
++		};
++
++		spi_slave@7001e000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0x7001e000 0x1000>;
++			interrupts = <26 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins>;
++			amb,id = <0>;
++		};
++
++		adc@7000d000 {
++			compatible = "ambarella,adc";
++			reg = <0x7000d000 0x1000>;
++			interrupts = <34 0x4>;
++			clock-frequency = <3000000>;
++			amb,polling-mode;
++		};
++
++		ir@70006000 {
++			compatible = "ambarella,ir";
++			reg = <0x70006000 0x1000>;
++			interrupts = <22 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@7000c000 {
++			compatible = "ambarella,wdt";
++			reg = <0x7000c000 0x1000>;
++			/* interrupts = <21 0x4>; */
++			timeout-sec = <15>;
++			amb,non-bootstatus;
++		};
++
++		rtc@7000d000 {
++			compatible = "ambarella,rtc";
++			reg = <0x7000d000 0x1000>;
++			amb,is-limited;
++		};
++
++		pwm: pwm@70004000 {
++			compatible = "ambarella,pwm";
++			reg = <0x70004000 0x1000 0x70008000 0x10>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@70009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70009000 0x1000>,
++			      <0x7000a000 0x1000>,
++			      <0x7000e000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <10 0x4 11 0x4 30 0x4>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 96>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x100e 0x100f>;
++			};
++
++			uart1_pins: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032 0x1034>,
++						 /* virtual pins, just for config */
++						 <0x1021 0x0022>;
++			};
++
++			uart1_flow_pins: uart1_flow@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1033 0x1035>,
++						 /* virtual pins, just for config */
++						 <0x0021 0x1022>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1027>; /* just WP is shared with GPIO */
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1000 0x1001>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1056 0x1057>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1024>;
++			};
++
++			i2c2_pins_idle: i2c2_idle@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x0024>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1023>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x104d 0x104e 0x104f 0x1050 0x1051>,
++						 /* virtual pins, just for config */
++						 <0x003f>;
++			};
++
++			pwm0_pins: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102d>;
++			};
++
++			pwm1_pins: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102e>;
++			};
++
++			pwm2_pins: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032>;
++			};
++
++			pwm3_pins: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1033>;
++			};
++
++			pwm5_pins: pwm5@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1010>;
++			};
++
++			sdio_pins: sdio@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1045 0x1046 0x1047
++						  0x1048 0x1049 0x104a>;
++			};
++
++			sdio_pins_idle: sdio_idle@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x0045 0x0046 0x0047
++						  0x0048 0x0049 0x004a>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1002 0x1003 0x1004>;
++			};
++
++			spi1_pins: spi1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1058 0x1059 0x105A>;
++			};
++
++			spi_slave_pins: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
++					/* virtual pins, just for
++					   configuration purpose.*/
++					<0x0021 0x1022>;
++			};
++		};
++	};
++
++	ahb@60000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x60000000 0x01000000>;
++		ranges;
++
++		intc: interrupt-controller@60003000 {
++			compatible = "ambarella,vic";
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0x60003000 0x1000>,
++			      <0x60010000 0x1000>;
++		};
++
++		dma: dma@60005000 {
++			compatible = "ambarella,dma";
++			reg = <0x60005000 0x1000>;
++			interrupts = <15 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <4>;
++			dma-requests = <4>;
++			dma-trans-type = <0 1 1 0>; /* 0-memcpy ,1-slave*/
++			amb,copy-align = <3>;
++		};
++
++		nand0: nand@60001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0x60001000 0x1000>, /* fio reg address */
++			      <0x60012000 0x1000>, /* fdma reg address */
++			      <0x60000000 0x4>;    /* fifo base */
++			interrupts = <16 0x4>,	/* fio_cmd_irq */
++				     <17 0x4>,	/* fio_dma_irq */
++				     <33 0x4>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			amb,enable-wp;
++			amb,no-bch;
++			amb,use-2x-pll;
++			nand-on-flash-bbt;
++		};
++
++		i2s0: i2s@6000a000 {
++			compatible = "ambarella,i2s";
++			reg = <0x6000a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++			dmas = <&dma 1 1>,
++				   <&dma 0 1>;
++			dma-names = "tx", "rx";
++		};
++
++		udc@60006000 {
++			compatible = "ambarella,udc";
++			reg = <0x60006000 0x2000 0x70170088 0x4>;
++			interrupts = <4 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		sdmmc0: sdmmc0@60002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x60002000 0x1000>,
++			      <0x60001000 0x80>; /* fio reg address */
++			interrupts = <18 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <524288>; /* valid value: 4K<<n */
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <24000000>;
++				bus-width = <4>;
++				cap-sdio-irq;
++				no-1-8-v;
++			};
++
++			slot@1 {
++				reg = <1>;
++				global-id = <1>;
++				max-frequency = <24000000>;
++				bus-width = <4>;
++				cap-sdio-irq;
++				no-1-8-v;
++
++				amb,force-gpio;
++				pinctrl-names = "work", "idle";
++				pinctrl-0 = <&sdio_pins>;
++				pinctrl-1 = <&sdio_pins_idle>;
++			};
++		};
++
++		mac0: ethernet@6000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x6000e000 0x2000>;
++			interrupts = <27 0x4>;
++			amb,tx-ring-size = <32>;
++			amb,rx-ring-size = <64>;
++		};
++
++		crypto@60014000 {
++			compatible = "ambarella,crypto";
++			reg = <0x60014000 0x1000>;
++			interrupts = <45 0x1>, <46 0x1>;
++			interrupt-names = "aes-irq", "des-irq";
++			amb,binary-mode;
++		};
++	};
++
++	rct@70170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x70170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@70170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0x70170050 0x4>;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++};
+diff --git a/arch/arm/boot/dts/ambarella-s2.dtsi b/arch/arm/boot/dts/ambarella-s2.dtsi
+new file mode 100644
+index 00000000..d9674e2d
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-s2.dtsi
+@@ -0,0 +1,577 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,s2";
++	interrupt-parent = <&gic>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		serial2 = &uart2;
++		serial3 = &uart3;
++		nand = &nand0;
++		sd0 = &sdmmc0;
++		sd1 = &sdmmc1;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		cpu@0 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0>;
++		};
++		cpu@1 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <1>;
++		};
++	};
++
++	gic: interrupt-controller@f0001000 {
++		compatible = "arm,cortex-a9-gic";
++		interrupt-controller;
++		#interrupt-cells = <3>;
++		reg = <0xf0001000 0x1000>,
++			  <0xf0000100 0x0100>;
++	};
++
++	apb@70000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x70000000 0x01000000>;
++		ranges;
++
++		timer7: timer@7000b064 {
++			compatible = "ambarella,clock-source";
++			reg = <0x7000b064 0x10 0x7000b030 0x4>;
++			interrupts = <0 108 0x1>;
++			ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer8: timer@7000b074 {
++			compatible = "ambarella,clock-event";
++			reg = <0x7000b074 0x10 0x7000b030 0x4>;
++			interrupts = <0 109 0x1>;
++			ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
++		};
++
++		/* local_timer is not used, just for debug purpose */
++		local_timer: timer@7000b054 {
++			compatible = "ambarella,local-clock-event";
++			reg = <0x7000b054 0x10 0x7000b030 0x4 0x7000b044 0x10 0x7000b030 0x4>;
++			interrupts = <0 107 0x1 0 106 0x1>;
++			ctrl-offset = <20 16>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@70005000 {
++			compatible = "ambarella,uart";
++			reg = <0x70005000 0x100>;
++			interrupts = <0 9 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			status = "ok";
++			/* amb,tx-fifo-fix; */
++		};
++
++		uart1: uart@7001f000 {
++			compatible = "ambarella,uart";
++			reg = <0x7001f000 0x100>;
++			interrupts = <0 25 0x04>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			/* amb,tx-fifo-fix; */
++		};
++
++		uart2: uart@70014000 {
++			compatible = "ambarella,uart";
++			reg = <0x70014000 0x100>;
++			interrupts = <0 91 0x04>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			/* amb,tx-fifo-fix; */
++		};
++
++		uart3: uart@70015000 {
++			compatible = "ambarella,uart";
++			reg = <0x70015000 0x100>;
++			interrupts = <0 92 0x04>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			/* amb,tx-fifo-fix; */
++		};
++
++		i2c0: i2c@70003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70003000 0x1000>;
++			interrupts = <0 19 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		i2c1: i2c@70007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70007000 0x1000>;
++			interrupts = <0 36 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			status = "disabled";
++	        };
++
++		i2c2: i2c@70013000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70013000 0x1000>;
++			interrupts = <0 90 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		spi0: spi@70002000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70002000 0x1000>;
++			interrupts = <0 20 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <60000000>;
++			amb,msb-first-only;
++		};
++
++		spi_slave@7001e000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0x7001e000 0x1000>;
++			interrupts = <0 26 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins>;
++		};
++
++		adc@7000d000 {
++			compatible = "ambarella,adc";
++			reg = <0x7000d000 0x1000>;
++			interrupts = <0 34 0x4>;
++			clock-frequency = <3000000>;
++		};
++
++		ir@70006000 {
++			compatible = "ambarella,ir";
++			reg = <0x70006000 0x1000>;
++			interrupts = <0 22 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@7000c000 {
++			compatible = "ambarella,wdt";
++			reg = <0x7000c000 0x1000>;
++			/* interrupts = <0 101 0x4>; */
++			timeout-sec = <15>;
++		};
++
++		rtc@7000d000 {
++			compatible = "ambarella,rtc";
++			reg = <0x7000d000 0x1000>;
++		};
++
++		pwm: pwm@70004000 {
++			compatible = "ambarella,pwm";
++			reg = <0x70004000 0x1000 0x70008000 0x10>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@70009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70009000 0x1000>,
++			      <0x7000a000 0x1000>,
++			      <0x7000e000 0x1000>,
++			      <0x70010000 0x1000>,
++			      <0x70011000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <0 10 0x04>,
++					     <0 11 0x04>,
++					     <0 30 0x04>,
++					     <0 29 0x04>,
++					     <0 48 0x04>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 160>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x100e 0x100f>;
++			};
++
++			uart1_pins: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1034 0x1035>,
++						 /* virtual pins, just for configuration purpose */
++						 <0x1021 0x0022 0x1032 0x1033 0x1034 0x1035>;
++			};
++
++			uart1_4pins: uart1_4pins@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
++						 /* virtual pins, just for configuration purpose */
++						 <0x1021 0x0022 0x1032 0x1033 0x1034 0x1035>;
++			};
++
++			uart2_pins: uart2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x100a 0x1012>;
++			};
++
++			uart3_pins: uart3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1013 0x1014>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1027>; /* just WP is shared with GPIO */
++			};
++
++			sdmmc0_pins: sdmmc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1041 0x1042 0x1043 0x1044>;
++			};
++
++			sdmmc1_pins_1bit: sdmmc1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1045 0x1046 0x1047
++						  0x104b 0x104c>;
++			};
++
++			sdmmc1_pins_4bit: sdmmc1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x1045 0x1046 0x1047 0x1048
++						  0x1049 0x104a 0x104b 0x104c>;
++			};
++
++			eth_pins:eth0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1008 0x101c 0x101d 0x101e 0x101f
++						  0x1028 0x1029 0x102a 0x102b 0x102c
++						  0x102f 0x1030 0x1052 0x1053 0x105c
++						  0x105d 0x105e 0x105f 0x107c 0x107d
++						  0x107e 0x107f 0x1080 0x1088 0x1089
++						  0x108a>;
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1000 0x1001>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1056 0x1057>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1024 0x1025>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1023>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x104d 0x104e 0x104f 0x1050 0x1051>,
++						 /* virtual pins, just for configuration purpose.*/
++						 <0x0064 0x0065>;
++			};
++
++			usb_host_pins: uhc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1007 0x1009>,
++						 /* virtual pins, just for configuration purpose.
++						   EHCI_PRT_PWR and APP_PRT_OVCURR share the hw
++						   mode with SPI enable pin. */
++						 <0x1060 0x1061>;
++			};
++
++			pwm0_pins: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102d>;
++			};
++
++			pwm1_pins: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102e>;
++			};
++
++			pwm2_pins: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032>,
++						/* virtual pins, just for
++						   configuration purpose.*/
++						 <0x0021 0x0022>;
++			};
++
++			pwm3_pins: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1033>,
++						/* virtual pins, just for
++						   configuration purpose.*/
++						 <0x0022 0x0003>;
++			};
++
++			pwm5_pins: pwm5@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1010>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1002 0x1003 0x1004>;
++			};
++
++			spi_slave_pins: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
++					/* virtual pins, just for
++					   configuration purpose.*/
++					<0x0021 0x1022>;
++			};
++		};
++	};
++
++	ahb@60000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x60000000 0x01000000>;
++		ranges;
++
++		dma: dma@60005000 {
++			compatible = "ambarella,dma";
++			reg = <0x60005000 0x1000>;
++			interrupts = <0 15 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <5>;
++			dma-requests = <5>;
++			dma-trans-type = <0 1 1 1 1>; /* 0-memcpy ,1-slave*/
++			amb,copy-align = <3>;
++		};
++
++		nand0: nand@60001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0x60001000 0x1000>, /* fio reg address */
++			      <0x60012000 0x1000>, /* fdma reg address */
++			      <0x60000000 0x4>;    /* fifo base */
++			interrupts = <0 16 0x04>,	/* fio_cmd_irq */
++				     <0 17 0x04>,	/* fio_dma_irq */
++				     <0 33 0x04>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			nand-on-flash-bbt;
++			amb,enable-wp;
++		};
++
++		i2s0: i2s@6000a000 {
++			compatible = "ambarella,i2s";
++			reg = <0x6000a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++			dmas = <&dma 1 1>,
++				   <&dma 0 1>;
++			dma-names = "tx", "rx";
++		};
++
++		udc@60006000 {
++			compatible = "ambarella,udc";
++			reg = <0x60006000 0x2000 0x70170088 0x4>;
++			interrupts = <0 4 0x04>;
++			amb,usbphy = <&usbphy>;
++			amb,dma-addr-fix;
++		};
++
++		ehci@60018000 {
++			compatible = "ambarella,ehci";
++			reg = <0x60018000 0x1000>;
++			interrupts = <0 73 0x04>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ohci@60019000 {
++			compatible = "ambarella,ohci";
++			reg = <0x60019000 0x1000>;
++			interrupts = <0 89 0x04>;
++			amb,usbphy = <&usbphy>;
++			status = "disabled";
++		};
++
++		sdmmc0: sdmmc0@60002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x60002000 0x1000>,
++			      <0x60001000 0x80>, /* fio reg address */
++			      <0x701701d0 0x4>;
++			interrupts = <0 18 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <524288>; /* valid value: 4K<<n */
++			amb,phy-timing = <0x00000001 0xe3e0e3e0 0x00000000>,
++					 <0x00000080 0xe3e0e3e0 0x00071c00>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc0_pins>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <48000000>;
++				bus-width = <8>;
++				amb,caps-ddr;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc1: sdmmc1@6000c000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x6000c000 0x1000>,
++			      <0x60001000 0x80>, /* fio reg address */
++			      <0x701701d0 0x4>;
++			interrupts = <0 52 0x4>;
++			amb,dma-addr-fix;
++			amb,clk-name = "gclk_sdio";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <524288>; /* valid value: 4K<<n */
++			amb,phy-timing = <0x00000001 0x1c1f1c1f 0x00000000>,
++					 <0x00000080 0x1c1f1c1f 0x00e0e000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc1_pins_4bit>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <1>;
++				max-frequency = <48000000>;
++				bus-width = <4>;
++				amb,caps-ddr;
++				cap-sdio-irq;
++			};
++		};
++
++		mac0: ethernet@6000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x6000e000 0x2000>;
++			interrupts = <0 27 0x4>;
++			amb,support-gmii;
++			amb,tx-ring-size = <64>;
++			amb,rx-ring-size = <64>;
++			amb,ipc-rx;
++			pinctrl-names = "default";
++			pinctrl-0 = <&eth_pins>;
++		};
++	};
++
++	axi@f0000000 {	/* AXI */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xf0000000 0x00030000>;
++		ranges;
++
++		crypto@f0020000 {
++			compatible = "ambarella,crypto";
++			reg = <0xf0020000 0x8000>;
++			interrupts = <0 122 0x1>, <0 121 0x1>, <0 120 0x1>, <0 123 0x1>;
++			interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++			amb,cap-md5-sha1;
++			amb,data-swap;
++			amb,reg-64bit;
++		};
++	};
++
++	rct@70170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x70170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@70170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0x70170050 0x4 0x6001b00c 0x4 0x70170088 0x4>;
++			amb,host-phy-num = <1>;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++};
+diff --git a/arch/arm/boot/dts/ambarella-s2e.dtsi b/arch/arm/boot/dts/ambarella-s2e.dtsi
+new file mode 100644
+index 00000000..cfd40dad
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-s2e.dtsi
+@@ -0,0 +1,632 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,s2e";
++	interrupt-parent = <&intc>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		serial2 = &uart2;
++		serial3 = &uart3;
++		nand = &nand0;
++		sd0 = &sdmmc0;
++		sd1 = &sdmmc1;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		amb,core-div = <1>;
++		clock-latency = <100000>;
++		/* the highest frequency is gotten in runtime */
++		cpufreq_tbl = < /*core_clk	cortex_clk*/
++				24000		24000
++				108000		504000>;
++		cpu@a00 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0xa00>;
++		};
++		cpu@a01 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0xa01>;
++		};
++	};
++
++	apb@70000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x70000000 0x01000000>;
++		ranges;
++
++		timer7: timer@7000b064 {
++			compatible = "ambarella,clock-source";
++			reg = <0x7000b064 0x10 0x7000b030 0x4>;
++			interrupts = <62 0x1>;
++			ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer8: timer@7000b074 {
++			compatible = "ambarella,clock-event";
++			reg = <0x7000b074 0x10 0x7000b030 0x4>;
++			interrupts = <63 0x1>;
++			ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
++		};
++
++		/* timer6 and timer5 */
++		local_timer: timer@7000b054 {
++			compatible = "ambarella,local-clock-event";
++			reg = <0x7000b054 0x10 0x7000b030 0x4 0x7000b044 0x10 0x7000b030 0x4>;
++			interrupts = <61 0x1 60 0x1>;
++			ctrl-offset = <20 16>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@70005000 {
++			compatible = "ambarella,uart";
++			reg = <0x70005000 0x100>;
++			interrupts = <9 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			status = "ok";
++			/* amb,tx-fifo-fix; */
++		};
++
++		uart1: uart@7001f000 {
++			compatible = "ambarella,uart";
++			reg = <0x7001f000 0x100>;
++			interrupts = <25 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart1_pins>;
++			status = "ok";
++			amb,msr-used;	/* use Modem Status Register */
++			amb,txdma-used;
++			amb,rxdma-used;
++			/* amb,tx-fifo-fix; */
++		};
++
++		uart2: uart@70014000 {
++			compatible = "ambarella,uart";
++			reg = <0x70014000 0x100>;
++			interrupts = <91 0x04>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			/* amb,tx-fifo-fix; */
++		};
++
++		uart3: uart@70015000 {
++			compatible = "ambarella,uart";
++			reg = <0x70015000 0x100>;
++			interrupts = <92 0x04>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			/* amb,tx-fifo-fix; */
++		};
++
++		i2c0: i2c@70003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70003000 0x1000>;
++			interrupts = <19 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		i2c1: i2c@70007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70007000 0x1000>;
++			interrupts = <36 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			status = "disabled";
++	        };
++
++		i2c2: i2c@70013000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70013000 0x1000>;
++			interrupts = <90 0x04>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		spi0: spi@70002000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70002000 0x1000>;
++			interrupts = <20 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <60000000>;
++			amb,msb-first-only;
++		};
++
++		spi_slave@7001e000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0x7001e000 0x1000>;
++			interrupts = <26 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins>;
++			status = "disabled";
++		};
++
++		adc@7000d000 {
++			compatible = "ambarella,adc";
++			reg = <0x7000d000 0x1000>;
++			interrupts = <34 0x4>;
++			clock-frequency = <3000000>;
++		};
++
++		ir@70006000 {
++			compatible = "ambarella,ir";
++			reg = <0x70006000 0x1000>;
++			interrupts = <22 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@7000c000 {
++			compatible = "ambarella,wdt";
++			reg = <0x7000c000 0x1000>;
++			/* interrupts = <21 0x4>; */
++			timeout-sec = <15>;
++		};
++
++		rtc@7000d000 {
++			compatible = "ambarella,rtc";
++			reg = <0x7000d000 0x1000>;
++			rtc,wakeup;
++		};
++
++		pwm: pwm@70004000 {
++			compatible = "ambarella,pwm";
++			reg = <0x70004000 0x1000 0x70008000 0x10>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@70009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x70009000 0x1000>,
++			      <0x7000a000 0x1000>,
++			      <0x7000e000 0x1000>,
++			      <0x70010000 0x1000>,
++			      <0x70011000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <10 0x04>,
++					     <11 0x04>,
++					     <30 0x04>,
++					     <29 0x04>,
++					     <48 0x04>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 160>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x100e 0x100f>;
++			};
++
++			uart1_pins: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1034 0x1035>,
++						 /* virtual pins, just for configuration purpose */
++						 <0x1021 0x0022 0x1032 0x1033>;
++			};
++
++			uart1_4pins: uart1_4pins@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
++						 /* virtual pins, just for configuration purpose */
++						 <0x1021 0x0022>;
++			};
++
++			uart2_pins: uart2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x100a 0x1012>;
++			};
++
++			uart3_pins: uart3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1013 0x1014>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1027>; /* just WP is shared with GPIO */
++			};
++
++			sdmmc0_pins: sdmmc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1041 0x1042 0x1043 0x1044>;
++			};
++
++			sdmmc1_pins_1bit: sdmmc1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1045 0x1046 0x1047
++						  0x104b 0x104c>;
++			};
++
++			sdmmc1_pins_4bit: sdmmc1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x1045 0x1046 0x1047 0x1048
++						  0x1049 0x104a 0x104b 0x104c>;
++			};
++
++			eth_pins: eth0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1008 0x101c 0x101d 0x101e 0x101f
++						  0x1028 0x1029 0x102a 0x102b 0x102c
++						  0x102f 0x1030 0x1052 0x1053 0x105c
++						  0x105d 0x105e 0x105f 0x107c 0x107d
++						  0x107e 0x107f 0x1080 0x1088 0x1089
++						  0x108a>;
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1000 0x1001>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1056 0x1057>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1024 0x1025>,
++						 /* virtual pins, just for configuration purpose */
++						 <0x1011>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1023>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x104d 0x104e 0x104f 0x1050 0x1051>,
++						 /* virtual pins, just for configuration purpose.*/
++						 <0x0064 0x0065>;
++			};
++
++			usb_host_pins: uhc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1007 0x1009>,
++						 /* virtual pins, just for configuration purpose.
++						   EHCI_PRT_PWR and APP_PRT_OVCURR share the hw
++						   mode with SPI enable pin. */
++						 <0x1060 0x1061>;
++			};
++
++			pwm0_pins: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102d>;
++			};
++
++			pwm1_pins: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102e>;
++			};
++
++			pwm2_pins: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032>,
++						/* virtual pins, just for
++						   configuration purpose.*/
++						 <0x0021 0x0022>;
++			};
++
++			pwm3_pins: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1033>,
++						/* virtual pins, just for
++						   configuration purpose.
++						   <0x0022>: kernel may throw out error,
++						   			ignore it.*/
++						 <0x0022 0x0023>;
++			};
++
++			pwmVD_pins: pwmVD@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1010>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1002 0x1003 0x1004>;
++			};
++
++			spi1_pins: spi1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1058 0x1059 0x105A>;
++			};
++
++			spi_slave_pins: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
++					/* virtual pins, just for
++					   configuration purpose.*/
++					<0x0021 0x1022>;
++			};
++		};
++	};
++
++	ahb@60000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x60000000 0x01000000>;
++		ranges;
++
++		intc: interrupt-controller@60003000 {
++			compatible = "ambarella,vic";
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0x60003000 0x1000>,
++			      <0x60010000 0x1000>,
++			      <0x6001c000 0x1000>;
++		};
++
++		dma: dma@60005000 {
++			compatible = "ambarella,dma";
++			reg = <0x60005000 0x1000>;
++			interrupts = <15 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <8>;
++			dma-requests = <8>;
++			dma-trans-type = <1 1 1 1 1 1 1 1>; /* 0-memcpy ,1-slave*/
++			amb,copy-align = <0>;
++			/* support pause/resume/stop */
++			amb,support-prs;
++		};
++
++		nand0: nand@60001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0x60001000 0x1000>, /* fio reg address */
++			      <0x60012000 0x1000>, /* fdma reg address */
++			      <0x60000000 0x4>;    /* fifo base */
++			interrupts = <16 0x04>,	/* fio_cmd_irq */
++				     <17 0x04>,	/* fio_dma_irq */
++				     <33 0x04>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			nand-on-flash-bbt;
++			amb,enable-wp;
++			/* amb,soft-ecc = <1>; */
++		};
++
++		spinor0: spinor@6000d000 {
++			compatible = "ambarella,spinor";
++			reg = <0x6000d000 0x2ff>, /* spi nor controller */
++			      <0x60005300 0x20>;  /* dma reg */
++			status = "disabled";
++		};
++
++		spi1: spi@6001f000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x6001f000 0x1000>;
++			interrupts = <53 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi1_pins>;
++			amb,clk-freq = <54000000>;
++			status = "disabled";
++		};
++
++		i2s0: i2s@6000a000 {
++			compatible = "ambarella,i2s";
++			reg = <0x6000a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++			dmas = <&dma 2 1>,
++				   <&dma 1 1>;
++			dma-names = "tx", "rx";
++		};
++
++		udc@60006000 {
++			compatible = "ambarella,udc";
++			reg = <0x60006000 0x2000 0x70170088 0x4>;
++			interrupts = <4 0x04>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ehci@60018000 {
++			compatible = "ambarella,ehci";
++			reg = <0x60018000 0x1000>;
++			interrupts = <73 0x04>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ohci@60019000 {
++			compatible = "ambarella,ohci";
++			reg = <0x60019000 0x1000>;
++			interrupts = <89 0x04>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		sdmmc0: sdmmc0@60002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x60002000 0x1000>,
++			      <0x60001000 0x80>, /* fio reg address */
++			      <0x70170340 0x8>;
++			interrupts = <18 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <524288>; /* valid value: 4K<<n */
++			amb,auto-tuning;
++			amb,phy-type = <0>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
++			amb,phy-timing = <0x00000001 0x04070000 0x00000000>,
++					 <0x000000a4 0x00000005 0x00001111>,
++					 <0x00000040 0x00000001 0x00001111>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc0_pins>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <50000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc1: sdmmc1@6000c000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x6000c000 0x1000>,
++			      <0x60001000 0x80>, /* fio reg address */
++			      <0x701701d0 0x4>;
++			interrupts = <52 0x4>;
++			amb,clk-name = "gclk_sdio";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <524288>; /* valid value: 4K<<n */
++			amb,auto-tuning;
++			amb,phy-type = <2>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
++			amb,phy-timing = <0x00000001 0x1c1f1c1f 0x00000000>,
++					 <0x00000080 0x1c1f1c1f 0x00e0e000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc1_pins_4bit>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <1>;
++				max-frequency = <50000000>;
++				bus-width = <4>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		mac0: ethernet@6000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0x6000e000 0x2000>;
++			interrupts = <27 0x4>;
++			amb,support-gmii;
++			amb,tx-ring-size = <64>;
++			amb,rx-ring-size = <64>;
++			amb,ipc-rx;
++			pinctrl-names = "default";
++			pinctrl-0 = <&eth_pins>;
++		};
++	};
++
++	axi@f0000000 {	/* AXI */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xf0000000 0x00030000>;
++		ranges;
++
++		crypto@f0020000 {
++			compatible = "ambarella,crypto";
++			reg = <0xf0020000 0x8000>;
++			interrupts = <44 0x1>, <45 0x1>, <47 0x1>, <88 0x1>;
++			interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++			amb,cap-md5-sha1;
++			amb,data-swap;
++			amb,reg-64bit;
++		};
++		l2-cache@f0002000 {
++			compatible = "arm,pl310-cache";
++			reg = <0xf0002000 0x1000>;
++			cache-unified;
++			cache-level = <2>;
++			arm,tag_latency = <3 3 3>;
++			arm,data_latency = <3 3 3>;
++		};
++	};
++
++	rct@70170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0x70170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@70170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0x70170050 0x4 0x6001b00c 0x4 0x70170088 0x4>;
++			amb,host-phy-num = <1>;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++};
+diff --git a/arch/arm/boot/dts/ambarella-s2l.dtsi b/arch/arm/boot/dts/ambarella-s2l.dtsi
+new file mode 100644
+index 00000000..50fa4cbf
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-s2l.dtsi
+@@ -0,0 +1,776 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,s2l";
++	interrupt-parent = <&intc>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		nand = &nand0;
++		sd0 = &sdmmc0;
++		sd1 = &sdmmc1;
++		sd2 = &sdmmc2;
++		spinor = &spinor0;
++		spinand = &spinand0;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++		/* the gpio used to disconnect RESET signal to
++		 * dram, used for self-refresh, can be overwritten. */
++		ambarella,dram-reset-ctrl = <5>;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		clock-latency = <100000>;
++		/* the highest frequency is gotten in runtime */
++		cpufreq_tbl = < /*core_clk	cortex_clk*/
++				24000		96000
++				108000		504000>;
++
++		cpu@0 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0>;
++		};
++	};
++
++	apb@e8000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe8000000 0x01000000>;
++		ranges;
++
++		timer7: timer@e800b064 {
++			compatible = "ambarella,clock-source";
++			reg = <0xe800b064 0x10 0xe800b030 0x4>;
++			interrupts = <62 0x1>;
++			ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer8: timer@e800b074 {
++			compatible = "ambarella,clock-event";
++			reg = <0xe800b074 0x10 0xe800b030 0x4>;
++			interrupts = <63 0x1>;
++			ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@e8005000 {
++			compatible = "ambarella,uart";
++			reg = <0xe8005000 0x1000>;
++			interrupts = <9 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			status = "ok";
++			/* amb,tx-fifo-fix; */
++		};
++
++		i2c0: i2c@e8003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8003000 0x1000>;
++			interrupts = <19 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			/* amb,duty-cycle = <0>; */
++			status = "disabled";
++	        };
++
++		i2c1: i2c@e8001000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8001000 0x1000>;
++			interrupts = <51 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			status = "disabled";
++	        };
++
++		i2c2: i2c@e8007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8007000 0x1000>;
++			interrupts = <36 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		adc@e801d000 {
++			compatible = "ambarella,adc";
++			reg = <0xe801d000 0x1000>;
++			interrupts = <34 0x4>;
++			clock-frequency = <3000000>;
++		};
++
++		ir@e8006000 {
++			compatible = "ambarella,ir";
++			reg = <0xe8006000 0x1000>;
++			interrupts = <22 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@e800c000 {
++			compatible = "ambarella,wdt";
++			reg = <0xe800c000 0x1000>;
++			/* interrupts = <21 0x4>; */
++			timeout-sec = <15>;
++		};
++
++		rtc@e8015000 {
++			compatible = "ambarella,rtc";
++			reg = <0xe8015000 0x1000>;
++			rtc,wakeup;
++		};
++
++		pwm: pwm@e8008000 {
++			compatible = "ambarella,pwm";
++			reg = <0xe8008000 0x1000>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@e8009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8009000 0x1000>,
++			      <0xe800a000 0x1000>,
++			      <0xe800e000 0x1000>,
++			      <0xe8010000 0x1000>,
++			      <0xe8016000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "iomux";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <10 0x4 11 0x4 30 0x4 29 0x4>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 128>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1027 0x1028>;
++			};
++
++			uart1_pins_a: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2001 0x2002>;
++			};
++
++			uart1_pins_b: uart1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x200f 0x2010>;
++			};
++
++			uart1_pins_c: uart1@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2013 0x2014>;
++			};
++
++			uart1_pins_d: uart1@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x3022 0x3023>;
++			};
++
++			uart1_pins_e: uart1@4 {
++				reg = <4>;
++				amb,pinmux-ids = <0x2027 0x2028>;
++			};
++
++			uart1_flow_pins_a: uart1_flow@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2003 0x2004>;
++			};
++
++			uart1_flow_pins_b: uart1_flow@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5005 0x5006>;
++			};
++
++			uart1_flow_pins_c: uart1_flow@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2011 0x2012>;
++			};
++
++			uart1_flow_pins_d: uart1_flow@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x3015 0x3016>;
++			};
++
++			uart1_flow_pins_e: uart1_flow@4 {
++				reg = <4>;
++				amb,pinmux-ids = <0x3024 0x3025>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2036 0x2037 0x2038 0x203d
++						  0x203e 0x203f 0x2040 0x2041
++						  0x2042 0x2043 0x2044 0x2045
++						  0x2046 0x2047 0x2048>;
++			};
++
++			spinor0_pins: spinor0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x3037 0x3038 0x303d 0x303e
++						  0x303f 0x3040 0x3041 0x3042
++						  0x3043 0x3044 0x3045 0x3046
++						  0x3047>;
++			};
++
++			sdmmc0_cd_pin: sdmmc0_cd@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x203b>;
++			};
++
++			sdmmc0_wp_pin: sdmmc0_wp@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x203c>;
++			};
++
++			sdmmc0_pins_1bit: sdmmc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2039 0x203a 0x2049>;
++			};
++
++			sdmmc0_pins_4bit: sdmmc0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x2039 0x203a 0x2049
++						  0x204a 0x204b 0x204c>;
++			};
++
++			sdmmc0_pins_8bit: sdmmc0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2039 0x203a 0x2049 0x204a 0x204b
++						  0x204c 0x204d 0x204e 0x204f 0x2050>;
++			};
++
++			sdmmc1_cd_pin: sdmmc1_cd@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2057>;
++			};
++
++			sdmmc1_wp_pin: sdmmc1_wp@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2058>;
++			};
++
++			sdmmc1_pins_1bit: sdmmc1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2051 0x2052 0x2053>;
++			};
++
++			sdmmc1_pins_4bit: sdmmc1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x2051 0x2052 0x2053
++						  0x2054 0x2055 0x2056>;
++			};
++
++			sdmmc2_cd_pin: sdmmc2_cd@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x5008>;
++			};
++
++			sdmmc2_wp_pin: sdmmc2_wp@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x5009>;
++			};
++
++			sdmmc2_pins_1bit: sdmmc2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x5007 0x500a 0x5012>;
++			};
++
++			sdmmc2_pins_4bit: sdmmc2@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5007 0x500a 0x500b
++						  0x500c 0x500d 0x5012>;
++			};
++
++			sdmmc2_pins_8bit: sdmmc2@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5007 0x500a 0x500b 0x500c 0x500d
++						  0x500e 0x500f 0x5010 0x5011 0x5012>;
++			};
++
++			eth_pins: eth0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4019 0x401a 0x102e 0x102f
++						  0x1030 0x1031 0x1032 0x1033
++						  0x1034 0x1035>;
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101b 0x101c>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101d 0x101e>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101f 0x1020>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1021>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1029 0x102a 0x102b 0x102c 0x102d>;
++			};
++
++			usb_host0_pins: uhc0@0 { /* USB0: host/device configurable */
++				reg = <0>;
++				amb,pinmux-ids = <0x1002 0x1004>;
++			};
++
++			usb_host1_pins: uhc1@0 { /* USB1: host only */
++				reg = <0>;
++				amb,pinmux-ids = <0x1001 0x1003>;
++			};
++
++			pwm0_pins_a: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4007>;
++			};
++
++			pwm0_pins_b: pwm0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5013>;
++			};
++
++			pwm0_pins_c: pwm0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x1071>;
++			};
++
++			pwm1_pins_a: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1005>;
++			};
++
++			pwm1_pins_b: pwm1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x4008>;
++			};
++
++			pwm1_pins_c: pwm1@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5014>;
++			};
++
++			pwm1_pins_d: pwm1@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x5017>;
++			};
++
++			pwm2_pins_a: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1006>;
++			};
++
++			pwm2_pins_b: pwm2@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x4009>;
++			};
++
++			pwm2_pins_c: pwm2@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5015>;
++			};
++
++			pwm3_pins_a: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x400a>;
++			};
++
++			pwm3_pins_b: pwm3@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x200e>;
++			};
++
++			pwm3_pins_c: pwm3@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5016>;
++			};
++
++			spi_slave_pins_a: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4022 0x4023 0x4024 0x4025>;
++			};
++
++			spi_slave_pins_b: spi_slave@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x3013 0x3014 0x3015 0x3016>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1022 0x1023 0x1024>;
++			};
++
++			spi1_pins_a: spi1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2007 0x2008 0x2009>;
++			};
++
++			spi1_pins_b: spi1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x402e 0x402f 0x4030>;
++			};
++		};
++	};
++
++	ahb@e0000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe0000000 0x01000000>;
++		ranges;
++
++		intc: interrupt-controller@e0003000 {
++			compatible = "ambarella,vic";
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0xe0003000 0x1000>,
++			      <0xe0010000 0x1000>,
++			      <0xe001c000 0x1000>;
++		};
++
++		dma: dma@e0005000 {
++			compatible = "ambarella,dma";
++			reg = <0xe0005000 0x1000>;
++			interrupts = <15 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <8>;
++			dma-requests = <12>;
++			dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
++			amb,copy-align = <0>;
++		};
++
++		nand0: nand@e0001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0xe0001000 0x1000>, /* fio reg address */
++			      <0xe0012000 0x1000>, /* fdma reg address */
++			      <0xe0000000 0x4>;    /* fifo base */
++			interrupts = <16 0x4>,	/* fio_cmd_irq */
++				     <17 0x4>,	/* fio_dma_irq */
++				     <33 0x4>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			nand-on-flash-bbt;
++			amb,enable-wp;
++			/* amb,soft-ecc = <1>; */
++		};
++
++		spinor0: spinor@e0031000 {
++			compatible = "ambarella,spinor";
++			reg = <0xe0031000 0x2ff>, /* spi nor controller */
++			      <0xe0005300 0x20>;  /* dma reg */
++			pinctrl-names = "default";
++			pinctrl-0 = <&spinor0_pins>;
++			status = "disabled";
++		};
++
++		spinand0: spinand@e0031000 {
++			compatible = "ambarella,spinand";
++			reg = <0xe0031000 0x2ff>, /* spi nor controller */
++			      <0xe0005300 0x20>;  /* dma reg */
++			pinctrl-names = "default";
++			pinctrl-0 = <&spinor0_pins>;
++			status = "disabled";
++		};
++
++		uart1: uart@e0032000 {
++			compatible = "ambarella,uart";
++			reg = <0xe0032000 0x1000>;
++			interrupts = <25 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart1_pins_b &uart1_flow_pins_c>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			amb,txdma-used;
++			amb,rxdma-used;
++			/* amb,tx-fifo-fix; */
++			/* need to select pinctrl setup in board dts */
++		};
++
++		i2s0: i2s@e001a000 {
++			compatible = "ambarella,i2s";
++			reg = <0xe001a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++			dmas = <&dma 5 1>,
++				   <&dma 4 1>;
++			dma-names = "tx", "rx";
++		};
++
++		udc@e0006000 {
++			compatible = "ambarella,udc";
++			reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
++			interrupts = <4 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ehci@e0018000 {
++			compatible = "ambarella,ehci";
++			reg = <0xe0018000 0x1000>;
++			interrupts = <39 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ohci@e0019000 {
++			compatible = "ambarella,ohci";
++			reg = <0xe0019000 0x1000>;
++			interrupts = <44 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		sdmmc0: sdmmc0@e0002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0002000 0x1000>,
++			      <0xe0001000 0x80>, /* fio reg address */
++			      <0xec1704c0 0x8>;
++			interrupts = <18 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			amb,auto-tuning;
++			amb,phy-type = <0>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
++			amb,phy-timing = <0x00000001 0x04070000 0x00000000>,
++					<0x00000040 0x00000001 0x00001111>,/*for sdr104 200M*/
++					<0x000000A4 0x00000005 0x00001111>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc0_pins_8bit &sdmmc0_cd_pin &sdmmc0_wp_pin>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <50000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				amb,caps-ddr;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc1: sdmmc1@e000c000 {
++			compatible = "ambarella,sdmmc";
++			reg = <0xe000c000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			#address-cells = <1>;
++			#size-cells = <0>;
++			interrupts = <52 0x4>;
++			amb,clk-name = "gclk_sdio";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc1_pins_4bit &sdmmc1_cd_pin &sdmmc1_wp_pin>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <1>;
++				max-frequency = <50000000>;
++				bus-width = <4>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc2: sdmmc2@e001f000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe001f000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			interrupts = <20 0x4>;
++			amb,clk-name = "gclk_sdxc";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <20>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc2_pins_8bit &sdmmc2_cd_pin &sdmmc2_wp_pin>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <2>;
++				max-frequency = <50000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		mac0: ethernet@e000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe000e000 0x2000>;
++			interrupts = <27 0x4>;
++			amb,tx-ring-size = <32>;
++			amb,rx-ring-size = <64>;
++			amb,ipc-tx;
++			amb,ipc-rx;
++			pinctrl-names = "default";
++			pinctrl-0 = <&eth_pins>;
++		};
++
++		spi0: spi@e0020000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0020000 0x1000>;
++			interrupts = <35 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <54000000>;
++			amb,dma-used;
++			dmas = <&dma 0 1>,
++				   <&dma 1 1>;
++			dma-names = "tx", "rx";
++		};
++
++		spi1: spi@e0021000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0021000 0x1000>;
++			interrupts = <37 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi1_pins_a>;
++			amb,clk-freq = <54000000>;
++			status = "disabled";
++		};
++
++		spi_slave@e0026000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0xe0026000 0x1000>;
++			interrupts = <38 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins_a>;
++			status = "disabled";
++		};
++	};
++
++	axi@f0000000 {	/* AXI */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xf0000000 0x00030000>;
++		ranges;
++
++		crypto@f0020000 {
++			compatible = "ambarella,crypto";
++			reg = <0xf0020000 0x8000>;
++			interrupts = <88 0x1>, <87 0x1>, <86 0x1>, <89 0x1>;
++			interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++			amb,cap-md5-sha1;
++			amb,data-swap;
++			amb,reg-64bit;
++		};
++		l2-cache@f0002000 {
++			compatible = "arm,pl310-cache";
++			reg = <0xf0002000 0x1000>;
++			cache-unified;
++			cache-level = <2>;
++			/* l2 cache latency use default setting */
++			/* arm,tag_latency = <1 2 1>; */
++			/* arm,data_latency = <1 3 1>; */
++		};
++	};
++
++	rct@ec170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xec170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@ec170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
++			amb,host-phy-num = <2>;
++			amb,owner-mask;
++			amb,owner-invert;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++
++	amba_lens {
++		compatible = "ambarella,lens";
++		interrupts = <12 0x1>,	/* zoom_timer_irq */
++			   <13 0x1>,		/* focus_timer_irq */
++			   <14 0x1>;		/* iris_timer_irq */
++	};
++
++};
+diff --git a/arch/arm/boot/dts/ambarella-s3.dtsi b/arch/arm/boot/dts/ambarella-s3.dtsi
+new file mode 100644
+index 00000000..7d2e6d5f
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-s3.dtsi
+@@ -0,0 +1,703 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,s3";
++	interrupt-parent = <&intc>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		nand = &nand0;
++		spinor = &spinor0;
++		sd0 = &sdmmc0;
++		sd1 = &sdmmc1;
++		sd2 = &sdmmc2;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		cpu@a00 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0xa00>;
++		};
++		cpu@a01 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0xa01>;
++		};
++	};
++
++	apb@e8000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe8000000 0x01000000>;
++		ranges;
++
++		timer7: timer@e800b064 {
++			compatible = "ambarella,clock-source";
++			reg = <0xe800b064 0x10 0xe800b030 0x4>;
++			interrupts = <13 0x1>;
++			ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer8: timer@e800b074 {
++			compatible = "ambarella,clock-event";
++			reg = <0xe800b074 0x10 0xe800b030 0x4>;
++			interrupts = <14 0x1>;
++			ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
++		};
++
++		/* timer06 and timer16 */
++		local_timer: timer@e800b054 {
++			compatible = "ambarella,local-clock-event";
++			reg = <0xe800b054 0x10 0xe800b030 0x4 0xe800f054 0x10 0xe800f030 0x4>;
++			interrupts = <12 0x1 28 0x1>;
++			ctrl-offset = <20 20>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@e8005000 {
++			compatible = "ambarella,uart";
++			reg = <0xe8005000 0x1000>;
++			interrupts = <108 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			status = "ok";
++			/* amb,tx-fifo-fix; */
++		};
++
++		i2c0: i2c@e8003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8003000 0x1000>;
++			interrupts = <85 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		i2c1: i2c@e8001000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8001000 0x1000>;
++			interrupts = <84 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			status = "disabled";
++	        };
++
++		i2c2: i2c@e8007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8007000 0x1000>;
++			interrupts = <83 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		adc@e801d000 {
++			compatible = "ambarella,adc";
++			reg = <0xe801d000 0x1000>;
++			interrupts = <103 0x4>;
++			clock-frequency = <3000000>;
++		};
++
++		ir@e8006000 {
++			compatible = "ambarella,ir";
++			reg = <0xe8006000 0x1000>;
++			interrupts = <86 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@e800c000 {
++			compatible = "ambarella,wdt";
++			reg = <0xe800c000 0x1000>;
++			/* interrupts = <105 0x4>; */
++			timeout-sec = <15>;
++		};
++
++		rtc@e8015000 {
++			compatible = "ambarella,rtc";
++			reg = <0xe8015000 0x1000>;
++		};
++
++		pwm: pwm@e8008000 {
++			compatible = "ambarella,pwm";
++			reg = <0xe8008000 0x1000>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@e8009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8009000 0x1000>,
++			      <0xe800a000 0x1000>,
++			      <0xe800e000 0x1000>,
++			      <0xe8010000 0x1000>,
++			      <0xe8011000 0x1000>,
++			      <0xe800d000 0x1000>,
++			      <0xe8014000 0x1000>,
++			      <0xe8016000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2", "gpio3",
++				    "gpio4", "gpio5", "gpio6", "iomux";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <124 0x4>, <123 0x4>, <122 0x4>,
++					     <121 0x4>, <120 0x4>, <119 0x4>,
++					     <118 0x4>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 224>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1024 0x1025>;
++			};
++
++			uart1_pins_a: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2008 0x2009>;
++			};
++
++			uart1_pins_b: uart1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x301b 0x301c>;
++			};
++
++			uart1_pins_c: uart1@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x10c3 0x10c4>;
++			};
++
++			uart1_flow_pins_a: uart1_flow@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x200a 0x200b>;
++			};
++
++			uart1_flow_pins_b: uart1_flow@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x301d 0x301e>;
++			};
++
++			uart1_flow_pins_c: uart1_flow@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x10c5 0x10c6>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2073 0x2074 0x2075 0x207a
++						  0x207b 0x207c 0x207d 0x207e
++						  0x207f 0x2080 0x2081 0x2082
++						  0x2083 0x2084 0x2085>;
++			};
++
++			spinor0_pins: spinor0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x3076 0x3077 0x3078 0x3079
++						  0x307d 0x307e 0x307f 0x3080
++						  0x3081 0x3082 0x3083 0x3084
++						  0x3086 0x3087 0x3088 0x3089
++						  0x308c>;
++			};
++
++			sdmmc0_pins_1bit: sdmmc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
++						  0x2086 0x209a>;
++			};
++
++			sdmmc0_pins_4bit: sdmmc0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
++						  0x2086 0x2087 0x2088 0x2089
++						  0x209a>;
++			};
++
++			sdmmc0_pins_8bit: sdmmc0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
++						  0x2086 0x2087 0x2088 0x2089
++						  0x208a 0x208b 0x208c 0x208d
++						  0x209a>;
++			};
++
++			sdmmc1_pins_1bit: sdmmc1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
++						  0x5004>;
++			};
++
++			sdmmc1_pins_4bit: sdmmc1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
++						  0x5004 0x5005 0x5006 0x5007>;
++			};
++
++			sdmmc2_pins_1bit: sdmmc2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2094
++						  0x2095 0x209b>;
++			};
++
++			sdmmc2_pins_4bit: sdmmc2@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
++						  0x2092 0x2093 0x2094 0x2095
++						  0x209b>;
++			};
++
++			sdmmc2_pins_8bit: sdmmc2@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
++						  0x2092 0x2093 0x2094 0x2095
++						  0x2096 0x2097 0x2098 0x2099
++						  0x209b>;
++			};
++
++			eth_gmii_pins: eth0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102b 0x102c 0x102d 0x102e 0x102f
++						  0x1030 0x1031 0x1032 0x1033 0x1034
++						  0x1035 0x1036 0x1037 0x1038 0x1039
++						  0x103a 0x103b 0x103c 0x103d 0x103e
++						  0x103f 0x1040 0x1041 0x1042 0x1043
++						  0x1044 0x1045 0x1046>;
++			};
++
++			eth_mii_pins: eth0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x202b 0x202c 0x202d 0x202e 0x202f
++						  0x2030 0x2035 0x2036 0x2037 0x2038
++						  0x203d 0x203e 0x203f 0x2040 0x2041
++						  0x2042 0x2043 0x2044 0x2045 0x2046>;
++			};
++
++			eth_rmii_pins: eth0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x302b 0x302d 0x302e 0x3035 0x3036
++						  0x303f 0x3041 0x3042 0x3043 0x3044
++						  0x3045 0x3046>;
++			};
++
++			eth_rgmii_pins: eth0@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x402b 0x402d 0x402e 0x402f 0x4030
++						  0x4035 0x4036 0x4037 0x4038 0x403f
++						  0x4043 0x4044 0x4045 0x4046>;
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1014 0x1015>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1016 0x1017>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1018 0x1019>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101b 0x101c 0x101d>;
++			};
++
++			spi1_pins_a: spi1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2000 0x2001 0x2002>;
++			};
++
++			spi1_pins_b: spi1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x20c3 0x20c4 0x20c5>;
++			};
++
++			spi_slave_pins: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1020 0x1021 0x1022 0x1023>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101a>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1026 0x1027 0x1028 0x1029 0x102a>;
++			};
++
++			usb_host0_pins_a: uhc0@0 { /* USB0: host/device configurable */
++				reg = <0>;
++				amb,pinmux-ids = <0x300c 0x300e>;
++			};
++
++			usb_host0_pins_b: uhc0@1 { /* USB0: host/device configurable */
++				reg = <1>;
++				amb,pinmux-ids = <0x204b 0x204d>;
++			};
++
++			usb_host1_pins_a: uhc1@0 { /* USB1: host only */
++				reg = <0>;
++				amb,pinmux-ids = <0x300d 0x300f>;
++			};
++
++			usb_host1_pins_b: uhc1@1 { /* USB1: host only */
++				reg = <1>;
++				amb,pinmux-ids = <0x204c 0x204e>;
++			};
++
++			pwm0_pins_a: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4004>;
++			};
++
++			pwm0_pins_b: pwm0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x10bc>;
++			};
++
++			pwm1_pins: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4005>;
++			};
++
++			pwm2_pins: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4006>;
++			};
++
++			pwm3_pins: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4007>;
++			};
++		};
++	};
++
++	ahb@e0000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe0000000 0x01000000>;
++		ranges;
++
++		intc: interrupt-controller@e0003000 {
++			compatible = "ambarella,vic";
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0xe0003000 0x1000>,
++			      <0xe0010000 0x1000>,
++			      <0xe001c000 0x1000>,
++			      <0xe0011000 0x1000>;
++		};
++
++		dma: dma@e0005000 {
++			compatible = "ambarella,dma";
++			reg = <0xe0005000 0x1000>;
++			interrupts = <69 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <8>;
++			dma-requests = <14>;
++			dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
++			dma-channel-sel = <0 1 0 0 8 9 11 10>;
++			amb,copy-align = <0>;
++			/* support pause/resume/stop */
++			amb,support-prs;
++		};
++
++		nand0: nand@e0001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0xe0001000 0x1000>, /* fio reg address */
++			      <0xe0012000 0x1000>, /* fdma reg address */
++			      <0xe0000000 0x4>;    /* fifo base */
++			interrupts = <72 0x4>,	/* fio_cmd_irq */
++				     <73 0x4>,	/* fio_dma_irq */
++				     <70 0x4>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			nand-on-flash-bbt;
++			amb,enable-wp;
++			/* amb,soft-ecc = <1>; */
++		};
++
++		spinor0: spinor@e0031000 {
++			compatible = "ambarella,spinor";
++			reg = <0xe0031000 0x2ff>, /* spi nor controller */
++			      <0xe0005300 0x20>;  /* dma reg */
++			pinctrl-names = "default";
++			pinctrl-0 = <&spinor0_pins>;
++			status = "disabled";
++		};
++
++		uart1: uart@e0032000 {
++			compatible = "ambarella,uart";
++			reg = <0xe0032000 0x1000>;
++			interrupts = <82 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart1_pins_c &uart1_flow_pins_c>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			amb,txdma-used;
++			amb,rxdma-used;
++			/* amb,tx-fifo-fix; */
++			/* need to select pinctrl setup in board dts */
++		};
++
++		i2s0: i2s@e001a000 {
++			compatible = "ambarella,i2s";
++			reg = <0xe001a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++			dmas = <&dma 5 1>,
++				   <&dma 4 1>;
++			dma-names = "tx", "rx";
++		};
++
++		udc@e0006000 {
++			compatible = "ambarella,udc";
++			reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
++			interrupts = <68 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ehci@e0018000 {
++			compatible = "ambarella,ehci";
++			reg = <0xe0018000 0x1000>;
++			interrupts = <66 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ohci@e0019000 {
++			compatible = "ambarella,ohci";
++			reg = <0xe0019000 0x1000>;
++			interrupts = <67 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		sdmmc0: sdmmc0@e0002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0002000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			interrupts = <77 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc0_pins_8bit>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <48000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc1: sdmmc1@e000c000 {
++			compatible = "ambarella,sdmmc";
++			reg = <0xe000c000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			#address-cells = <1>;
++			#size-cells = <0>;
++			interrupts = <76 0x4>;
++			amb,clk-name = "gclk_sdio";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc1_pins_4bit>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <1>;
++				max-frequency = <48000000>;
++				bus-width = <4>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc2: sdmmc2@e001f000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe001f000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			interrupts = <75 0x4>;
++			amb,clk-name = "gclk_sdxc";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc2_pins_8bit>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <2>;
++				max-frequency = <12000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		mac0: ethernet@e000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe000e000 0x2000>;
++			interrupts = <65 0x4>;
++			amb,tx-ring-size = <32>;
++			amb,rx-ring-size = <64>;
++			amb,ipc-tx;
++			amb,ipc-rx;
++			pinctrl-names = "default";
++			pinctrl-0 = <&eth_gmii_pins>;
++		};
++
++		spi0: spi@e0020000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0020000 0x1000>;
++			interrupts = <80 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <54000000>;
++			dmas = <&dma 0 1>,
++				   <&dma 1 1>;
++			dma-names = "tx", "rx";
++		};
++
++		spi1: spi@e0021000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0021000 0x1000>;
++			interrupts = <79 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi1_pins_a>;
++			amb,clk-freq = <54000000>;
++			status = "disabled";
++		};
++
++		spi_slave@e0026000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0xe0026000 0x1000>;
++			interrupts = <81 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins>;
++			status = "disabled";
++		};
++	};
++
++	axi@f0000000 {	/* AXI */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xf0000000 0x00030000>;
++		ranges;
++
++		crypto@f0020000 {
++			compatible = "ambarella,crypto";
++			reg = <0xf0020000 0x8000>;
++			interrupts = <111 0x1>, <112 0x1>, <113 0x1>, <110 0x1>;
++			interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++			amb,cap-md5-sha1;
++			amb,data-swap;
++			amb,reg-64bit;
++		};
++	};
++
++	rct@ec170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xec170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@ec170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
++			amb,host-phy-num = <2>;
++			amb,owner-mask;
++			amb,owner-invert;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++};
+diff --git a/arch/arm/boot/dts/ambarella-s3l.dtsi b/arch/arm/boot/dts/ambarella-s3l.dtsi
+new file mode 100644
+index 00000000..44ebef8b
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-s3l.dtsi
+@@ -0,0 +1,781 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,s3l";
++	interrupt-parent = <&intc>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		nand = &nand0;
++		spinand = &spinand0;
++		spinor = &spinor0;
++		sd0 = &sdmmc0;
++		sd2 = &sdmmc2;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		ethernet0 = &mac0;
++		mdio-gpio0 = <&mdio0>;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++		/* the gpio used to disconnect RESET signal to
++		 * dram, used for self-refresh, can be overwritten. */
++		ambarella,dram-reset-ctrl = <5>;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		clock-latency = <100000>;
++		/* the highest frequency is gotten in runtime */
++		cpufreq_tbl = < /*core_clk	cortex_clk*/
++				24000           96000
++				72000		120000
++				96000		168000
++				108000		504000>;
++
++		cpu@0 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0>;
++		};
++	};
++
++	apb@e8000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe8000000 0x01000000>;
++		ranges;
++
++		timer7: timer@e800b064 {
++			compatible = "ambarella,clock-source";
++			reg = <0xe800b064 0x10 0xe800b030 0x4>;
++			interrupts = <6 0x1>;
++			ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer8: timer@e800b074 {
++			compatible = "ambarella,clock-event";
++			reg = <0xe800b074 0x10 0xe800b030 0x4>;
++			interrupts = <63 0x1>;
++			ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@e8005000 {
++			compatible = "ambarella,uart";
++			reg = <0xe8005000 0x1000>;
++			interrupts = <61 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			status = "ok";
++			/* amb,tx-fifo-fix; */
++		};
++
++		i2c0: i2c@e8003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8003000 0x1000>;
++			interrupts = <83 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		i2c1: i2c@e8001000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8001000 0x1000>;
++			interrupts = <82 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			status = "disabled";
++	        };
++
++		i2c2: i2c@e8007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8007000 0x1000>;
++			interrupts = <81 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			status = "disabled";
++	        };
++
++		adc@e801d000 {
++			compatible = "ambarella,adc";
++			reg = <0xe801d000 0x1000>;
++			interrupts = <57 0x4>;
++			clock-frequency = <3000000>;
++		};
++
++		ir@e8006000 {
++			compatible = "ambarella,ir";
++			reg = <0xe8006000 0x1000>;
++			interrupts = <84 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@e800c000 {
++			compatible = "ambarella,wdt";
++			reg = <0xe800c000 0x1000>;
++			/* interrupts = <59 0x4>; */
++			timeout-sec = <15>;
++		};
++
++		rtc@e8015000 {
++			compatible = "ambarella,rtc";
++			reg = <0xe8015000 0x1000>;
++			interrupts = <64 0x1>;
++			rtc,wakeup;
++		};
++
++		pwm: pwm@e8008000 {
++			compatible = "ambarella,pwm";
++			reg = <0xe8008000 0x1000>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@e8009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8009000 0x1000>,
++			      <0xe800a000 0x1000>,
++			      <0xe800e000 0x1000>,
++			      <0xe8010000 0x1000>,
++			      <0xe8016000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "iomux";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <52 0x4 51 0x4 50 0x4 49 0x4>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 128>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1028 0x1029>;
++			};
++
++			uart1_pins_a: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2001 0x2002>;
++			};
++
++			uart1_pins_b: uart1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x2010 0x2011>;
++			};
++
++			uart1_pins_c: uart1@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2014 0x2015>;
++			};
++
++			uart1_pins_d: uart1@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x3023 0x3024>;
++			};
++
++			uart1_pins_e: uart1@4 {
++				reg = <4>;
++				amb,pinmux-ids = <0x2028 0x2029>;
++			};
++
++			uart1_flow_pins_a: uart1_flow@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2003 0x2004>;
++			};
++
++			uart1_flow_pins_b: uart1_flow@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5005 0x5006>;
++			};
++
++			uart1_flow_pins_c: uart1_flow@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2012 0x2013>;
++			};
++
++			uart1_flow_pins_d: uart1_flow@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x2016 0x2017>;
++			};
++
++			uart1_flow_pins_e: uart1_flow@4 {
++				reg = <4>;
++				amb,pinmux-ids = <0x3025 0x3026>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2037 0x2038 0x2039 0x203e
++						  0x203f 0x2040 0x2041 0x2042
++						  0x2043 0x2044 0x2045 0x2046
++						  0x2047 0x2048 0x2049>;
++			};
++
++			spinor0_pins: spinor0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x3038 0x3039 0x303e 0x303f
++						  0x3040 0x3041 0x3042 0x3043
++						  0x3044 0x3045 0x3046 0x3047
++						  0x3048>;
++			};
++
++			sdmmc0_cd_pin: sdmmc0_cd@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x203c>;
++			};
++
++			sdmmc0_wp_pin: sdmmc0_wp@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x203d>;
++			};
++
++			sdmmc0_pins_1bit: sdmmc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x203a 0x203b 0x204a>;
++			};
++
++			sdmmc0_pins_4bit: sdmmc0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x203a 0x203b 0x204a
++						  0x204b 0x204c 0x204d>;
++			};
++
++			sdmmc0_pins_8bit: sdmmc0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x203a 0x203b 0x204a 0x204b 0x204c
++						  0x204d 0x204e 0x204f 0x2050 0x2051>;
++			};
++
++			sdmmc2_cd_pin: sdmmc2_cd@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2058>;
++			};
++
++			sdmmc2_wp_pin: sdmmc2_wp@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2059>;
++			};
++
++			sdmmc2_pins_1bit: sdmmc2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2052 0x2053 0x2054>;
++			};
++
++			sdmmc2_pins_4bit: sdmmc2@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x2052 0x2053 0x2054
++						  0x2055 0x2056 0x2057>;
++			};
++
++			sdmmc2_pins_8bit: sdmmc2@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2052 0x2053 0x2054 0x2055 0x2056
++						  0x2057 0x205a 0x205b 0x205c 0x205d>;
++			};
++
++			rmii_pins: eth0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102f 0x1030 0x1031 0x1032
++						  0x1033 0x1034 0x1035 0x1036>;
++			};
++
++			mii_pins: eth0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x302f 0x3030 0x3031 0x4011
++						  0x4012 0x4013 0x4014 0x4015
++						  0x4016 0x4017 0x4018 0x3032
++						  0x3033 0x3034 0x3035 0x3036>;
++			};
++
++			mdio_gpio_pins: mdio_gpio@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x401a 0x401b>;
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101c 0x101d>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101e 0x101f>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1020 0x1021>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1022>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102a 0x102b 0x102c 0x102d 0x102e>;
++			};
++
++			usb_host0_pins: uhc0@0 { /* USB0: host/device configurable */
++				reg = <0>;
++				amb,pinmux-ids = <0x1002 0x1004>;
++			};
++
++			pwm0_pins_a: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4008>;
++			};
++
++			pwm0_pins_b: pwm0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5014>;
++			};
++
++			pwm0_pins_c: pwm0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x1078>;
++			};
++
++			pwm1_pins_a: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1005>;
++			};
++
++			pwm1_pins_b: pwm1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x4009>;
++			};
++
++			pwm1_pins_c: pwm1@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5015>;
++			};
++
++			pwm1_pins_d: pwm1@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x5018>;
++			};
++
++			pwm2_pins_a: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1006>;
++			};
++
++			pwm2_pins_b: pwm2@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x400a>;
++			};
++
++			pwm2_pins_c: pwm2@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5016>;
++			};
++
++			pwm3_pins_a: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x400b>;
++			};
++
++			pwm3_pins_b: pwm3@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x200f>;
++			};
++
++			pwm3_pins_c: pwm3@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x5017>;
++			};
++
++			spi_slave_pins_a: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x3001 0x3002 0x3003 0x3004>;
++			};
++
++			spi_slave_pins_b: spi_slave@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x3010 0x3011 0x3012 0x3013>;
++			};
++
++			spi_slave_pins_c: spi_slave@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x3014 0x3015 0x3016 0x3017>;
++			};
++
++			spi_slave_pins_d: spi_slave@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x4023 0x4024 0x4025 0x4026>;
++			};
++
++			spi_slave_pins_e: spi_slave@4 {
++				reg = <4>;
++				amb,pinmux-ids = <0x504e 0x504f 0x5050 0x5051>;
++			};
++
++			spi_slave_pins_f: spi_slave@5 {
++				reg = <5>;
++				amb,pinmux-ids = <0x5054 0x5055 0x5056 0x5057>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1023 0x1024 0x1025>;
++			};
++
++			spi1_pins_a: spi1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2008 0x2009 0x200a>;
++			};
++
++			spi1_pins_b: spi1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x402f 0x4030 0x4031>;
++			};
++		};
++	};
++
++	ahb@e0000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe0000000 0x01000000>;
++		ranges;
++
++		intc: interrupt-controller@e0003000 {
++			compatible = "ambarella,vic";
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0xe0003000 0x1000>,
++			      <0xe0010000 0x1000>,
++			      <0xe001c000 0x1000>;
++		};
++
++		dma: dma@e0005000 {
++			compatible = "ambarella,dma";
++			reg = <0xe0005000 0x1000>;
++			interrupts = <69 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <8>;
++			dma-requests = <12>;
++			dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
++			dma-channel-sel = <4 5 0 0 8 9 11 10>;
++			amb,copy-align = <0>;
++			/* support pause/resume/stop */
++			amb,support-prs;
++		};
++
++		nand0: nand@e0001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0xe0001000 0x1000>, /* fio reg address */
++			      <0xe0012000 0x1000>, /* fdma reg address */
++			      <0xe0000000 0x4>;    /* fifo base */
++			interrupts = <72 0x4>,	/* fio_cmd_irq */
++				     <73 0x4>,	/* fio_dma_irq */
++				     <70 0x4>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			nand-on-flash-bbt;
++			amb,enable-wp;
++			/* amb,soft-ecc = <1>; */
++		};
++
++		spinand0: spinand@e0031000 {
++			compatible = "ambarella,spinand";
++			reg = <0xe0031000 0x2ff>, /* spi nor controller */
++				<0xe0005300 0x20>;  /* dma reg */
++			pinctrl-names = "default";
++			pinctrl-0 = <&spinor0_pins>;
++			status = "disabled";
++			};
++
++		spinor0: spinor@e0031000 {
++			compatible = "ambarella,spinor";
++			reg = <0xe0031000 0x2ff>, /* spi nor controller */
++			      <0xe0005300 0x20>;  /* dma reg */
++			pinctrl-names = "default";
++			pinctrl-0 = <&spinor0_pins>;
++			status = "disabled";
++		};
++
++		uart1: uart@e0032000 {
++			compatible = "ambarella,uart";
++			reg = <0xe0032000 0x1000>;
++			interrupts = <80 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart1_pins_c &uart1_flow_pins_d>;
++			status = "ok";
++			amb,msr-used;	/* use Modem Status Register */
++			amb,txdma-used;
++			amb,rxdma-used;
++			/* amb,tx-fifo-fix; */
++			/* need to select pinctrl setup in board dts */
++		};
++
++		i2s0: i2s@e001a000 {
++			compatible = "ambarella,i2s";
++			reg = <0xe001a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++			dmas = <&dma 5 1>, <&dma 4 1>;
++			dma-names = "tx", "rx";
++		};
++
++		udc@e0006000 {
++			compatible = "ambarella,udc";
++			reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
++			interrupts = <68 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ehci@e0018000 {
++			compatible = "ambarella,ehci";
++			reg = <0xe0018000 0x1000>;
++			interrupts = <66 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ohci@e0019000 {
++			compatible = "ambarella,ohci";
++			reg = <0xe0019000 0x1000>;
++			interrupts = <67 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		sdmmc0: sdmmc0@e0002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0002000 0x1000>,
++			      <0xe0001000 0x80>,/* fio reg address */
++			      <0xec1704c0 0x8>;  /* phy timing reg*/
++			interrupts = <75 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch-vol-tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			amb,auto-tuning;
++			amb,phy-type = <0>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
++			amb,phy-timing = <0x0000001f 0x04070000 0x00000000>,
++					/*sdr50 100M,sdr104 120M*/
++					<0x00000060 0x10410400 0x00D04104>,
++					<0x00000080 0x10410400  0x02504104>;/*DDR50 50M*/
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc0_pins_8bit &sdmmc0_cd_pin &sdmmc0_wp_pin>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <50000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc2: sdmmc2@e001f000 { /* SDXC rather than SDIO */
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe001f000 0x1000>,
++			      <0xe0001000 0x80>,/* fio reg address */
++			      <0xec1704c8 0x8>;  /* phy timing reg*/
++			interrupts = <74 0x4>;
++			amb,clk-name = "gclk_sdxc";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch-vol-tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			amb,auto-tuning;
++			amb,phy-type = <0>;
++			amb,phy-timing = <0x0000001f 0x04070000 0x00000000>,
++					/*sdr50 100M,sdr104 120M*/
++					<0x00000060 0x10410400 0x00D04104>,
++					<0x00000080 0x10410400  0x02504104>;/*DDR50 50M*/
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc2_pins_8bit &sdmmc2_cd_pin &sdmmc2_wp_pin>;
++
++			slot@0 {
++				reg = <0>;
++				global-id = <1>;
++				max-frequency = <50000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		mac0: ethernet@e000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe000e000 0x2000>;
++			interrupts = <65 0x4>;
++			amb,tx-ring-size = <32>;
++			amb,rx-ring-size = <64>;
++			amb,ipc-tx;
++			amb,ipc-rx;
++			//amb,mdio-gpio;
++			pinctrl-names = "default";
++			//pinctrl-0 = <&rmii_pins>;
++			pinctrl-0 = <&rmii_pins &mdio_gpio_pins>;
++		};
++
++		spi0: spi@e0020000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0020000 0x1000>;
++			interrupts = <78 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <54000000>;
++			/* amb,dma-used; */
++			dmas = <&dma 0 1>, <&dma 1 1>;
++			dma-names = "tx", "rx";
++		};
++
++		spi1: spi@e0021000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0021000 0x1000>;
++			interrupts = <77 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi1_pins_a>;
++			amb,clk-freq = <54000000>;
++			status = "disabled";
++		};
++
++		spi_slave@e0026000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0xe0026000 0x1000>;
++			interrupts = <79 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins_a>;
++			status = "disabled";
++		};
++	};
++
++	axi@f0000000 {	/* AXI */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xf0000000 0x00030000>;
++		ranges;
++
++		crypto@f0020000 {
++			compatible = "ambarella,crypto";
++			reg = <0xf0020000 0x8000>;
++			interrupts = <30 0x1>, <29 0x1>, <28 0x1>, <31 0x1>;
++			interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++			amb,cap-md5-sha1;
++			amb,data-swap;
++			amb,reg-64bit;
++		};
++
++		l2-cache@f0002000 {
++			compatible = "arm,pl310-cache";
++			reg = <0xf0002000 0x1000>;
++			cache-unified;
++			cache-level = <2>;
++			/* l2 cache latency use default setting */
++			/* arm,tag_latency = <1 2 1>; */
++			/* arm,data_latency = <1 3 1>; */
++		};
++	};
++
++	rct@ec170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xec170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@ec170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
++			amb,host-phy-num = <1>;
++			amb,owner-mask;
++			amb,owner-invert;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++
++	mdio0: mdio {
++		compatible = "virtual,mdio-gpio";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		gpios = <&gpio 26 0
++			 &gpio 27 0>;
++
++		phy@0{
++			reg = <0>;
++		};
++	};
++
++	amba_lens {
++		compatible = "ambarella,lens";
++		interrupts = <4 0x1>,	/* zoom_timer_irq */
++			   <1 0x1>,	/* focus_timer_irq */
++			   <2 0x1>;	/* iris_timer_irq */
++	};
++
++};
+diff --git a/arch/arm/boot/dts/ambarella-supercam.dtsi b/arch/arm/boot/dts/ambarella-supercam.dtsi
+new file mode 100644
+index 00000000..a0758f75
+--- /dev/null
++++ b/arch/arm/boot/dts/ambarella-supercam.dtsi
+@@ -0,0 +1,701 @@
++/*
++ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++/include/ "skeleton.dtsi"
++
++/ {
++	compatible = "ambarella,s3";
++	interrupt-parent = <&intc>;
++
++	aliases {
++		serial0 = &uart0;
++		serial1 = &uart1;
++		nand = &nand0;
++		spinor = &spinor0;
++		emmc = &sdmmc0;
++		i2c0 = &i2c0;
++		i2c1 = &i2c1;
++		i2c2 = &i2c2;
++		spi0 = &spi0;
++		spi1 = &spi1;
++		ethernet0 = &mac0;
++	};
++
++	/* the memory node will be overwritten in Amboot,
++	 * here is just the default value. */
++	memory {
++		device_type = "memory";
++		reg = <0x00200000 0x07e00000>; /* 126M */
++	};
++
++	chosen {
++		linux,stdout-path = &uart0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		cpu@a00 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0xa00>;
++		};
++		cpu@a01 {
++			device_type = "cpu";
++			compatible = "arm,cortex-a9";
++			reg = <0xa01>;
++		};
++	};
++
++	apb@e8000000 {	/* APB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe8000000 0x01000000>;
++		ranges;
++
++		timer7: timer@e800b064 {
++			compatible = "ambarella,clock-source";
++			reg = <0xe800b064 0x10 0xe800b030 0x4>;
++			interrupts = <13 0x1>;
++			ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
++		};
++
++		timer8: timer@e800b074 {
++			compatible = "ambarella,clock-event";
++			reg = <0xe800b074 0x10 0xe800b030 0x4>;
++			interrupts = <14 0x1>;
++			ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
++		};
++
++		/* timer06 and timer16 */
++		local_timer: timer@e800b054 {
++			compatible = "ambarella,local-clock-event";
++			reg = <0xe800b054 0x10 0xe800b030 0x4 0xe800f054 0x10 0xe800f030 0x4>;
++			interrupts = <12 0x1 28 0x1>;
++			ctrl-offset = <20 20>; /* bit offset in timer-ctrl reg */
++		};
++
++		uart0: uart@e8005000 {
++			compatible = "ambarella,uart";
++			reg = <0xe8005000 0x1000>;
++			interrupts = <108 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++			status = "ok";
++			/* amb,tx-fifo-fix; */
++		};
++
++		i2c0: i2c@e8003000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8003000 0x1000>;
++			interrupts = <85 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			amb,bulk-num = <60>;
++			status = "disabled";
++	        };
++
++		i2c1: i2c@e8001000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8001000 0x1000>;
++			interrupts = <84 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c1_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x08>;
++			amb,bulk-num = <60>;
++			status = "disabled";
++	        };
++
++		i2c2: i2c@e8007000 {
++			compatible = "ambarella,i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8007000 0x1000>;
++			interrupts = <83 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			clock-frequency = <100000>;
++			amb,i2c-class = <0x81>;
++			amb,bulk-num = <60>;
++			status = "disabled";
++	        };
++
++		adc@e801d000 {
++			compatible = "ambarella,adc";
++			reg = <0xe801d000 0x1000>;
++			interrupts = <103 0x4>;
++			clock-frequency = <3000000>;
++		};
++
++		ir@e8006000 {
++			compatible = "ambarella,ir";
++			reg = <0xe8006000 0x1000>;
++			interrupts = <86 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&ir_pins>;
++		};
++
++		wdt@e800c000 {
++			compatible = "ambarella,wdt";
++			reg = <0xe800c000 0x1000>;
++			/* interrupts = <105 0x4>; */
++			timeout-sec = <15>;
++		};
++
++		rtc@e8015000 {
++			compatible = "ambarella,rtc";
++			reg = <0xe8015000 0x1000>;
++		};
++
++		pwm: pwm@e8008000 {
++			compatible = "ambarella,pwm";
++			reg = <0xe8008000 0x1000>;
++			#pwm-cells = <3>;
++		};
++
++		pinctrl: pinctrl@e8009000 {
++			compatible = "ambarella,pinctrl", "simple-bus";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe8009000 0x1000>,
++			      <0xe800a000 0x1000>,
++			      <0xe800e000 0x1000>,
++			      <0xe8010000 0x1000>,
++			      <0xe8011000 0x1000>,
++			      <0xe800d000 0x1000>,
++			      <0xe8014000 0x1000>,
++			      <0xe8016000 0x1000>;
++			reg-names = "gpio0", "gpio1", "gpio2", "gpio3",
++				    "gpio4", "gpio5", "gpio6", "iomux";
++			#gpio-range-cells = <3>;
++
++			gpio: gpio@0 {
++				compatible = "ambarella,gpio";
++				/* gpio interrupts to vic */
++				interrupts = <124 0x4>, <123 0x4>, <122 0x4>,
++					     <121 0x4>, <120 0x4>, <119 0x4>,
++					     <118 0x4>;
++				gpio-controller;
++				#gpio-cells = <2>;
++				gpio-ranges = <&pinctrl 0 0 224>;
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			uart0_pins: uart0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1024 0x1025>;
++			};
++
++			uart1_pins_a: uart1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2008 0x2009>;
++			};
++
++			uart1_pins_b: uart1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x301b 0x301c>;
++			};
++
++			uart1_pins_c: uart1@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x10c3 0x10c4>;
++			};
++
++			uart1_flow_pins_a: uart1_flow@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x200a 0x200b>;
++			};
++
++			uart1_flow_pins_b: uart1_flow@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x301d 0x301e>;
++			};
++
++			uart1_flow_pins_c: uart1_flow@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x10c5 0x10c6>;
++			};
++
++			nand0_pins: nand0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2073 0x2074 0x2075 0x207a
++						  0x207b 0x207c 0x207d 0x207e
++						  0x207f 0x2080 0x2081 0x2082
++						  0x2083 0x2084 0x2085>;
++			};
++
++			spinor0_pins: spinor0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x3076 0x3077 0x3078 0x3079
++						  0x307d 0x307e 0x307f 0x3080
++						  0x3081 0x3082 0x3083 0x3084
++						  0x3086 0x3087 0x3088 0x3089
++						  0x308c>;
++			};
++
++			sdmmc0_pins_1bit: sdmmc0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
++						  0x2086 0x209a>;
++			};
++
++			sdmmc0_pins_4bit: sdmmc0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
++						  0x2086 0x2087 0x2088 0x2089
++						  0x209a>;
++			};
++
++			sdmmc0_pins_8bit: sdmmc0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
++						  0x2086 0x2087 0x2088 0x2089
++						  0x208a 0x208b 0x208c 0x208d
++						  0x209a>;
++			};
++
++			sdmmc1_pins_1bit: sdmmc1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
++						  0x5004>;
++			};
++
++			sdmmc1_pins_4bit: sdmmc1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
++						  0x5004 0x5005 0x5006 0x5007>;
++			};
++
++			sdmmc2_pins_1bit: sdmmc2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2094
++						  0x2095 0x209b>;
++			};
++
++			sdmmc2_pins_4bit: sdmmc2@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
++						  0x2092 0x2093 0x2094 0x2095
++						  0x209b>;
++			};
++
++			sdmmc2_pins_8bit: sdmmc2@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
++						  0x2092 0x2093 0x2094 0x2095
++						  0x2096 0x2097 0x2098 0x2099
++						  0x209b>;
++			};
++
++			eth_gmii_pins: eth0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x102b 0x102c 0x102d 0x102e 0x102f
++						  0x1030 0x1031 0x1032 0x1033 0x1034
++						  0x1035 0x1036 0x1037 0x1038 0x1039
++						  0x103a 0x103b 0x103c 0x103d 0x103e
++						  0x103f 0x1040 0x1041 0x1042 0x1043
++						  0x1044 0x1045 0x1046>;
++			};
++
++			eth_mii_pins: eth0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x202b 0x202c 0x202d 0x202e 0x202f
++						  0x2030 0x2035 0x2036 0x2037 0x2038
++						  0x203d 0x203e 0x203f 0x2040 0x2041
++						  0x2042 0x2043 0x2044 0x2045 0x2046>;
++			};
++
++			eth_rmii_pins: eth0@2 {
++				reg = <2>;
++				amb,pinmux-ids = <0x302b 0x302d 0x302e 0x3035 0x3036
++						  0x303f 0x3041 0x3042 0x3043 0x3044
++						  0x3045 0x3046>;
++			};
++
++			eth_rgmii_pins: eth0@3 {
++				reg = <3>;
++				amb,pinmux-ids = <0x402b 0x402d 0x402e 0x402f 0x4030
++						  0x4035 0x4036 0x4037 0x4038 0x403f
++						  0x4043 0x4044 0x4045 0x4046>;
++			};
++
++			i2c0_pins: i2c0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1014 0x1015>;
++			};
++
++			i2c1_pins: i2c1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1016 0x1017>;
++			};
++
++			i2c2_pins: i2c2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1018 0x1019>;
++			};
++
++			spi0_pins: spi0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101b 0x101c 0x101d>;
++			};
++
++			spi1_pins_a: spi1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x2000 0x2001 0x2002>;
++			};
++
++			spi1_pins_b: spi1@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x20c3 0x20c4 0x20c5>;
++			};
++
++			spi_slave_pins: spi_slave@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1020 0x1021 0x1022 0x1023>;
++			};
++
++			ir_pins: ir0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x101a>;
++			};
++
++			i2s0_pins: i2s0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x1026 0x1027 0x1028 0x1029 0x102a>;
++			};
++
++			usb_host0_pins_a: uhc0@0 { /* USB0: host/device configurable */
++				reg = <0>;
++				amb,pinmux-ids = <0x300c 0x300e>;
++			};
++
++			usb_host0_pins_b: uhc0@1 { /* USB0: host/device configurable */
++				reg = <1>;
++				amb,pinmux-ids = <0x204b 0x204d>;
++			};
++
++			usb_host1_pins_a: uhc1@0 { /* USB1: host only */
++				reg = <0>;
++				amb,pinmux-ids = <0x300d 0x300f>;
++			};
++
++			usb_host1_pins_b: uhc1@1 { /* USB1: host only */
++				reg = <1>;
++				amb,pinmux-ids = <0x204c 0x204e>;
++			};
++
++			pwm0_pins_a: pwm0@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4004>;
++			};
++
++			pwm0_pins_b: pwm0@1 {
++				reg = <1>;
++				amb,pinmux-ids = <0x10bc>;
++			};
++
++			pwm1_pins: pwm1@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4005>;
++			};
++
++			pwm2_pins: pwm2@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4006>;
++			};
++
++			pwm3_pins: pwm3@0 {
++				reg = <0>;
++				amb,pinmux-ids = <0x4007>;
++			};
++		};
++	};
++
++	ahb@e0000000 {	/* AHB */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xe0000000 0x01000000>;
++		ranges;
++
++		intc: interrupt-controller@e0003000 {
++			compatible = "ambarella,vic";
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0xe0003000 0x1000>,
++			      <0xe0010000 0x1000>,
++			      <0xe001c000 0x1000>,
++			      <0xe0011000 0x1000>;
++		};
++
++		dma: dma@e0005000 {
++			compatible = "ambarella,dma";
++			reg = <0xe0005000 0x1000>;
++			interrupts = <69 0x4>;
++			#dma-cells = <2>;
++			dma-channels = <8>;
++			dma-requests = <14>;
++			dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
++			amb,copy-align = <0>;
++			/* support pause/resume/stop */
++			amb,support-prs;
++		};
++
++		nand0: nand@e0001000 {
++			compatible = "ambarella,nand";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			reg = <0xe0001000 0x1000>, /* fio reg address */
++			      <0xe0012000 0x1000>, /* fdma reg address */
++			      <0xe0000000 0x4>;    /* fifo base */
++			interrupts = <72 0x4>,	/* fio_cmd_irq */
++				     <73 0x4>,	/* fio_dma_irq */
++				     <70 0x4>;	/* fdma_irq */
++			pinctrl-names = "default";
++			pinctrl-0 = <&nand0_pins>;
++			nand-on-flash-bbt;
++			amb,enable-wp;
++			/* amb,soft-ecc = <1>; */
++		};
++
++		spinor0: spinor@e0031000 {
++			compatible = "ambarella,spinor";
++			reg = <0xe0031000 0x2ff>, /* spi nor controller */
++			      <0xe0005300 0x20>;  /* dma reg */
++			pinctrl-names = "default";
++			pinctrl-0 = <&spinor0_pins>;
++			status = "disabled";
++		};
++
++		uart1: uart@e0032000 {
++			compatible = "ambarella,uart";
++			reg = <0xe0032000 0x1000>;
++			interrupts = <82 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart1_pins_c &uart1_flow_pins_c>;
++			status = "disabled";
++			amb,msr-used;	/* use Modem Status Register */
++			amb,txdma-used;
++			amb,rxdma-used;
++			/* amb,tx-fifo-fix; */
++			/* need to select pinctrl setup in board dts */
++		};
++
++		i2s0: i2s@e001a000 {
++			compatible = "ambarella,i2s";
++			reg = <0xe001a000 0x1000>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2s0_pins>;
++			amb,i2s-channels = <2>;
++			amb,default-mclk = <12288000>;
++		};
++
++		udc@e0006000 {
++			compatible = "ambarella,udc";
++			reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
++			interrupts = <68 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ehci@e0018000 {
++			compatible = "ambarella,ehci";
++			reg = <0xe0018000 0x1000>;
++			interrupts = <66 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		ohci@e0019000 {
++			compatible = "ambarella,ohci";
++			reg = <0xe0019000 0x1000>;
++			interrupts = <67 0x4>;
++			amb,usbphy = <&usbphy>;
++		};
++
++		sdmmc0: sdmmc0@e0002000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0002000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			interrupts = <77 0x4>;
++			amb,clk-name = "gclk_sd";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc0_pins_8bit>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <0>;
++				max-frequency = <48000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc1: sdmmc1@e000c000 {
++			compatible = "ambarella,sdmmc";
++			reg = <0xe000c000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			#address-cells = <1>;
++			#size-cells = <0>;
++			interrupts = <76 0x4>;
++			amb,clk-name = "gclk_sdio";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc1_pins_4bit>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <1>;
++				max-frequency = <48000000>;
++				bus-width = <4>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		sdmmc2: sdmmc2@e001f000 {
++			compatible = "ambarella,sdmmc";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe001f000 0x1000>,
++			      <0xe0001000 0x80>; /* fio reg address */
++			interrupts = <75 0x4>;
++			amb,clk-name = "gclk_sdxc";
++			amb,wait-tmo = <10000>; /* in millisecond */
++			amb,switch_vol_tmo = <100>;
++			amb,max-blk-size = <131072>; /* valid value: 4K<<n */
++			pinctrl-names = "default";
++			pinctrl-0 = <&sdmmc2_pins_8bit>;
++			status = "disabled";
++
++			slot@0 {
++				reg = <0>;
++				global-id = <2>;
++				max-frequency = <12000000>;
++				bus-width = <8>;
++				amb,caps-adma;
++				cap-sdio-irq;
++			};
++		};
++
++		mac0: ethernet@e000e000 {
++			compatible = "ambarella,eth";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe000e000 0x2000>;
++			interrupts = <65 0x4>;
++			amb,tx-ring-size = <32>;
++			amb,rx-ring-size = <64>;
++			amb,ipc-tx;
++			amb,ipc-rx;
++			pinctrl-names = "default";
++			pinctrl-0 = <&eth_gmii_pins>;
++		};
++
++		spi0: spi@e0020000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0020000 0x1000>;
++			interrupts = <80 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi0_pins>;
++			amb,clk-freq = <54000000>;
++			dmas = <&dma 0 1>,
++				   <&dma 1 1>;
++			dma-names = "tx", "rx";
++		};
++
++		spi1: spi@e0021000 {
++			compatible = "ambarella,spi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xe0021000 0x1000>;
++			interrupts = <79 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi1_pins_b>;
++			amb,clk-freq = <54000000>;
++			status = "ok";
++		};
++
++		spi_slave@e0026000 {
++			compatible = "ambarella,spi-slave";
++			reg = <0xe0026000 0x1000>;
++			interrupts = <81 0x4>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&spi_slave_pins>;
++			status = "disabled";
++		};
++	};
++
++	axi@f0000000 {	/* AXI */
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xf0000000 0x00030000>;
++		ranges;
++
++		crypto@f0020000 {
++			compatible = "ambarella,crypto";
++			reg = <0xf0020000 0x8000>;
++			interrupts = <111 0x1>, <112 0x1>, <113 0x1>, <110 0x1>;
++			interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
++			amb,cap-md5-sha1;
++			amb,data-swap;
++			amb,reg-64bit;
++		};
++	};
++
++	rct@ec170000 {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		reg = <0xec170000 0x1000>;
++		ranges;
++
++		usbphy: usbphy@ec170050 {
++			compatible = "ambarella,usbphy";
++			reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
++			amb,host-phy-num = <2>;
++			amb,owner-mask;
++			amb,owner-invert;
++		};
++	};
++
++	iav {
++		compatible = "ambarella,iav";
++	};
++
++	bogus_bus {
++		compatible = "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		dummycodec: codec@0 {
++			compatible = "ambarella,dummycodec";
++		};
++	};
++};
+diff --git a/arch/arm/configs/ambarella_a5s_defconfig b/arch/arm/configs/ambarella_a5s_defconfig
+new file mode 100644
+index 00000000..595c8894
+--- /dev/null
++++ b/arch/arm/configs/ambarella_a5s_defconfig
+@@ -0,0 +1,2176 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.0 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_FHANDLE is not set
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++CONFIG_IRQ_DOMAIN_DEBUG=y
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++# CONFIG_TREE_PREEMPT_RCU is not set
++CONFIG_TINY_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++# CONFIG_RCU_STALL_COMMON is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
++# CONFIG_PLAT_AMBARELLA_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_MEM_START_LOW is not set
++# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_IOMUX is not set
++# CONFIG_PLAT_AMBARELLA_S2 is not set
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++CONFIG_PLAT_AMBARELLA_A5S=y
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++CONFIG_AMBARELLA_SUPPORT_BAPI=y
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++
++#
++# Sys file system support
++#
++# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
++# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0xC0208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0xC0200000
++CONFIG_AMBARELLA_INITRD_PHYS=0xC0A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=64
++CONFIG_AMBARELLA_EXT_GPIO_NUM=64
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V6=y
++CONFIG_CPU_32v6=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_ABRT_EV6=y
++CONFIG_CPU_PABRT_V6=y
++CONFIG_CPU_CACHE_V6=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V6=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++CONFIG_CPU_USE_DOMAINS=y
++
++#
++# Processor Features
++#
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++# CONFIG_CACHE_L2X0 is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_326103 is not set
++# CONFIG_ARM_ERRATA_411920 is not set
++# CONFIG_ARM_ERRATA_364296 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_NEED_PER_CPU_KM=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_ARM_APPENDED_DTB is not set
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_HIBERNATION is not set
++CONFIG_PM_SLEEP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=y
++CONFIG_NET_KEY=y
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_NET_IPVTI is not set
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++CONFIG_INET_IPCOMP=y
++CONFIG_INET_XFRM_TUNNEL=y
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++CONFIG_INET_UDP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++CONFIG_STP=y
++CONFIG_BRIDGE=y
++CONFIG_BRIDGE_IGMP_SNOOPING=y
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=y
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIBTSDIO is not set
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=y
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=y
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=y
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++# CONFIG_DMA_SHARED_BUFFER is not set
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_OF_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=y
++CONFIG_OF_MTD=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=y
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++CONFIG_NETCONSOLE=y
++CONFIG_NETCONSOLE_DYNAMIC=y
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++# CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE is not set
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++# CONFIG_MICREL_PHY_KSZ80X1R is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_WLAN is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=m
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA_IR=m
++CONFIG_INPUT_AMBARELLA_ADC=m
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_MUX=y
++
++#
++# Multiplexer I2C Chip support
++#
++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
++# CONFIG_I2C_MUX_GPIO is not set
++# CONFIG_I2C_MUX_PCA9541 is not set
++# CONFIG_I2C_MUX_PCA954x is not set
++CONFIG_I2C_MUX_PINCTRL=y
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++# CONFIG_SPI_SLAVE_AMBARELLA is not set
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_PINCTRL_SINGLE is not set
++# CONFIG_PINCTRL_EXYNOS is not set
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_PINCTRL_AMB=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=y
++CONFIG_FB_SYS_COPYAREA=y
++CONFIG_FB_SYS_IMAGEBLIT=y
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=y
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_L4F00242T03 is not set
++# CONFIG_LCD_LMS283GF05 is not set
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI922X is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++CONFIG_LCD_PLATFORM=y
++# CONFIG_LCD_S6E63M0 is not set
++# CONFIG_LCD_LD9040 is not set
++# CONFIG_LCD_AMS369FG06 is not set
++# CONFIG_LCD_LMS501KF03 is not set
++# CONFIG_LCD_HX8357 is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++# CONFIG_BACKLIGHT_GENERIC is not set
++# CONFIG_BACKLIGHT_PWM is not set
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++# CONFIG_LOGO is not set
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_SOC_DMAENGINE_PCM=y
++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBA_BOARD=m
++CONFIG_AMBARELLA_DUMMY_BOARD=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++CONFIG_SND_AMBARELLA_CODEC=m
++CONFIG_SND_SOC_AK4642_AMB=m
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=y
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=y
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=y
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=y
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=y
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=y
++# CONFIG_HID_LCPOWER is not set
++CONFIG_HID_LOGITECH=y
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=m
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_PHY=y
++CONFIG_USB_AMBARELLA_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++# CONFIG_SAMSUNG_USBPHY is not set
++# CONFIG_SAMSUNG_USB2PHY is not set
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++CONFIG_MMC_TEST=m
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++# CONFIG_RPROC_SUPPORT is not set
++# CONFIG_RPCLNT_SUPPORT is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++CONFIG_PWM=y
++CONFIG_PWM_AMBARELLA=m
++CONFIG_IRQCHIP=y
++CONFIG_AMBARELLA_VIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=m
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_FANOTIFY=y
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++
++#
++# RCU Debugging
++#
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_LKDTM is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=y
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=y
++# CONFIG_CRYPTO_USER_API_HASH is not set
++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
++CONFIG_CRYPTO_HW=y
++#CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++CONFIG_XZ_DEC_X86=y
++CONFIG_XZ_DEC_POWERPC=y
++CONFIG_XZ_DEC_IA64=y
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++CONFIG_XZ_DEC_SPARC=y
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_GENERIC_ATOMIC64=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_a7l_defconfig b/arch/arm/configs/ambarella_a7l_defconfig
+new file mode 100644
+index 00000000..3fe42184
+--- /dev/null
++++ b/arch/arm/configs/ambarella_a7l_defconfig
+@@ -0,0 +1,2063 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.0 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_FHANDLE is not set
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++# CONFIG_IRQ_DOMAIN_DEBUG is not set
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++# CONFIG_TREE_PREEMPT_RCU is not set
++CONFIG_TINY_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++# CONFIG_RCU_STALL_COMMON is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
++# CONFIG_PLAT_AMBARELLA_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_MEM_START_LOW is not set
++# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++# CONFIG_PLAT_AMBARELLA_S2 is not set
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++CONFIG_PLAT_AMBARELLA_A7L=y
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++CONFIG_AMBARELLA_SUPPORT_BAPI=y
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++
++#
++# Sys file system support
++#
++# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
++# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0xC0208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0xC0200000
++CONFIG_AMBARELLA_INITRD_PHYS=0xC0A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++
++#
++# FIO Configuration
++#
++# CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=64
++CONFIG_AMBARELLA_EXT_GPIO_NUM=64
++
++#
++# Ambarella Board
++#
++CONFIG_MACH_AMBARELLA=y
++CONFIG_MACH_DURIAN=y
++
++#
++# Misc on Board Devices
++#
++
++#
++# Ambarella
++#
++CONFIG_AMBARELLA_VOUT=y
++
++#
++# Touch
++#
++# CONFIG_TOUCH_AMBARELLA_AK4183 is not set
++# CONFIG_TOUCH_AMBARELLA_CHACHA_MT4D is not set
++# CONFIG_TOUCH_AMBARELLA_TM1510 is not set
++# CONFIG_TOUCH_AMBARELLA_TM1726 is not set
++# CONFIG_TOUCH_AMBARELLA_TM1927 is not set
++# CONFIG_TOUCH_AMBARELLA_FT540 is not set
++# CONFIG_TOUCH_AMBARELLA_NT11001 is not set
++
++#
++# LCD
++#
++
++#
++# RTC
++#
++
++#
++# Audio Codec
++#
++# CONFIG_CODEC_AMBARELLA_WM8737 is not set
++# CONFIG_CODEC_AMBARELLA_WM8994 is not set
++# CONFIG_CODEC_AMBARELLA_ES8328 is not set
++# CONFIG_CODEC_AMBARELLA_AK4642 is not set
++
++#
++# PMIC
++#
++# CONFIG_PMIC_AMBARELLA_WM831X is not set
++
++#
++# cpufreq-dev
++#
++# CONFIG_CPUFREQ_AMBARELLA_DEVICE is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V6=y
++CONFIG_CPU_32v6=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_ABRT_EV6=y
++CONFIG_CPU_PABRT_V6=y
++CONFIG_CPU_CACHE_V6=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V6=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++CONFIG_CPU_USE_DOMAINS=y
++
++#
++# Processor Features
++#
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++# CONFIG_CACHE_L2X0 is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_326103 is not set
++# CONFIG_ARM_ERRATA_411920 is not set
++# CONFIG_ARM_ERRATA_364296 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_NEED_PER_CPU_KM=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++
++#
++# Boot options
++#
++# CONFIG_USE_OF is not set
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_HIBERNATION is not set
++CONFIG_PM_SLEEP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=y
++CONFIG_NET_KEY=y
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_NET_IPVTI is not set
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++CONFIG_INET_IPCOMP=y
++CONFIG_INET_XFRM_TUNNEL=y
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++CONFIG_INET_UDP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++CONFIG_STP=y
++CONFIG_BRIDGE=y
++CONFIG_BRIDGE_IGMP_SNOOPING=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=y
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIBTSDIO is not set
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=y
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=y
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=y
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++# CONFIG_DMA_SHARED_BUFFER is not set
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=y
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_NETDEVICES is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA=m
++CONFIG_INPUT_AMBARELLA_IR=y
++CONFIG_INPUT_AMBARELLA_ADC=y
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_MUX=y
++
++#
++# Multiplexer I2C Chip support
++#
++# CONFIG_I2C_MUX_GPIO is not set
++CONFIG_I2C_MUX_AMBARELLA=y
++# CONFIG_I2C_MUX_PCA9541 is not set
++# CONFIG_I2C_MUX_PCA954x is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++# CONFIG_SPI_SLAVE_AMBARELLA is not set
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_CORE is not set
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=y
++CONFIG_FB_SYS_COPYAREA=y
++CONFIG_FB_SYS_IMAGEBLIT=y
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=y
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_L4F00242T03 is not set
++# CONFIG_LCD_LMS283GF05 is not set
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI922X is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++CONFIG_LCD_PLATFORM=y
++# CONFIG_LCD_S6E63M0 is not set
++# CONFIG_LCD_LD9040 is not set
++# CONFIG_LCD_AMS369FG06 is not set
++# CONFIG_LCD_LMS501KF03 is not set
++# CONFIG_LCD_HX8357 is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++# CONFIG_BACKLIGHT_GENERIC is not set
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++# CONFIG_LOGO is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBARELLA_DUMMY_BOARD=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=y
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=y
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=y
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=y
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=y
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=y
++# CONFIG_HID_LCPOWER is not set
++CONFIG_HID_LOGITECH=y
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=m
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_PHY is not set
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++CONFIG_MMC_TEST=m
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++
++#
++# HID Sensor RTC drivers
++#
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++# CONFIG_PWM is not set
++CONFIG_AMBARELLA_VIC=y
++CONFIG_AMBARELLA_GVIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=m
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_FANOTIFY=y
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++
++#
++# RCU Debugging
++#
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_LKDTM is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=y
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=y
++# CONFIG_CRYPTO_USER_API_HASH is not set
++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++CONFIG_XZ_DEC_X86=y
++CONFIG_XZ_DEC_POWERPC=y
++CONFIG_XZ_DEC_IA64=y
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++CONFIG_XZ_DEC_SPARC=y
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_GENERIC_ATOMIC64=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_a8_ramfs_ca9_a_defconfig b/arch/arm/configs/ambarella_a8_ramfs_ca9_a_defconfig
+new file mode 100644
+index 00000000..d759e609
+--- /dev/null
++++ b/arch/arm/configs/ambarella_a8_ramfs_ca9_a_defconfig
+@@ -0,0 +1,157 @@
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_RELAY=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE="/home/tjlee/git_repo/ambarella/a8/boss_sdk/output/ramfs_ca9_a/images/rootfs.cpio"
++CONFIG_INITRAMFS_COMPRESSION_GZIP=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++CONFIG_PROFILING=y
++CONFIG_JUMP_LABEL=y
++CONFIG_MODULES=y
++CONFIG_MODULE_FORCE_LOAD=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++# CONFIG_BLK_DEV_BSG is not set
++CONFIG_ARCH_AMBARELLA=y
++CONFIG_PLAT_AMBARELLA_A8_CORTEX=y
++CONFIG_AMBARELLA_RAW_BOOT=y
++CONFIG_AMBARELLA_PMUSERENR_EN=y
++CONFIG_AMBARELLA_PLL_PROC=y
++CONFIG_AMBARELLA_PPM_SIZE=0x60000000
++CONFIG_AMBARELLA_MEMORY_SIZE=0x06000000
++CONFIG_AMBARELLA_ZRELADDR=0x10008000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x10001000
++CONFIG_AMBARELLA_INITRD_PHYS=0x10800000
++CONFIG_AMBARELLA_TIMER_HZ=1000
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_MACH_HYACINTH_0=y
++CONFIG_ARM_THUMBEE=y
++# CONFIG_SWP_EMULATE is not set
++CONFIG_ARM_ERRATA_751472=y
++CONFIG_SMP=y
++CONFIG_SCHED_MC=y
++CONFIG_VMSPLIT_1G=y
++CONFIG_NR_CPUS=2
++CONFIG_PREEMPT=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++CONFIG_CLEANCACHE=y
++CONFIG_FRONTSWAP=y
++CONFIG_UACCESS_WITH_MEMCPY=y
++CONFIG_CMDLINE="console=ttyS2"
++CONFIG_VFP=y
++CONFIG_NEON=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_SUSPEND is not set
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_NET_IPIP=y
++CONFIG_IP_MROUTE=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++CONFIG_INET_IPCOMP=y
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_IPV6 is not set
++CONFIG_BRIDGE=y
++# CONFIG_WIRELESS is not set
++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++# CONFIG_BLK_DEV is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_VENDOR_AMBARELLA=y
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++# CONFIG_WLAN is not set
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_SERIO is not set
++CONFIG_VT_HW_CONSOLE_BINDING=y
++# CONFIG_LEGACY_PTYS is not set
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++CONFIG_HW_RANDOM=y
++CONFIG_GPIO_SYSFS=y
++# CONFIG_HWMON is not set
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_MEDIA_CAMERA_SUPPORT=y
++CONFIG_VIDEO_ADV_DEBUG=y
++CONFIG_V4L_PLATFORM_DRIVERS=y
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++CONFIG_V4L_TEST_DRIVERS=y
++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
++# CONFIG_HID is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RPROC_CA9_A=y
++CONFIG_RPMSG_AMBXC=y
++CONFIG_RPMSG_RSH=y
++CONFIG_RPMSG_VETH=y
++CONFIG_RPMSG_VGPIO=y
++CONFIG_FANOTIFY=y
++CONFIG_FSCACHE=y
++CONFIG_FSCACHE_STATS=y
++CONFIG_FSCACHE_HISTOGRAM=y
++CONFIG_CACHEFILES=y
++CONFIG_CACHEFILES_HISTOGRAM=y
++CONFIG_TMPFS=y
++CONFIG_CONFIGFS_FS=y
++# CONFIG_MISC_FILESYSTEMS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V4=y
++CONFIG_NFS_V4_1=y
++CONFIG_ROOT_NFS=y
++CONFIG_NLS=y
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=y
++CONFIG_NLS_UTF8=y
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_FS=y
++# CONFIG_RCU_CPU_STALL_VERBOSE is not set
++CONFIG_DYNAMIC_DEBUG=y
++CONFIG_DEBUG_USER=y
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_PCBC=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_LZO=y
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
+diff --git a/arch/arm/configs/ambarella_a8_ramfs_ca9_b_defconfig b/arch/arm/configs/ambarella_a8_ramfs_ca9_b_defconfig
+new file mode 100644
+index 00000000..0cfd413c
+--- /dev/null
++++ b/arch/arm/configs/ambarella_a8_ramfs_ca9_b_defconfig
+@@ -0,0 +1,147 @@
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_RELAY=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE="/home/tjlee/git_repo/ambarella/a8/boss_sdk/output/ramfs_ca9_b/images/rootfs.cpio"
++CONFIG_INITRAMFS_COMPRESSION_GZIP=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++CONFIG_PROFILING=y
++CONFIG_JUMP_LABEL=y
++CONFIG_MODULES=y
++CONFIG_MODULE_FORCE_LOAD=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++# CONFIG_BLK_DEV_BSG is not set
++CONFIG_ARCH_AMBARELLA=y
++CONFIG_PLAT_AMBARELLA_A8_CORTEX=y
++CONFIG_AMBARELLA_RAW_BOOT=y
++CONFIG_AMBARELLA_PMUSERENR_EN=y
++CONFIG_AMBARELLA_PLL_PROC=y
++CONFIG_AMBARELLA_PPM_SIZE=0x60000000
++CONFIG_AMBARELLA_MEMORY_SIZE=0x06000000
++CONFIG_AMBARELLA_ZRELADDR=0x10008000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x10001000
++CONFIG_AMBARELLA_INITRD_PHYS=0x10800000
++CONFIG_AMBARELLA_TIMER_HZ=1000
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_MACH_HYACINTH_1=y
++CONFIG_ARM_THUMBEE=y
++# CONFIG_SWP_EMULATE is not set
++CONFIG_ARM_ERRATA_751472=y
++CONFIG_SMP=y
++CONFIG_SCHED_MC=y
++CONFIG_VMSPLIT_1G=y
++CONFIG_NR_CPUS=2
++CONFIG_PREEMPT=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++CONFIG_CLEANCACHE=y
++CONFIG_FRONTSWAP=y
++CONFIG_UACCESS_WITH_MEMCPY=y
++CONFIG_CMDLINE="console=ttyS2"
++CONFIG_VFP=y
++CONFIG_NEON=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_SUSPEND is not set
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_NET_IPIP=y
++CONFIG_IP_MROUTE=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++CONFIG_INET_IPCOMP=y
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_IPV6 is not set
++CONFIG_DNS_RESOLVER=y
++# CONFIG_WIRELESS is not set
++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++# CONFIG_BLK_DEV is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++# CONFIG_WLAN is not set
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_SERIO is not set
++CONFIG_VT_HW_CONSOLE_BINDING=y
++# CONFIG_LEGACY_PTYS is not set
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++CONFIG_HW_RANDOM=y
++CONFIG_GPIO_SYSFS=y
++# CONFIG_HWMON is not set
++# CONFIG_HID is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RPROC_CA9_B=y
++CONFIG_RPCLNT_CA9_B=y
++CONFIG_RPMSG_VGPIO=y
++CONFIG_RPDEV_RSH=y
++CONFIG_RPDEV_VETH=y
++CONFIG_FANOTIFY=y
++CONFIG_FSCACHE=y
++CONFIG_FSCACHE_STATS=y
++CONFIG_FSCACHE_HISTOGRAM=y
++CONFIG_CACHEFILES=y
++CONFIG_CACHEFILES_HISTOGRAM=y
++CONFIG_TMPFS=y
++CONFIG_CONFIGFS_FS=y
++# CONFIG_MISC_FILESYSTEMS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++CONFIG_NLS=y
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=y
++CONFIG_NLS_UTF8=y
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_FS=y
++# CONFIG_RCU_CPU_STALL_VERBOSE is not set
++CONFIG_DYNAMIC_DEBUG=y
++CONFIG_DEBUG_USER=y
++CONFIG_KEYS=y
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_PCBC=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_LZO=y
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
+diff --git a/arch/arm/configs/ambarella_s2_arm11_defconfig b/arch/arm/configs/ambarella_s2_arm11_defconfig
+new file mode 100644
+index 00000000..7ba8aa83
+--- /dev/null
++++ b/arch/arm/configs/ambarella_s2_arm11_defconfig
+@@ -0,0 +1,2384 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.0 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_FHANDLE is not set
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++# CONFIG_IRQ_DOMAIN_DEBUG is not set
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++# CONFIG_TREE_PREEMPT_RCU is not set
++CONFIG_TINY_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++# CONFIG_RCU_STALL_COMMON is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
++# CONFIG_PLAT_AMBARELLA_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_MEM_START_LOW is not set
++# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++CONFIG_PLAT_AMBARELLA_S2=y
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++CONFIG_PLAT_AMBARELLA_S2_ARM11=y
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++CONFIG_AMBARELLA_SUPPORT_BAPI=y
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++
++#
++# Sys file system support
++#
++# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
++# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x10000000
++CONFIG_AMBARELLA_ZRELADDR=0xD0008000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0xD0200000
++CONFIG_AMBARELLA_INITRD_PHYS=0xD0A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++
++#
++# FIO Configuration
++#
++# CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=64
++CONFIG_AMBARELLA_EXT_GPIO_NUM=64
++
++#
++# Ambarella Board
++#
++CONFIG_MACH_AMBARELLA=y
++CONFIG_MACH_GINKGO=y
++
++#
++# Misc on Board Devices
++#
++
++#
++# Ambarella
++#
++CONFIG_AMBARELLA_VOUT=y
++
++#
++# Touch
++#
++# CONFIG_TOUCH_AMBARELLA_AK4183 is not set
++# CONFIG_TOUCH_AMBARELLA_CHACHA_MT4D is not set
++# CONFIG_TOUCH_AMBARELLA_TM1510 is not set
++# CONFIG_TOUCH_AMBARELLA_TM1726 is not set
++# CONFIG_TOUCH_AMBARELLA_TM1927 is not set
++# CONFIG_TOUCH_AMBARELLA_FT540 is not set
++# CONFIG_TOUCH_AMBARELLA_NT11001 is not set
++
++#
++# LCD
++#
++
++#
++# RTC
++#
++
++#
++# Audio Codec
++#
++# CONFIG_CODEC_AMBARELLA_WM8737 is not set
++# CONFIG_CODEC_AMBARELLA_WM8994 is not set
++# CONFIG_CODEC_AMBARELLA_ES8328 is not set
++CONFIG_CODEC_AMBARELLA_AK4642=y
++
++#
++# PMIC
++#
++# CONFIG_PMIC_AMBARELLA_WM831X is not set
++
++#
++# cpufreq-dev
++#
++# CONFIG_CPUFREQ_AMBARELLA_DEVICE is not set
++CONFIG_GPIO_PCA953X=y
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V6=y
++CONFIG_CPU_32v6=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_ABRT_EV6=y
++CONFIG_CPU_PABRT_V6=y
++CONFIG_CPU_CACHE_V6=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V6=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++CONFIG_CPU_USE_DOMAINS=y
++
++#
++# Processor Features
++#
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++# CONFIG_CACHE_L2X0 is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_326103 is not set
++# CONFIG_ARM_ERRATA_411920 is not set
++# CONFIG_ARM_ERRATA_364296 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_NEED_PER_CPU_KM=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++
++#
++# Boot options
++#
++# CONFIG_USE_OF is not set
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_HIBERNATION is not set
++CONFIG_PM_SLEEP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=y
++CONFIG_NET_KEY=y
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_NET_IPVTI is not set
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++CONFIG_INET_IPCOMP=y
++CONFIG_INET_XFRM_TUNNEL=y
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++CONFIG_INET_UDP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++CONFIG_STP=y
++CONFIG_BRIDGE=y
++CONFIG_BRIDGE_IGMP_SNOOPING=y
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=y
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIBTUSB is not set
++# CONFIG_BT_HCIBTSDIO is not set
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=y
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=y
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=y
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++# CONFIG_DMA_SHARED_BUFFER is not set
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++CONFIG_NETCONSOLE=y
++CONFIG_NETCONSOLE_DYNAMIC=y
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++# CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE is not set
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_IPHETH is not set
++CONFIG_WLAN=y
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_ATH_CARDS is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_RTLWIFI is not set
++# CONFIG_WL_TI is not set
++# CONFIG_ZD1211RW is not set
++# CONFIG_MWIFIEX is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA=m
++CONFIG_INPUT_AMBARELLA_IR=y
++CONFIG_INPUT_AMBARELLA_ADC=y
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++# CONFIG_I2C_MUX is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++# CONFIG_SPI_SLAVE_AMBARELLA is not set
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++CONFIG_GPIO_PCA953X_IRQ=y
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_CORE is not set
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=y
++CONFIG_FB_SYS_COPYAREA=y
++CONFIG_FB_SYS_IMAGEBLIT=y
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=y
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_GENERIC is not set
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++# CONFIG_LOGO is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_UA101 is not set
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_USB_6FIRE is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBEVK_BOARD=m
++CONFIG_AMBARELLA_DUMMY_BOARD=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++CONFIG_SND_SOC_AK4642_AMB=m
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=y
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=y
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=y
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=y
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=y
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=y
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=y
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=m
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEFAULT_PERSIST=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=m
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AMBARELLA=y
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++CONFIG_USB_OHCI_AMBARELLA=y
++# CONFIG_USB_OHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_F81232 is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_METRO is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_XSENS_MT is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_WISHBONE is not set
++# CONFIG_USB_SERIAL_ZTE is not set
++# CONFIG_USB_SERIAL_SSU100 is not set
++# CONFIG_USB_SERIAL_QT2 is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++# CONFIG_USB_PHY is not set
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++# CONFIG_USB_DUMMY_HCD is not set
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++CONFIG_MMC_TEST=m
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++# CONFIG_PWM is not set
++CONFIG_AMBARELLA_VIC=y
++CONFIG_AMBARELLA_GVIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=m
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_FANOTIFY=y
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++
++#
++# RCU Debugging
++#
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_LKDTM is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=y
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=y
++# CONFIG_CRYPTO_USER_API_HASH is not set
++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
++CONFIG_CRYPTO_HW=y
++CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++CONFIG_XZ_DEC_X86=y
++CONFIG_XZ_DEC_POWERPC=y
++CONFIG_XZ_DEC_IA64=y
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++CONFIG_XZ_DEC_SPARC=y
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_GENERIC_ATOMIC64=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_s2_cortex_defconfig b/arch/arm/configs/ambarella_s2_cortex_defconfig
+new file mode 100644
+index 00000000..1f57a220
+--- /dev/null
++++ b/arch/arm/configs/ambarella_s2_cortex_defconfig
+@@ -0,0 +1,2553 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.73 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++CONFIG_FHANDLE=y
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++CONFIG_IRQ_DOMAIN_DEBUG=y
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_ARCH_HAS_TICK_BROADCAST=y
++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++CONFIG_RCU_STALL_COMMON=y
++# CONFIG_RCU_USER_QS is not set
++CONFIG_RCU_FANOUT=32
++CONFIG_RCU_FANOUT_LEAF=16
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_RCU_FAST_NO_HZ is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++# CONFIG_RCU_NOCB_CPU is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++# CONFIG_CGROUP_FREEZER is not set
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++# CONFIG_CGROUP_CPUACCT is not set
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++# CONFIG_RT_GROUP_SCHED is not set
++# CONFIG_BLK_CGROUP is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_USE_GENERIC_SMP_HELPERS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_STOP_MACHINE=y
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
++CONFIG_MUTEX_SPIN_ON_OWNER=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++# CONFIG_PLAT_AMBARELLA_SUPPORT_VIC is not set
++CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
++CONFIG_PLAT_AMBARELLA_CORTEX=y
++CONFIG_PLAT_AMBARELLA_CORTEX_SMP=y
++# CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_PM is not set
++CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
++# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++CONFIG_PLAT_AMBARELLA_S2=y
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++CONFIG_PLAT_AMBARELLA_S2_CORTEX=y
++# CONFIG_PLAT_AMBARELLA_S2E is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++# CONFIG_PLAT_AMBARELLA_S3 is not set
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++# CONFIG_PLAT_AMBARELLA_LOWER_ARM_PLL is not set
++# CONFIG_AMBARELLA_SUPPORT_BAPI is not set
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
++
++#
++# Sys file system support
++#
++CONFIG_AMBARELLA_SYS_CACHE_CALL=y
++# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0x00208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
++CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++CONFIG_AMBARELLA_TIMER_HZ=1000
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=16
++CONFIG_AMBARELLA_EXT_GPIO_NUM=16
++CONFIG_GPIO_PCA953X=y
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++CONFIG_ARM_THUMBEE=y
++CONFIG_ARM_VIRT_EXT=y
++# CONFIG_SWP_EMULATE is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_KUSER_HELPERS=y
++CONFIG_OUTER_CACHE=y
++CONFIG_OUTER_CACHE_SYNC=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++CONFIG_CACHE_L2X0=y
++CONFIG_CACHE_PL310=y
++# CONFIG_CACHE_PL310_EARLY_BRESP is not set
++CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
++# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
++# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++# CONFIG_ARM_ERRATA_742230 is not set
++# CONFIG_ARM_ERRATA_742231 is not set
++CONFIG_PL310_ERRATA_588369=y
++# CONFIG_ARM_ERRATA_643719 is not set
++# CONFIG_ARM_ERRATA_720789 is not set
++CONFIG_PL310_ERRATA_727915=y
++# CONFIG_ARM_ERRATA_743622 is not set
++# CONFIG_ARM_ERRATA_751472 is not set
++CONFIG_PL310_ERRATA_753970=y
++CONFIG_ARM_ERRATA_754322=y
++# CONFIG_ARM_ERRATA_754327 is not set
++CONFIG_ARM_ERRATA_764369=y
++CONFIG_PL310_ERRATA_769419=y
++CONFIG_ARM_ERRATA_775420=y
++# CONFIG_ARM_ERRATA_798181 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_HAVE_SMP=y
++CONFIG_SMP=y
++CONFIG_SMP_ON_UP=y
++CONFIG_ARM_CPU_TOPOLOGY=y
++# CONFIG_SCHED_MC is not set
++# CONFIG_SCHED_SMT is not set
++CONFIG_HAVE_ARM_SCU=y
++# CONFIG_HAVE_ARM_ARCH_TIMER is not set
++CONFIG_HAVE_ARM_TWD=y
++# CONFIG_MCPM is not set
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++CONFIG_NR_CPUS=2
++CONFIG_HOTPLUG_CPU=y
++# CONFIG_ARM_PSCI is not set
++CONFIG_LOCAL_TIMERS=y
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=1000
++CONFIG_SCHED_HRTICK=y
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_CROSS_MEMORY_ATTACH=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_ARM_APPENDED_DTB is not set
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_HIBERNATION is not set
++CONFIG_PM_SLEEP=y
++CONFIG_PM_SLEEP_SMP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=y
++CONFIG_NET_KEY=y
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_NET_IPVTI is not set
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++CONFIG_INET_IPCOMP=y
++CONFIG_INET_XFRM_TUNNEL=y
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++CONFIG_INET_UDP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++CONFIG_STP=y
++CONFIG_BRIDGE=y
++CONFIG_BRIDGE_IGMP_SNOOPING=y
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=y
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_RPS=y
++CONFIG_RFS_ACCEL=y
++CONFIG_XPS=y
++# CONFIG_NETPRIO_CGROUP is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIBTUSB is not set
++# CONFIG_BT_HCIBTSDIO is not set
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=y
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=y
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=y
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++# CONFIG_DMA_SHARED_BUFFER is not set
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_OF_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=m
++CONFIG_OF_MTD=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++CONFIG_NETCONSOLE=y
++CONFIG_NETCONSOLE_DYNAMIC=y
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++# CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE is not set
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++# CONFIG_MICREL_PHY_KSZ80X1R is not set
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_IPHETH is not set
++CONFIG_WLAN=y
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_ATH_CARDS is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_RTLWIFI is not set
++# CONFIG_WL_TI is not set
++# CONFIG_ZD1211RW is not set
++# CONFIG_MWIFIEX is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=m
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA_IR=m
++CONFIG_INPUT_AMBARELLA_ADC=m
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++# CONFIG_I2C_MUX is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++CONFIG_SPI_SLAVE_AMBARELLA=m
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_DEBUG_PINCTRL is not set
++# CONFIG_PINCTRL_SINGLE is not set
++# CONFIG_PINCTRL_EXYNOS is not set
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_PINCTRL_AMB=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++CONFIG_GPIO_PCA953X_IRQ=y
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MPCORE_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=y
++CONFIG_FB_SYS_COPYAREA=y
++CONFIG_FB_SYS_IMAGEBLIT=y
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=y
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_PWM=m
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++# CONFIG_LOGO is not set
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_UA101 is not set
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_USB_6FIRE is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_SOC_DMAENGINE_PCM=y
++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBA_BOARD=m
++CONFIG_SND_AMBARELLA_CODEC=m
++CONFIG_SND_SOC_AK4642_AMB=m
++# CONFIG_SND_SOC_AK4951_AMB is not set
++# CONFIG_SND_SOC_AK4954_AMB is not set
++# CONFIG_SND_SOC_ES8388 is not set
++# CONFIG_SND_SOC_WM8974_AMB is not set
++# CONFIG_SND_SOC_WM8940_AMB is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=y
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=y
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=y
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=y
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=y
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=y
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=y
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=m
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEFAULT_PERSIST=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=m
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AMBARELLA=m
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++CONFIG_USB_OHCI_AMBARELLA=y
++# CONFIG_USB_OHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_U1960 is not set
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_F81232 is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_METRO is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_XSENS_MT is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_WISHBONE is not set
++# CONFIG_USB_SERIAL_ZTE is not set
++# CONFIG_USB_SERIAL_SSU100 is not set
++# CONFIG_USB_SERIAL_QT2 is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_EHSET_TEST_FIXTURE is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++CONFIG_USB_AMBARELLA_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++# CONFIG_SAMSUNG_USBPHY is not set
++# CONFIG_SAMSUNG_USB2PHY is not set
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG is not set
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++# CONFIG_USB_DUMMY_HCD is not set
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++CONFIG_MMC_TEST=m
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++CONFIG_CLKSRC_OF=y
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++# CONFIG_RPROC_SUPPORT is not set
++# CONFIG_RPCLNT_SUPPORT is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++CONFIG_PWM=y
++CONFIG_PWM_AMBARELLA=m
++CONFIG_IRQCHIP=y
++CONFIG_ARM_GIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_FANOTIFY=y
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_READABLE_ASM is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_LOCKUP_DETECTOR is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++# CONFIG_DETECT_HUNG_TASK is not set
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++# CONFIG_DEBUG_KMEMLEAK is not set
++CONFIG_DEBUG_PREEMPT=y
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_ATOMIC_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_TEST_LIST_SORT is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++
++#
++# RCU Debugging
++#
++# CONFIG_PROVE_RCU_DELAY is not set
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_RCU_CPU_STALL_TIMEOUT=60
++CONFIG_RCU_CPU_STALL_VERBOSE=y
++# CONFIG_RCU_CPU_STALL_INFO is not set
++# CONFIG_RCU_TRACE is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_DEBUG_PER_CPU_MAPS is not set
++# CONFIG_LKDTM is not set
++# CONFIG_NOTIFIER_ERROR_INJECTION is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_RBTREE_TEST is not set
++# CONFIG_INTERVAL_TREE_TEST is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_LL is not set
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_PCRYPT is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=y
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=y
++# CONFIG_CRYPTO_USER_API_HASH is not set
++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
++CONFIG_CRYPTO_HW=y
++CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++CONFIG_XZ_DEC_X86=y
++CONFIG_XZ_DEC_POWERPC=y
++CONFIG_XZ_DEC_IA64=y
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++CONFIG_XZ_DEC_SPARC=y
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_CPU_RMAP=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_s2e_defconfig b/arch/arm/configs/ambarella_s2e_defconfig
+new file mode 100644
+index 00000000..791f3676
+--- /dev/null
++++ b/arch/arm/configs/ambarella_s2e_defconfig
+@@ -0,0 +1,2744 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.73 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++CONFIG_FHANDLE=y
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++CONFIG_IRQ_DOMAIN_DEBUG=y
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_ARCH_HAS_TICK_BROADCAST=y
++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++CONFIG_RCU_STALL_COMMON=y
++# CONFIG_RCU_USER_QS is not set
++CONFIG_RCU_FANOUT=32
++CONFIG_RCU_FANOUT_LEAF=16
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_RCU_FAST_NO_HZ is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++# CONFIG_RCU_NOCB_CPU is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++# CONFIG_CGROUP_FREEZER is not set
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++# CONFIG_CGROUP_CPUACCT is not set
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++# CONFIG_RT_GROUP_SCHED is not set
++# CONFIG_BLK_CGROUP is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_USE_GENERIC_SMP_HELPERS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_STOP_MACHINE=y
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
++CONFIG_MUTEX_SPIN_ON_OWNER=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
++CONFIG_PLAT_AMBARELLA_CORTEX=y
++CONFIG_PLAT_AMBARELLA_CORTEX_SMP=y
++CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
++CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
++# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++# CONFIG_PLAT_AMBARELLA_S2 is not set
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++CONFIG_PLAT_AMBARELLA_S2E=y
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++# CONFIG_PLAT_AMBARELLA_S3 is not set
++# CONFIG_PLAT_AMBARELLA_S3L is not set
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_CALC_PLL is not set
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
++
++#
++# Sys file system support
++#
++CONFIG_AMBARELLA_SYS_CACHE_CALL=y
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0x00208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
++CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=16
++CONFIG_AMBARELLA_EXT_GPIO_NUM=16
++# CONFIG_AMBARELLA_SREF_FIFO_EXEC is not set
++CONFIG_GPIO_PCA953X=y
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++CONFIG_ARM_THUMBEE=y
++CONFIG_ARM_VIRT_EXT=y
++# CONFIG_SWP_EMULATE is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_KUSER_HELPERS=y
++CONFIG_OUTER_CACHE=y
++CONFIG_OUTER_CACHE_SYNC=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++CONFIG_CACHE_L2X0=y
++CONFIG_CACHE_PL310=y
++# CONFIG_CACHE_PL310_EARLY_BRESP is not set
++CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
++# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
++# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++# CONFIG_ARM_ERRATA_742230 is not set
++# CONFIG_ARM_ERRATA_742231 is not set
++CONFIG_PL310_ERRATA_588369=y
++# CONFIG_ARM_ERRATA_643719 is not set
++# CONFIG_ARM_ERRATA_720789 is not set
++CONFIG_PL310_ERRATA_727915=y
++# CONFIG_ARM_ERRATA_743622 is not set
++# CONFIG_ARM_ERRATA_751472 is not set
++# CONFIG_PL310_ERRATA_753970 is not set
++CONFIG_ARM_ERRATA_754322=y
++# CONFIG_ARM_ERRATA_754327 is not set
++CONFIG_ARM_ERRATA_764369=y
++# CONFIG_PL310_ERRATA_769419 is not set
++CONFIG_ARM_ERRATA_775420=y
++# CONFIG_ARM_ERRATA_798181 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_HAVE_SMP=y
++CONFIG_SMP=y
++CONFIG_SMP_ON_UP=y
++CONFIG_ARM_CPU_TOPOLOGY=y
++# CONFIG_SCHED_MC is not set
++# CONFIG_SCHED_SMT is not set
++CONFIG_HAVE_ARM_SCU=y
++# CONFIG_HAVE_ARM_ARCH_TIMER is not set
++# CONFIG_MCPM is not set
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++CONFIG_NR_CPUS=2
++CONFIG_HOTPLUG_CPU=y
++# CONFIG_ARM_PSCI is not set
++CONFIG_LOCAL_TIMERS=y
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_ARM_APPENDED_DTB is not set
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
++
++#
++# ARM CPU frequency scaling drivers
++#
++# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
++# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
++# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
++CONFIG_ARM_AMBARALLA_CPUFREQ=y
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_HIBERNATION is not set
++CONFIG_PM_SLEEP=y
++CONFIG_PM_SLEEP_SMP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_RPS=y
++CONFIG_RFS_ACCEL=y
++CONFIG_XPS=y
++# CONFIG_NETPRIO_CGROUP is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=m
++CONFIG_BT_HCIBTSDIO=m
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++# CONFIG_BT_HCIUART_ATH3K is not set
++CONFIG_BT_HCIUART_LL=y
++# CONFIG_BT_HCIUART_3WIRE is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_BT_ATH3K is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=m
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=m
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH=""
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++CONFIG_DMA_SHARED_BUFFER=y
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_OF_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
++CONFIG_MTD_BLOCK_AMBRO=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_SPINAND_AMBARELLA is not set
++# CONFIG_MTD_SPINAND_ONDIEECC is not set
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=m
++CONFIG_OF_MTD=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++CONFIG_MICREL_PHY_KSZ80X1R=m
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_IPHETH is not set
++CONFIG_WLAN=y
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_MAC80211_HWSIM is not set
++CONFIG_ATH_CARDS=m
++# CONFIG_ATH_DEBUG is not set
++# CONFIG_ATH9K is not set
++# CONFIG_ATH9K_HTC is not set
++# CONFIG_CARL9170 is not set
++CONFIG_ATH6KL=m
++CONFIG_ATH6KL_SDIO=m
++# CONFIG_ATH6KL_USB is not set
++# CONFIG_ATH6KL_DEBUG is not set
++# CONFIG_AR5523 is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_RTLWIFI is not set
++# CONFIG_WL_TI is not set
++# CONFIG_ZD1211RW is not set
++CONFIG_MWIFIEX=m
++CONFIG_MWIFIEX_SDIO=m
++# CONFIG_MWIFIEX_USB is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=m
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=m
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA_IR=m
++CONFIG_INPUT_AMBARELLA_ADC=m
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++# CONFIG_I2C_MUX is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=m
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++CONFIG_SPI_SLAVE_AMBARELLA=m
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_DEBUG_PINCTRL is not set
++# CONFIG_PINCTRL_SINGLE is not set
++# CONFIG_PINCTRL_EXYNOS is not set
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_PINCTRL_AMB=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++CONFIG_GPIO_PCA953X_IRQ=y
++CONFIG_GPIO_PCF857X=y
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++CONFIG_MEDIA_SUPPORT=m
++
++#
++# Multimedia core support
++#
++CONFIG_MEDIA_CAMERA_SUPPORT=y
++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
++# CONFIG_MEDIA_RADIO_SUPPORT is not set
++# CONFIG_MEDIA_RC_SUPPORT is not set
++CONFIG_MEDIA_CONTROLLER=y
++CONFIG_VIDEO_DEV=m
++# CONFIG_VIDEO_V4L2_SUBDEV_API is not set
++CONFIG_VIDEO_V4L2=m
++# CONFIG_VIDEO_ADV_DEBUG is not set
++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
++CONFIG_VIDEOBUF2_CORE=m
++CONFIG_VIDEOBUF2_MEMOPS=m
++CONFIG_VIDEOBUF2_VMALLOC=m
++# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
++# CONFIG_TTPCI_EEPROM is not set
++
++#
++# Media drivers
++#
++CONFIG_MEDIA_USB_SUPPORT=y
++
++#
++# Webcam devices
++#
++CONFIG_USB_VIDEO_CLASS=m
++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
++CONFIG_USB_GSPCA=m
++# CONFIG_USB_M5602 is not set
++# CONFIG_USB_STV06XX is not set
++# CONFIG_USB_GL860 is not set
++# CONFIG_USB_GSPCA_BENQ is not set
++# CONFIG_USB_GSPCA_CONEX is not set
++# CONFIG_USB_GSPCA_CPIA1 is not set
++# CONFIG_USB_GSPCA_ETOMS is not set
++# CONFIG_USB_GSPCA_FINEPIX is not set
++# CONFIG_USB_GSPCA_JEILINJ is not set
++# CONFIG_USB_GSPCA_JL2005BCD is not set
++# CONFIG_USB_GSPCA_KINECT is not set
++# CONFIG_USB_GSPCA_KONICA is not set
++# CONFIG_USB_GSPCA_MARS is not set
++# CONFIG_USB_GSPCA_MR97310A is not set
++# CONFIG_USB_GSPCA_NW80X is not set
++# CONFIG_USB_GSPCA_OV519 is not set
++# CONFIG_USB_GSPCA_OV534 is not set
++# CONFIG_USB_GSPCA_OV534_9 is not set
++# CONFIG_USB_GSPCA_PAC207 is not set
++# CONFIG_USB_GSPCA_PAC7302 is not set
++# CONFIG_USB_GSPCA_PAC7311 is not set
++# CONFIG_USB_GSPCA_SE401 is not set
++# CONFIG_USB_GSPCA_SN9C2028 is not set
++# CONFIG_USB_GSPCA_SN9C20X is not set
++# CONFIG_USB_GSPCA_SONIXB is not set
++# CONFIG_USB_GSPCA_SONIXJ is not set
++# CONFIG_USB_GSPCA_SPCA500 is not set
++# CONFIG_USB_GSPCA_SPCA501 is not set
++# CONFIG_USB_GSPCA_SPCA505 is not set
++# CONFIG_USB_GSPCA_SPCA506 is not set
++# CONFIG_USB_GSPCA_SPCA508 is not set
++# CONFIG_USB_GSPCA_SPCA561 is not set
++# CONFIG_USB_GSPCA_SPCA1528 is not set
++# CONFIG_USB_GSPCA_SQ905 is not set
++# CONFIG_USB_GSPCA_SQ905C is not set
++# CONFIG_USB_GSPCA_SQ930X is not set
++# CONFIG_USB_GSPCA_STK014 is not set
++# CONFIG_USB_GSPCA_STV0680 is not set
++# CONFIG_USB_GSPCA_SUNPLUS is not set
++# CONFIG_USB_GSPCA_T613 is not set
++# CONFIG_USB_GSPCA_TOPRO is not set
++# CONFIG_USB_GSPCA_TV8532 is not set
++# CONFIG_USB_GSPCA_VC032X is not set
++# CONFIG_USB_GSPCA_VICAM is not set
++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
++# CONFIG_USB_GSPCA_ZC3XX is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_VIDEO_CPIA2 is not set
++# CONFIG_USB_ZR364XX is not set
++# CONFIG_USB_STKWEBCAM is not set
++# CONFIG_USB_S2255 is not set
++# CONFIG_USB_SN9C102 is not set
++
++#
++# Webcam, TV (analog/digital) USB devices
++#
++# CONFIG_VIDEO_EM28XX is not set
++# CONFIG_V4L_PLATFORM_DRIVERS is not set
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
++# CONFIG_VIDEO_SH_VEU is not set
++# CONFIG_V4L_TEST_DRIVERS is not set
++
++#
++# Supported MMC/SDIO adapters
++#
++# CONFIG_CYPRESS_FIRMWARE is not set
++
++#
++# Media ancillary drivers (tuners, sensors, i2c, frontends)
++#
++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
++
++#
++# Audio decoders, processors and mixers
++#
++
++#
++# RDS decoders
++#
++
++#
++# Video decoders
++#
++
++#
++# Video and audio decoders
++#
++
++#
++# Video encoders
++#
++
++#
++# Camera sensor devices
++#
++
++#
++# Flash devices
++#
++
++#
++# Video improvement chips
++#
++
++#
++# Miscelaneous helper chips
++#
++
++#
++# Sensors used on soc_camera driver
++#
++
++#
++# Tools to develop new frontends
++#
++# CONFIG_DVB_DUMMY_FE is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=m
++CONFIG_FB_SYS_COPYAREA=m
++CONFIG_FB_SYS_IMAGEBLIT=m
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=m
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=m
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_PWM=m
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_FONT_AUTOSELECT=y
++# CONFIG_LOGO is not set
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_UA101 is not set
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_USB_6FIRE is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_SOC_DMAENGINE_PCM=y
++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBA_BOARD=m
++CONFIG_SND_AMBARELLA_CODEC=m
++CONFIG_SND_SOC_AK4642_AMB=m
++CONFIG_SND_SOC_AK4951_AMB=m
++# CONFIG_SND_SOC_AK4954_AMB is not set
++# CONFIG_SND_SOC_AK7719_DSP is not set
++# CONFIG_SND_SOC_AK7755 is not set
++# CONFIG_SND_SOC_TLV320ADC3xxx is not set
++# CONFIG_SND_SOC_ES8388 is not set
++# CONFIG_SND_SOC_WM8974_AMB is not set
++# CONFIG_SND_SOC_WM8940_AMB is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=m
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=m
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=m
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=m
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=m
++CONFIG_HID_CHERRY=m
++CONFIG_HID_CHICONY=m
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=m
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=m
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=m
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=m
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=m
++CONFIG_HID_MONTEREY=m
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEFAULT_PERSIST is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=m
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AMBARELLA=m
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++CONFIG_USB_OHCI_AMBARELLA=y
++# CONFIG_USB_OHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_U1960 is not set
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_F81232 is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_METRO is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_XSENS_MT is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_WISHBONE is not set
++# CONFIG_USB_SERIAL_ZTE is not set
++# CONFIG_USB_SERIAL_SSU100 is not set
++# CONFIG_USB_SERIAL_QT2 is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_EHSET_TEST_FIXTURE is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++CONFIG_USB_AMBARELLA_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++# CONFIG_SAMSUNG_USBPHY is not set
++# CONFIG_SAMSUNG_USB2PHY is not set
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG is not set
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++CONFIG_USB_G_MULTI=m
++CONFIG_USB_G_MULTI_RNDIS=y
++# CONFIG_USB_G_MULTI_CDC is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++# CONFIG_USB_G_WEBCAM is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_AMBARELLA_EMMC_BOOT is not set
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_ISL12022 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++# CONFIG_RPROC_SUPPORT is not set
++# CONFIG_RPCLNT_SUPPORT is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++CONFIG_PWM=y
++CONFIG_PWM_AMBARELLA=m
++CONFIG_IRQCHIP=y
++CONFIG_AMBARELLA_VIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=m
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=m
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=m
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++# CONFIG_DNOTIFY is not set
++CONFIG_INOTIFY_USER=y
++# CONFIG_FANOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_SQUASHFS=y
++# CONFIG_SQUASHFS_XATTR is not set
++CONFIG_SQUASHFS_ZLIB=y
++CONFIG_SQUASHFS_LZO=y
++CONFIG_SQUASHFS_XZ=y
++CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
++# CONFIG_SQUASHFS_EMBEDDED is not set
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_READABLE_ASM is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_LOCKUP_DETECTOR is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++# CONFIG_DETECT_HUNG_TASK is not set
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++# CONFIG_DEBUG_KMEMLEAK is not set
++CONFIG_DEBUG_PREEMPT=y
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_ATOMIC_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_TEST_LIST_SORT is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++
++#
++# RCU Debugging
++#
++# CONFIG_PROVE_RCU_DELAY is not set
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_RCU_CPU_STALL_TIMEOUT=21
++CONFIG_RCU_CPU_STALL_VERBOSE=y
++# CONFIG_RCU_CPU_STALL_INFO is not set
++# CONFIG_RCU_TRACE is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_DEBUG_PER_CPU_MAPS is not set
++# CONFIG_LKDTM is not set
++# CONFIG_NOTIFIER_ERROR_INJECTION is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_RBTREE_TEST is not set
++# CONFIG_INTERVAL_TREE_TEST is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_LL is not set
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_PCRYPT is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=m
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_USER_API=y
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_HW=y
++CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++# CONFIG_XZ_DEC_X86 is not set
++# CONFIG_XZ_DEC_POWERPC is not set
++# CONFIG_XZ_DEC_IA64 is not set
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++# CONFIG_XZ_DEC_SPARC is not set
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_CPU_RMAP=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_s2l_defconfig b/arch/arm/configs/ambarella_s2l_defconfig
+new file mode 100644
+index 00000000..db360841
+--- /dev/null
++++ b/arch/arm/configs/ambarella_s2l_defconfig
+@@ -0,0 +1,2519 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.104 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++CONFIG_FHANDLE=y
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++CONFIG_IRQ_DOMAIN_DEBUG=y
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++# CONFIG_TREE_PREEMPT_RCU is not set
++CONFIG_TINY_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++# CONFIG_RCU_STALL_COMMON is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++# CONFIG_CGROUP_FREEZER is not set
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++# CONFIG_CGROUP_CPUACCT is not set
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++# CONFIG_RT_GROUP_SCHED is not set
++# CONFIG_BLK_CGROUP is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
++CONFIG_PLAT_AMBARELLA_CORTEX=y
++# CONFIG_PLAT_AMBARELLA_CORTEX_SMP is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
++CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
++CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++# CONFIG_PLAT_AMBARELLA_S2 is not set
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2E is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++CONFIG_PLAT_AMBARELLA_S2L=y
++# CONFIG_PLAT_AMBARELLA_S3 is not set
++# CONFIG_PLAT_AMBARELLA_S3L is not set
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_CALC_PLL is not set
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
++
++#
++# Sys file system support
++#
++# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0x00208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
++CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=16
++CONFIG_AMBARELLA_EXT_GPIO_NUM=16
++CONFIG_AMBARELLA_SREF_FIFO_EXEC=y
++CONFIG_GPIO_PCA953X=y
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++CONFIG_ARM_THUMBEE=y
++CONFIG_ARM_VIRT_EXT=y
++# CONFIG_SWP_EMULATE is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_KUSER_HELPERS=y
++CONFIG_OUTER_CACHE=y
++CONFIG_OUTER_CACHE_SYNC=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++CONFIG_CACHE_L2X0=y
++CONFIG_CACHE_PL310=y
++# CONFIG_CACHE_PL310_EARLY_BRESP is not set
++CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
++# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
++# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++CONFIG_PL310_ERRATA_588369=y
++# CONFIG_ARM_ERRATA_720789 is not set
++CONFIG_PL310_ERRATA_727915=y
++# CONFIG_ARM_ERRATA_743622 is not set
++# CONFIG_ARM_ERRATA_751472 is not set
++# CONFIG_PL310_ERRATA_753970 is not set
++# CONFIG_ARM_ERRATA_754322 is not set
++# CONFIG_PL310_ERRATA_769419 is not set
++# CONFIG_ARM_ERRATA_775420 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_HAVE_ARM_ARCH_TIMER is not set
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++# CONFIG_ARM_PSCI is not set
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_NEED_PER_CPU_KM=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_ARM_APPENDED_DTB is not set
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
++
++#
++# ARM CPU frequency scaling drivers
++#
++# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
++# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
++# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
++CONFIG_ARM_AMBARALLA_CPUFREQ=y
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_HIBERNATE_CALLBACKS=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION=""
++CONFIG_PM_SLEEP=y
++# CONFIG_PM_AUTOSLEEP is not set
++CONFIG_PM_WAKELOCKS=y
++CONFIG_PM_WAKELOCKS_LIMIT=100
++CONFIG_PM_WAKELOCKS_GC=y
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++# CONFIG_PM_TEST_SUSPEND is not set
++CONFIG_PM_SLEEP_DEBUG=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_WLAN_UPDATE_SEQ is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++# CONFIG_NETPRIO_CGROUP is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=m
++CONFIG_BT_HCIBTSDIO=m
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++# CONFIG_BT_HCIUART_ATH3K is not set
++CONFIG_BT_HCIUART_LL=y
++# CONFIG_BT_HCIUART_3WIRE is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_BT_ATH3K is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=m
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=m
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH=""
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++# CONFIG_DMA_SHARED_BUFFER is not set
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_OF_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
++CONFIG_MTD_BLOCK_AMBRO=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_SPINAND_AMBARELLA is not set
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=m
++CONFIG_OF_MTD=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++CONFIG_MICREL_PHY_KSZ80X1R=m
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_IPHETH is not set
++CONFIG_WLAN=y
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_MAC80211_HWSIM is not set
++CONFIG_ATH_CARDS=m
++# CONFIG_ATH_DEBUG is not set
++# CONFIG_ATH9K is not set
++# CONFIG_ATH9K_HTC is not set
++# CONFIG_CARL9170 is not set
++CONFIG_ATH6KL=m
++CONFIG_ATH6KL_SDIO=m
++# CONFIG_ATH6KL_USB is not set
++# CONFIG_ATH6KL_DEBUG is not set
++# CONFIG_AR5523 is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_RTLWIFI is not set
++# CONFIG_WL_TI is not set
++# CONFIG_ZD1211RW is not set
++CONFIG_MWIFIEX=m
++CONFIG_MWIFIEX_SDIO=m
++# CONFIG_MWIFIEX_USB is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=m
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=m
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA_IR=m
++CONFIG_INPUT_AMBARELLA_ADC=m
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++# CONFIG_I2C_MUX is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=m
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++CONFIG_SPI_SLAVE_AMBARELLA=m
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_PINCTRL_SINGLE is not set
++# CONFIG_PINCTRL_EXYNOS is not set
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_PINCTRL_AMB=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++CONFIG_GPIO_PCA953X_IRQ=y
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=m
++CONFIG_FB_SYS_COPYAREA=m
++CONFIG_FB_SYS_IMAGEBLIT=m
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=m
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=m
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_PWM=m
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_FONT_AUTOSELECT=y
++# CONFIG_LOGO is not set
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_UA101 is not set
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_USB_6FIRE is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_SOC_DMAENGINE_PCM=y
++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBA_BOARD=m
++CONFIG_SND_AMBARELLA_CODEC=m
++CONFIG_SND_SOC_AK4642_AMB=m
++CONFIG_SND_SOC_AK4951_AMB=m
++CONFIG_SND_SOC_AK4954_AMB=m
++# CONFIG_SND_SOC_AK7719_DSP is not set
++# CONFIG_SND_SOC_AK7755 is not set
++# CONFIG_SND_SOC_TLV320ADC3xxx is not set
++CONFIG_SND_SOC_ES8388=m
++# CONFIG_SND_SOC_ES8374 is not set
++# CONFIG_SND_SOC_WM8974_AMB is not set
++# CONFIG_SND_SOC_WM8940_AMB is not set
++# CONFIG_SND_SOC_ZL380TW is not set
++# CONFIG_SND_SOC_RT5670 is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=m
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=m
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=m
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=m
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=m
++CONFIG_HID_CHERRY=m
++CONFIG_HID_CHICONY=m
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=m
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=m
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=m
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=m
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=m
++CONFIG_HID_MONTEREY=m
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEFAULT_PERSIST is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=m
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AMBARELLA=m
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++CONFIG_USB_OHCI_AMBARELLA=y
++# CONFIG_USB_OHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_U1960 is not set
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_F81232 is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_METRO is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_XSENS_MT is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_WISHBONE is not set
++# CONFIG_USB_SERIAL_ZTE is not set
++# CONFIG_USB_SERIAL_SSU100 is not set
++# CONFIG_USB_SERIAL_QT2 is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_EHSET_TEST_FIXTURE is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++CONFIG_USB_AMBARELLA_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++# CONFIG_SAMSUNG_USBPHY is not set
++# CONFIG_SAMSUNG_USB2PHY is not set
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_AMB_STREAM is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++CONFIG_USB_G_MULTI=m
++CONFIG_USB_G_MULTI_RNDIS=y
++# CONFIG_USB_G_MULTI_CDC is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_AMBARELLA_EMMC_BOOT is not set
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++# CONFIG_RPROC_SUPPORT is not set
++# CONFIG_RPCLNT_SUPPORT is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++CONFIG_PWM=y
++CONFIG_PWM_AMBARELLA=m
++CONFIG_IRQCHIP=y
++CONFIG_AMBARELLA_VIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++# CONFIG_DNOTIFY is not set
++CONFIG_INOTIFY_USER=y
++# CONFIG_FANOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=m
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_SQUASHFS=y
++# CONFIG_SQUASHFS_XATTR is not set
++CONFIG_SQUASHFS_ZLIB=y
++CONFIG_SQUASHFS_LZO=y
++CONFIG_SQUASHFS_XZ=y
++CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
++# CONFIG_SQUASHFS_EMBEDDED is not set
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++
++#
++# RCU Debugging
++#
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_LKDTM is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_USER_API=y
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_HW=y
++CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++# CONFIG_XZ_DEC_X86 is not set
++# CONFIG_XZ_DEC_POWERPC is not set
++# CONFIG_XZ_DEC_IA64 is not set
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++# CONFIG_XZ_DEC_SPARC is not set
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_s3_defconfig b/arch/arm/configs/ambarella_s3_defconfig
+new file mode 100644
+index 00000000..c1b22151
+--- /dev/null
++++ b/arch/arm/configs/ambarella_s3_defconfig
+@@ -0,0 +1,2554 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.0 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++CONFIG_FHANDLE=y
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++CONFIG_IRQ_DOMAIN_DEBUG=y
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_ARCH_HAS_TICK_BROADCAST=y
++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++CONFIG_RCU_STALL_COMMON=y
++# CONFIG_RCU_USER_QS is not set
++CONFIG_RCU_FANOUT=32
++CONFIG_RCU_FANOUT_LEAF=16
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_RCU_FAST_NO_HZ is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++# CONFIG_RCU_NOCB_CPU is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++# CONFIG_CGROUP_FREEZER is not set
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++# CONFIG_CGROUP_CPUACCT is not set
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++# CONFIG_RT_GROUP_SCHED is not set
++# CONFIG_BLK_CGROUP is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_USE_GENERIC_SMP_HELPERS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_STOP_MACHINE=y
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_MUTEX_SPIN_ON_OWNER=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
++CONFIG_PLAT_AMBARELLA_CORTEX=y
++CONFIG_PLAT_AMBARELLA_CORTEX_SMP=y
++CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
++CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
++CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++# CONFIG_PLAT_AMBARELLA_S2 is not set
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2E is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++CONFIG_PLAT_AMBARELLA_S3=y
++
++#
++# Generic Platform Configuration
++#
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++CONFIG_AMBARELLA_SUPPORT_BAPI=y
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA is not set
++
++#
++# Sys file system support
++#
++CONFIG_AMBARELLA_SYS_CACHE_CALL=y
++# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0x00208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
++CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=16
++CONFIG_AMBARELLA_EXT_GPIO_NUM=16
++CONFIG_GPIO_PCA953X=y
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++CONFIG_ARM_THUMBEE=y
++CONFIG_ARM_VIRT_EXT=y
++# CONFIG_SWP_EMULATE is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_OUTER_CACHE=y
++CONFIG_OUTER_CACHE_SYNC=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++CONFIG_CACHE_L2X0=y
++CONFIG_CACHE_PL310=y
++# CONFIG_CACHE_PL310_EARLY_BRESP is not set
++CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
++# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
++# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++# CONFIG_ARM_ERRATA_742230 is not set
++# CONFIG_ARM_ERRATA_742231 is not set
++CONFIG_PL310_ERRATA_588369=y
++# CONFIG_ARM_ERRATA_643719 is not set
++# CONFIG_ARM_ERRATA_720789 is not set
++CONFIG_PL310_ERRATA_727915=y
++# CONFIG_ARM_ERRATA_743622 is not set
++# CONFIG_ARM_ERRATA_751472 is not set
++# CONFIG_PL310_ERRATA_753970 is not set
++# CONFIG_ARM_ERRATA_754322 is not set
++# CONFIG_ARM_ERRATA_754327 is not set
++CONFIG_ARM_ERRATA_764369=y
++# CONFIG_PL310_ERRATA_769419 is not set
++# CONFIG_ARM_ERRATA_775420 is not set
++# CONFIG_ARM_ERRATA_798181 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_HAVE_SMP=y
++CONFIG_SMP=y
++CONFIG_SMP_ON_UP=y
++CONFIG_ARM_CPU_TOPOLOGY=y
++# CONFIG_SCHED_MC is not set
++# CONFIG_SCHED_SMT is not set
++CONFIG_HAVE_ARM_SCU=y
++# CONFIG_HAVE_ARM_ARCH_TIMER is not set
++# CONFIG_MCPM is not set
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++CONFIG_NR_CPUS=2
++CONFIG_HOTPLUG_CPU=y
++# CONFIG_ARM_PSCI is not set
++CONFIG_LOCAL_TIMERS=y
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_ARM_APPENDED_DTB is not set
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_HIBERNATION is not set
++CONFIG_PM_SLEEP=y
++CONFIG_PM_SLEEP_SMP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_RPS=y
++CONFIG_RFS_ACCEL=y
++CONFIG_XPS=y
++# CONFIG_NETPRIO_CGROUP is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=m
++CONFIG_BT_HCIBTSDIO=m
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++# CONFIG_BT_HCIUART_ATH3K is not set
++CONFIG_BT_HCIUART_LL=y
++# CONFIG_BT_HCIUART_3WIRE is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_BT_ATH3K is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=m
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=m
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH=""
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++# CONFIG_DMA_SHARED_BUFFER is not set
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_OF_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
++CONFIG_MTD_BLOCK_AMBRO=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=m
++CONFIG_OF_MTD=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++CONFIG_MICREL_PHY_KSZ80X1R=m
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_IPHETH is not set
++CONFIG_WLAN=y
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_MAC80211_HWSIM is not set
++CONFIG_ATH_CARDS=m
++# CONFIG_ATH_DEBUG is not set
++# CONFIG_ATH9K is not set
++# CONFIG_ATH9K_HTC is not set
++# CONFIG_CARL9170 is not set
++CONFIG_ATH6KL=m
++CONFIG_ATH6KL_SDIO=m
++# CONFIG_ATH6KL_USB is not set
++# CONFIG_ATH6KL_DEBUG is not set
++# CONFIG_AR5523 is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_RTLWIFI is not set
++# CONFIG_WL_TI is not set
++# CONFIG_ZD1211RW is not set
++CONFIG_MWIFIEX=m
++CONFIG_MWIFIEX_SDIO=m
++# CONFIG_MWIFIEX_USB is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=m
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=m
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA_IR=m
++CONFIG_INPUT_AMBARELLA_ADC=m
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++# CONFIG_I2C_MUX is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=m
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++CONFIG_SPI_SLAVE_AMBARELLA=m
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_DEBUG_PINCTRL is not set
++# CONFIG_PINCTRL_SINGLE is not set
++# CONFIG_PINCTRL_EXYNOS is not set
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_PINCTRL_AMB=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++CONFIG_GPIO_PCA953X_IRQ=y
++CONFIG_GPIO_PCF857X=y
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=m
++CONFIG_FB_SYS_COPYAREA=m
++CONFIG_FB_SYS_IMAGEBLIT=m
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=m
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=m
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_PWM=m
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_FONT_AUTOSELECT=y
++# CONFIG_LOGO is not set
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_UA101 is not set
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_USB_6FIRE is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_SOC_DMAENGINE_PCM=y
++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBA_BOARD=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++CONFIG_SND_AMBARELLA_CODEC=m
++CONFIG_SND_SOC_AK4951_AMB=m
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=m
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=m
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=m
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=m
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=m
++CONFIG_HID_CHERRY=m
++CONFIG_HID_CHICONY=m
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=m
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=m
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=m
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=m
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=m
++CONFIG_HID_MONTEREY=m
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEFAULT_PERSIST is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=m
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AMBARELLA=y
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++CONFIG_USB_OHCI_AMBARELLA=y
++# CONFIG_USB_OHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_U1960 is not set
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_F81232 is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_METRO is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_XSENS_MT is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_WISHBONE is not set
++# CONFIG_USB_SERIAL_ZTE is not set
++# CONFIG_USB_SERIAL_SSU100 is not set
++# CONFIG_USB_SERIAL_QT2 is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++CONFIG_USB_AMBARELLA_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++# CONFIG_SAMSUNG_USBPHY is not set
++# CONFIG_SAMSUNG_USB2PHY is not set
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG is not set
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++CONFIG_USB_G_MULTI=m
++CONFIG_USB_G_MULTI_RNDIS=y
++# CONFIG_USB_G_MULTI_CDC is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++# CONFIG_RPROC_SUPPORT is not set
++# CONFIG_RPCLNT_SUPPORT is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++CONFIG_PWM=y
++CONFIG_PWM_AMBARELLA=m
++CONFIG_IRQCHIP=y
++CONFIG_AMBARELLA_VIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=m
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=m
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=m
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++# CONFIG_DNOTIFY is not set
++CONFIG_INOTIFY_USER=y
++# CONFIG_FANOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_SQUASHFS=y
++# CONFIG_SQUASHFS_XATTR is not set
++CONFIG_SQUASHFS_ZLIB=y
++CONFIG_SQUASHFS_LZO=y
++CONFIG_SQUASHFS_XZ=y
++CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
++# CONFIG_SQUASHFS_EMBEDDED is not set
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_READABLE_ASM is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_LOCKUP_DETECTOR is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++# CONFIG_DETECT_HUNG_TASK is not set
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++# CONFIG_DEBUG_KMEMLEAK is not set
++CONFIG_DEBUG_PREEMPT=y
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_ATOMIC_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_TEST_LIST_SORT is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++
++#
++# RCU Debugging
++#
++# CONFIG_PROVE_RCU_DELAY is not set
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_RCU_CPU_STALL_TIMEOUT=21
++CONFIG_RCU_CPU_STALL_VERBOSE=y
++# CONFIG_RCU_CPU_STALL_INFO is not set
++# CONFIG_RCU_TRACE is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_DEBUG_PER_CPU_MAPS is not set
++# CONFIG_LKDTM is not set
++# CONFIG_NOTIFIER_ERROR_INJECTION is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_RBTREE_TEST is not set
++# CONFIG_INTERVAL_TREE_TEST is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_LL is not set
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_PCRYPT is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=m
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_USER_API=y
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_HW=y
++CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++# CONFIG_XZ_DEC_X86 is not set
++# CONFIG_XZ_DEC_POWERPC is not set
++# CONFIG_XZ_DEC_IA64 is not set
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++# CONFIG_XZ_DEC_SPARC is not set
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_CPU_RMAP=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/configs/ambarella_s3l_defconfig b/arch/arm/configs/ambarella_s3l_defconfig
+new file mode 100644
+index 00000000..4bc220eb
+--- /dev/null
++++ b/arch/arm/configs/ambarella_s3l_defconfig
+@@ -0,0 +1,2763 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.73 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_IO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="Ambarella"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++CONFIG_FHANDLE=y
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_IRQ_DOMAIN=y
++CONFIG_IRQ_DOMAIN_DEBUG=y
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++# CONFIG_TREE_PREEMPT_RCU is not set
++CONFIG_TINY_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++# CONFIG_RCU_STALL_COMMON is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++# CONFIG_CGROUP_FREEZER is not set
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++# CONFIG_CGROUP_CPUACCT is not set
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++# CONFIG_RT_GROUP_SCHED is not set
++# CONFIG_BLK_CGROUP is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++CONFIG_BLK_DEV_BSG=y
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_AMBPTB_PARTITION=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_READ_TRYLOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK=y
++CONFIG_ARCH_INLINE_READ_LOCK_BH=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_READ_UNLOCK=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_SPIN_TRYLOCK=y
++CONFIG_INLINE_SPIN_TRYLOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK=y
++CONFIG_INLINE_SPIN_LOCK_BH=y
++CONFIG_INLINE_SPIN_LOCK_IRQ=y
++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
++CONFIG_INLINE_SPIN_UNLOCK_BH=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_READ_TRYLOCK=y
++CONFIG_INLINE_READ_LOCK=y
++CONFIG_INLINE_READ_LOCK_BH=y
++CONFIG_INLINE_READ_LOCK_IRQ=y
++CONFIG_INLINE_READ_LOCK_IRQSAVE=y
++CONFIG_INLINE_READ_UNLOCK=y
++CONFIG_INLINE_READ_UNLOCK_BH=y
++CONFIG_INLINE_READ_UNLOCK_IRQ=y
++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
++CONFIG_INLINE_WRITE_TRYLOCK=y
++CONFIG_INLINE_WRITE_LOCK=y
++CONFIG_INLINE_WRITE_LOCK_BH=y
++CONFIG_INLINE_WRITE_LOCK_IRQ=y
++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
++CONFIG_INLINE_WRITE_UNLOCK=y
++CONFIG_INLINE_WRITE_UNLOCK_BH=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++CONFIG_ARCH_AMBARELLA=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_EXYNOS is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++CONFIG_PLAT_AMBARELLA=y
++
++#
++# Ambarella Platform
++#
++CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
++# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
++CONFIG_PLAT_AMBARELLA_CORTEX=y
++# CONFIG_PLAT_AMBARELLA_CORTEX_SMP is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
++CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
++CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
++# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
++# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
++# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
++# CONFIG_PLAT_AMBARELLA_S2 is not set
++# CONFIG_PLAT_AMBARELLA_A8 is not set
++# CONFIG_PLAT_AMBARELLA_A5S is not set
++# CONFIG_PLAT_AMBARELLA_A7L is not set
++# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2E is not set
++# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
++# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
++# CONFIG_PLAT_AMBARELLA_S2L is not set
++# CONFIG_PLAT_AMBARELLA_S3 is not set
++CONFIG_PLAT_AMBARELLA_S3L=y
++
++#
++# Generic Platform Configuration
++#
++CONFIG_AMBARELLA_CALC_PLL=y
++# CONFIG_AMBARELLA_RAW_BOOT is not set
++# CONFIG_AMBARELLA_PMUSERENR_EN is not set
++CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
++
++#
++# Sys file system support
++#
++# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
++
++#
++# Proc file system support
++#
++CONFIG_AMBARELLA_PLL_PROC=y
++# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
++
++#
++# Memory Configuration
++#
++CONFIG_AMBARELLA_PPM_SIZE=0x00200000
++CONFIG_AMBARELLA_ZRELADDR=0x00208000
++CONFIG_AMBARELLA_TEXTOFS=0x00008000
++CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
++CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
++# CONFIG_AMBARELLA_IO_MAP is not set
++# CONFIG_AMBARELLA_PPM_UNCACHED is not set
++CONFIG_AMBARELLA_TIMER_HZ=100
++CONFIG_AMBARELLA_TIMER_HIGHRES=y
++CONFIG_AMBARELLA_EXT_IRQ_NUM=16
++CONFIG_AMBARELLA_EXT_GPIO_NUM=16
++CONFIG_AMBARELLA_SREF_FIFO_EXEC=y
++CONFIG_GPIO_PCA953X=y
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++CONFIG_ARM_THUMBEE=y
++CONFIG_ARM_VIRT_EXT=y
++# CONFIG_SWP_EMULATE is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_KUSER_HELPERS=y
++CONFIG_OUTER_CACHE=y
++CONFIG_OUTER_CACHE_SYNC=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++CONFIG_CACHE_L2X0=y
++CONFIG_CACHE_PL310=y
++# CONFIG_CACHE_PL310_EARLY_BRESP is not set
++CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
++# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
++# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++CONFIG_PL310_ERRATA_588369=y
++# CONFIG_ARM_ERRATA_720789 is not set
++CONFIG_PL310_ERRATA_727915=y
++# CONFIG_ARM_ERRATA_743622 is not set
++# CONFIG_ARM_ERRATA_751472 is not set
++# CONFIG_PL310_ERRATA_753970 is not set
++# CONFIG_ARM_ERRATA_754322 is not set
++# CONFIG_PL310_ERRATA_769419 is not set
++# CONFIG_ARM_ERRATA_775420 is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_HAVE_ARM_ARCH_TIMER is not set
++# CONFIG_VMSPLIT_3G is not set
++CONFIG_VMSPLIT_2G=y
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0x80000000
++# CONFIG_ARM_PSCI is not set
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=100
++CONFIG_SCHED_HRTICK=y
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_HAVE_ARCH_PFN_VALID=y
++# CONFIG_HIGHMEM is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_COMPACTION is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_NEED_PER_CPU_KM=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++CONFIG_CC_STACKPROTECTOR=y
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_ARM_APPENDED_DTB is not set
++CONFIG_CMDLINE="console=ttyS0"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
++
++#
++# ARM CPU frequency scaling drivers
++#
++# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
++# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
++# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
++CONFIG_ARM_AMBARALLA_CPUFREQ=y
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_BINFMT_SCRIPT=y
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_HIBERNATE_CALLBACKS=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION=""
++CONFIG_PM_SLEEP=y
++# CONFIG_PM_AUTOSLEEP is not set
++CONFIG_PM_WAKELOCKS=y
++CONFIG_PM_WAKELOCKS_LIMIT=100
++CONFIG_PM_WAKELOCKS_GC=y
++# CONFIG_PM_RUNTIME is not set
++CONFIG_PM=y
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++# CONFIG_PM_TEST_SUSPEND is not set
++CONFIG_PM_SLEEP_DEBUG=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++CONFIG_UNIX_DIAG=y
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++CONFIG_XFRM_USER=y
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_NET_IP_TUNNEL is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++# CONFIG_NETPRIO_CGROUP is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++# CONFIG_BT_HIDP is not set
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=m
++CONFIG_BT_HCIBTSDIO=m
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++# CONFIG_BT_HCIUART_ATH3K is not set
++CONFIG_BT_HCIUART_LL=y
++# CONFIG_BT_HCIUART_3WIRE is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_BT_ATH3K is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=m
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEBUGFS=y
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++CONFIG_MAC80211=m
++CONFIG_MAC80211_HAS_RC=y
++CONFIG_MAC80211_RC_MINSTREL=y
++CONFIG_MAC80211_RC_MINSTREL_HT=y
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_MESSAGE_TRACING is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_INPUT=y
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH=""
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=m
++CONFIG_REGMAP_SPI=m
++CONFIG_DMA_SHARED_BUFFER=y
++# CONFIG_CMA is not set
++
++#
++# Bus devices
++#
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_OF_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_BLKDEVS=y
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
++CONFIG_MTD_BLOCK_AMBRO=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++# CONFIG_MTD_SWAP is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOCG3 is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_BCH=y
++CONFIG_MTD_NAND_ECC_BCH=y
++# CONFIG_MTD_SM_COMMON is not set
++CONFIG_MTD_NAND_AMBARELLA=y
++# CONFIG_MTD_SPINAND_AMBARELLA is not set
++# CONFIG_MTD_SPINAND_ONDIEECC is not set
++# CONFIG_MTD_NAND_DENALI is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_DOCG4 is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_LIMIT=20
++# CONFIG_MTD_UBI_FASTMAP is not set
++# CONFIG_MTD_UBI_GLUEBI is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=m
++CONFIG_OF_MTD=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=65536
++CONFIG_BLK_DEV_XIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SRAM is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_VENDOR_AMBARELLA=m
++CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_VENDOR_FARADAY is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++CONFIG_MICREL_PHY_KSZ80X1R=m
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_IPHETH is not set
++CONFIG_WLAN=y
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_MAC80211_HWSIM is not set
++CONFIG_ATH_CARDS=m
++# CONFIG_ATH_DEBUG is not set
++# CONFIG_ATH9K is not set
++# CONFIG_ATH9K_HTC is not set
++# CONFIG_CARL9170 is not set
++CONFIG_ATH6KL=m
++CONFIG_ATH6KL_SDIO=m
++# CONFIG_ATH6KL_USB is not set
++# CONFIG_ATH6KL_DEBUG is not set
++# CONFIG_AR5523 is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_RTLWIFI is not set
++# CONFIG_WL_TI is not set
++# CONFIG_ZD1211RW is not set
++CONFIG_MWIFIEX=m
++CONFIG_MWIFIEX_SDIO=m
++# CONFIG_MWIFIEX_USB is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=m
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=m
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_AD714X is not set
++# CONFIG_INPUT_BMA150 is not set
++CONFIG_INPUT_AMBARELLA_IR=m
++CONFIG_INPUT_AMBARELLA_ADC=m
++# CONFIG_INPUT_MMA8450 is not set
++# CONFIG_INPUT_MPU3050 is not set
++# CONFIG_INPUT_GP2A is not set
++# CONFIG_INPUT_GPIO_TILT_POLLED is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_KXTJ9 is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_CM109 is not set
++CONFIG_INPUT_UINPUT=m
++# CONFIG_INPUT_PCF8574 is not set
++# CONFIG_INPUT_PWM_BEEPER is not set
++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
++# CONFIG_INPUT_ADXL34X is not set
++# CONFIG_INPUT_CMA3000 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++# CONFIG_DEVKMEM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AMBARELLA=y
++CONFIG_SERIAL_AMBARELLA_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=m
++# CONFIG_I2C_MUX is not set
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_AMBARELLA=y
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_SLAVE=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_AMBARELLA=m
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# SPI Slave Controller Drivers
++#
++CONFIG_SPI_SLAVE_AMBARELLA=m
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_PINCTRL_SINGLE is not set
++# CONFIG_PINCTRL_EXYNOS is not set
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_PINCTRL_AMB=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++CONFIG_GPIO_PCA953X_IRQ=y
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AMBARELLA_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_MAX77686 is not set
++# CONFIG_MFD_MAX77693 is not set
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++# CONFIG_MFD_MAX8997 is not set
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++# CONFIG_MFD_SEC_CORE is not set
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_SYSCON is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65090 is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_WM8994 is not set
++# CONFIG_REGULATOR is not set
++CONFIG_MEDIA_SUPPORT=m
++
++#
++# Multimedia core support
++#
++CONFIG_MEDIA_CAMERA_SUPPORT=y
++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
++# CONFIG_MEDIA_RADIO_SUPPORT is not set
++# CONFIG_MEDIA_RC_SUPPORT is not set
++CONFIG_MEDIA_CONTROLLER=y
++CONFIG_VIDEO_DEV=m
++# CONFIG_VIDEO_V4L2_SUBDEV_API is not set
++CONFIG_VIDEO_V4L2=m
++# CONFIG_VIDEO_ADV_DEBUG is not set
++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
++CONFIG_VIDEOBUF2_CORE=m
++CONFIG_VIDEOBUF2_MEMOPS=m
++CONFIG_VIDEOBUF2_VMALLOC=m
++# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
++# CONFIG_TTPCI_EEPROM is not set
++
++#
++# Media drivers
++#
++CONFIG_MEDIA_USB_SUPPORT=y
++
++#
++# Webcam devices
++#
++CONFIG_USB_VIDEO_CLASS=m
++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
++CONFIG_USB_GSPCA=m
++# CONFIG_USB_M5602 is not set
++# CONFIG_USB_STV06XX is not set
++# CONFIG_USB_GL860 is not set
++# CONFIG_USB_GSPCA_BENQ is not set
++# CONFIG_USB_GSPCA_CONEX is not set
++# CONFIG_USB_GSPCA_CPIA1 is not set
++# CONFIG_USB_GSPCA_ETOMS is not set
++# CONFIG_USB_GSPCA_FINEPIX is not set
++# CONFIG_USB_GSPCA_JEILINJ is not set
++# CONFIG_USB_GSPCA_JL2005BCD is not set
++# CONFIG_USB_GSPCA_KINECT is not set
++# CONFIG_USB_GSPCA_KONICA is not set
++# CONFIG_USB_GSPCA_MARS is not set
++# CONFIG_USB_GSPCA_MR97310A is not set
++# CONFIG_USB_GSPCA_NW80X is not set
++# CONFIG_USB_GSPCA_OV519 is not set
++# CONFIG_USB_GSPCA_OV534 is not set
++# CONFIG_USB_GSPCA_OV534_9 is not set
++# CONFIG_USB_GSPCA_PAC207 is not set
++# CONFIG_USB_GSPCA_PAC7302 is not set
++# CONFIG_USB_GSPCA_PAC7311 is not set
++# CONFIG_USB_GSPCA_SE401 is not set
++# CONFIG_USB_GSPCA_SN9C2028 is not set
++# CONFIG_USB_GSPCA_SN9C20X is not set
++# CONFIG_USB_GSPCA_SONIXB is not set
++# CONFIG_USB_GSPCA_SONIXJ is not set
++# CONFIG_USB_GSPCA_SPCA500 is not set
++# CONFIG_USB_GSPCA_SPCA501 is not set
++# CONFIG_USB_GSPCA_SPCA505 is not set
++# CONFIG_USB_GSPCA_SPCA506 is not set
++# CONFIG_USB_GSPCA_SPCA508 is not set
++# CONFIG_USB_GSPCA_SPCA561 is not set
++# CONFIG_USB_GSPCA_SPCA1528 is not set
++# CONFIG_USB_GSPCA_SQ905 is not set
++# CONFIG_USB_GSPCA_SQ905C is not set
++# CONFIG_USB_GSPCA_SQ930X is not set
++# CONFIG_USB_GSPCA_STK014 is not set
++# CONFIG_USB_GSPCA_STV0680 is not set
++# CONFIG_USB_GSPCA_SUNPLUS is not set
++# CONFIG_USB_GSPCA_T613 is not set
++# CONFIG_USB_GSPCA_TOPRO is not set
++# CONFIG_USB_GSPCA_TV8532 is not set
++# CONFIG_USB_GSPCA_VC032X is not set
++# CONFIG_USB_GSPCA_VICAM is not set
++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
++# CONFIG_USB_GSPCA_ZC3XX is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_VIDEO_CPIA2 is not set
++# CONFIG_USB_ZR364XX is not set
++# CONFIG_USB_STKWEBCAM is not set
++# CONFIG_USB_S2255 is not set
++# CONFIG_USB_SN9C102 is not set
++
++#
++# Webcam, TV (analog/digital) USB devices
++#
++# CONFIG_VIDEO_EM28XX is not set
++# CONFIG_V4L_PLATFORM_DRIVERS is not set
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
++# CONFIG_VIDEO_SH_VEU is not set
++# CONFIG_V4L_TEST_DRIVERS is not set
++
++#
++# Supported MMC/SDIO adapters
++#
++# CONFIG_CYPRESS_FIRMWARE is not set
++
++#
++# Media ancillary drivers (tuners, sensors, i2c, frontends)
++#
++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
++
++#
++# Audio decoders, processors and mixers
++#
++
++#
++# RDS decoders
++#
++
++#
++# Video decoders
++#
++
++#
++# Video and audio decoders
++#
++
++#
++# Video encoders
++#
++
++#
++# Camera sensor devices
++#
++
++#
++# Flash devices
++#
++
++#
++# Video improvement chips
++#
++
++#
++# Miscelaneous helper chips
++#
++
++#
++# Sensors used on soc_camera driver
++#
++
++#
++# Tools to develop new frontends
++#
++# CONFIG_DVB_DUMMY_FE is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++# CONFIG_FB_CFB_FILLRECT is not set
++# CONFIG_FB_CFB_COPYAREA is not set
++# CONFIG_FB_CFB_IMAGEBLIT is not set
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++CONFIG_FB_SYS_FILLRECT=m
++CONFIG_FB_SYS_COPYAREA=m
++CONFIG_FB_SYS_IMAGEBLIT=m
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++CONFIG_FB_SYS_FOPS=m
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++CONFIG_FB_AMBARELLA=m
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_PWM=m
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=m
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_FONT_AUTOSELECT=y
++# CONFIG_LOGO is not set
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=m
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_COMPRESS_OFFLOAD=m
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_UA101 is not set
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_USB_6FIRE is not set
++CONFIG_SND_SOC=m
++CONFIG_SND_SOC_DMAENGINE_PCM=y
++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
++CONFIG_SND_AMBARELLA_SOC=m
++CONFIG_SND_AMBARELLA_SOC_I2S=m
++CONFIG_SND_AMBARELLA_BOARD=m
++CONFIG_AMBA_BOARD=m
++CONFIG_SND_AMBARELLA_CODEC=m
++# CONFIG_SND_SOC_AK4642_AMB is not set
++CONFIG_SND_SOC_AK4951_AMB=m
++# CONFIG_SND_SOC_AK4954_AMB is not set
++CONFIG_SND_SOC_AK7719_DSP=m
++CONFIG_SND_SOC_AK7755=m
++# CONFIG_SND_SOC_TLV320ADC3xxx is not set
++# CONFIG_SND_SOC_ES8388 is not set
++# CONFIG_SND_SOC_WM8974_AMB is not set
++# CONFIG_SND_SOC_WM8940_AMB is not set
++CONFIG_SND_SOC_AMBARELLA_DUMMY=m
++# CONFIG_SND_ATMEL_SOC is not set
++CONFIG_SND_SOC_I2C_AND_SPI=m
++# CONFIG_SND_SOC_ALL_CODECS is not set
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=m
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=m
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=m
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=m
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=m
++CONFIG_HID_CHERRY=m
++CONFIG_HID_CHICONY=m
++# CONFIG_HID_PRODIKEYS is not set
++CONFIG_HID_CYPRESS=m
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=m
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=m
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=m
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=m
++CONFIG_HID_MONTEREY=m
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEFAULT_PERSIST is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=m
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AMBARELLA=m
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++CONFIG_USB_OHCI_AMBARELLA=y
++# CONFIG_USB_OHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_U1960 is not set
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_F81232 is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_METRO is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_XSENS_MT is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_WISHBONE is not set
++# CONFIG_USB_SERIAL_ZTE is not set
++# CONFIG_USB_SERIAL_SSU100 is not set
++# CONFIG_USB_SERIAL_QT2 is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_EHSET_TEST_FIXTURE is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++CONFIG_USB_AMBARELLA_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++# CONFIG_SAMSUNG_USBPHY is not set
++# CONFIG_SAMSUNG_USB2PHY is not set
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=500
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++CONFIG_USB_AMBARELLA=m
++CONFIG_USB_LIBCOMPOSITE=m
++CONFIG_USB_F_ACM=m
++CONFIG_USB_U_SERIAL=m
++CONFIG_USB_F_SERIAL=m
++CONFIG_USB_F_OBEX=m
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++CONFIG_USB_MASS_STORAGE=m
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++CONFIG_USB_G_MULTI=m
++CONFIG_USB_G_MULTI_RNDIS=y
++# CONFIG_USB_G_MULTI_CDC is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++# CONFIG_USB_G_WEBCAM is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_MINORS=32
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++CONFIG_MMC_AMBARELLA=m
++# CONFIG_AMBARELLA_EMMC_BOOT is not set
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MMC_DW is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++CONFIG_RTC_INTF_DEV_UIE_EMUL=y
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++CONFIG_RTC_DRV_ISL12022=y
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AMBARELLA=y
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_AMBARELLA_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++
++#
++# Hardware Spinlock drivers
++#
++# CONFIG_MAILBOX is not set
++# CONFIG_IOMMU_SUPPORT is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++# CONFIG_RPROC_SUPPORT is not set
++# CONFIG_RPCLNT_SUPPORT is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++CONFIG_IIO=m
++CONFIG_IIO_BUFFER=y
++# CONFIG_IIO_BUFFER_CB is not set
++CONFIG_IIO_KFIFO_BUF=m
++CONFIG_IIO_TRIGGERED_BUFFER=m
++CONFIG_IIO_TRIGGER=y
++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
++
++#
++# Accelerometers
++#
++# CONFIG_KXSD9 is not set
++# CONFIG_IIO_ST_ACCEL_3AXIS is not set
++
++#
++# Analog to digital converters
++#
++# CONFIG_AD7266 is not set
++# CONFIG_AD7298 is not set
++# CONFIG_AD7923 is not set
++# CONFIG_AD7791 is not set
++# CONFIG_AD7793 is not set
++# CONFIG_AD7476 is not set
++# CONFIG_AD7887 is not set
++# CONFIG_EXYNOS_ADC is not set
++# CONFIG_MAX1363 is not set
++# CONFIG_TI_ADC081C is not set
++
++#
++# Amplifiers
++#
++# CONFIG_AD8366 is not set
++
++#
++# Hid Sensor IIO Common
++#
++
++#
++# Digital to analog converters
++#
++# CONFIG_AD5064 is not set
++# CONFIG_AD5360 is not set
++# CONFIG_AD5380 is not set
++# CONFIG_AD5421 is not set
++# CONFIG_AD5624R_SPI is not set
++# CONFIG_AD5446 is not set
++# CONFIG_AD5449 is not set
++# CONFIG_AD5504 is not set
++# CONFIG_AD5755 is not set
++# CONFIG_AD5764 is not set
++# CONFIG_AD5791 is not set
++# CONFIG_AD5686 is not set
++# CONFIG_MAX517 is not set
++# CONFIG_MCP4725 is not set
++
++#
++# Frequency Synthesizers DDS/PLL
++#
++
++#
++# Clock Generator/Distribution
++#
++# CONFIG_AD9523 is not set
++
++#
++# Phase-Locked Loop (PLL) frequency synthesizers
++#
++# CONFIG_ADF4350 is not set
++
++#
++# Digital gyroscope sensors
++#
++# CONFIG_ADIS16080 is not set
++# CONFIG_ADIS16136 is not set
++# CONFIG_ADXRS450 is not set
++# CONFIG_IIO_ST_GYRO_3AXIS is not set
++# CONFIG_ITG3200 is not set
++
++#
++# Inertial measurement units
++#
++# CONFIG_ADIS16400 is not set
++# CONFIG_ADIS16480 is not set
++# CONFIG_INV_MPU6050_IIO is not set
++CONFIG_INV_MPU9250_IIO=m
++
++#
++# Light sensors
++#
++# CONFIG_ADJD_S311 is not set
++# CONFIG_SENSORS_TSL2563 is not set
++# CONFIG_VCNL4000 is not set
++
++#
++# Magnetometer sensors
++#
++# CONFIG_AK8975 is not set
++# CONFIG_IIO_ST_MAGN_3AXIS is not set
++CONFIG_PWM=y
++CONFIG_PWM_AMBARELLA=m
++CONFIG_IRQCHIP=y
++CONFIG_AMBARELLA_VIC=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=m
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=m
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=m
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_EXPORTFS=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++# CONFIG_DNOTIFY is not set
++CONFIG_INOTIFY_USER=y
++# CONFIG_FANOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
++CONFIG_CUSE=m
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=m
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_UBIFS_FS=y
++CONFIG_UBIFS_FS_ADVANCED_COMPR=y
++CONFIG_UBIFS_FS_LZO=y
++CONFIG_UBIFS_FS_ZLIB=y
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_SQUASHFS=y
++# CONFIG_SQUASHFS_XATTR is not set
++CONFIG_SQUASHFS_ZLIB=y
++CONFIG_SQUASHFS_LZO=y
++CONFIG_SQUASHFS_XZ=y
++CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
++# CONFIG_SQUASHFS_EMBEDDED is not set
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_SWAP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++# CONFIG_NFSD_V4 is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_DEBUG is not set
++# CONFIG_CEPH_FS is not set
++CONFIG_CIFS=y
++CONFIG_CIFS_STATS=y
++# CONFIG_CIFS_STATS2 is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR is not set
++CONFIG_CIFS_DEBUG=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_SMB2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_SECTION_MISMATCH=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++
++#
++# RCU Debugging
++#
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_LKDTM is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=m
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_USER_API=y
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_HW=y
++CONFIG_CRYPTO_DEV_AMBARELLA=m
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_RATIONAL=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++# CONFIG_XZ_DEC_X86 is not set
++# CONFIG_XZ_DEC_POWERPC is not set
++# CONFIG_XZ_DEC_IA64 is not set
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++# CONFIG_XZ_DEC_SPARC is not set
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_BCH=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++CONFIG_AVERAGE=y
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
+index f89515ad..bfe2a2f5 100644
+--- a/arch/arm/include/asm/ftrace.h
++++ b/arch/arm/include/asm/ftrace.h
+@@ -45,22 +45,14 @@ void *return_address(unsigned int);
+ 
+ #else
+ 
+-extern inline void *return_address(unsigned int level)
++static inline void *return_address(unsigned int level)
+ {
+ 	return NULL;
+ }
+ 
+ #endif
+ 
+-#define HAVE_ARCH_CALLER_ADDR
+-
+-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+-#define CALLER_ADDR1 ((unsigned long)return_address(1))
+-#define CALLER_ADDR2 ((unsigned long)return_address(2))
+-#define CALLER_ADDR3 ((unsigned long)return_address(3))
+-#define CALLER_ADDR4 ((unsigned long)return_address(4))
+-#define CALLER_ADDR5 ((unsigned long)return_address(5))
+-#define CALLER_ADDR6 ((unsigned long)return_address(6))
++#define ftrace_return_address(n) return_address(n)
+ 
+ #endif /* ifndef __ASSEMBLY__ */
+ 
+diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
+index 3b2c40b5..b1379075 100644
+--- a/arch/arm/include/asm/hardware/cache-l2x0.h
++++ b/arch/arm/include/asm/hardware/cache-l2x0.h
+@@ -78,6 +78,8 @@
+ #define L2X0_CACHE_ID_RTL_R3P2          0x8
+ 
+ #define L2X0_AUX_CTRL_MASK			0xc0000fff
++#define L2X0_AUX_CTRL_FULL_LINE_OF_ZERO_SHIFT	0
++#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT	0
+ #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT	0
+ #define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK	0x7
+ #define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT	3
+@@ -90,12 +92,21 @@
+ #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT		17
+ #define L2X0_AUX_CTRL_WAY_SIZE_MASK		(0x7 << 17)
+ #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT	22
++#define L2X0_AUX_CTRL_CR_POLICY_SHIFT		25
+ #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT		26
+ #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT		27
+ #define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT	28
+ #define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT	29
+ #define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT		30
+ 
++#define L2X0_PREFETCH_CTRL_PREFETCH_OFFSET_SHIFT	0
++#define L2X0_PREFETCH_CTRL_PREFETCH_OFFSET_MASK		0x1f
++#define L2X0_PREFETCH_CTRL_PREFETCH_DROP_SHIFT		24
++#define L2X0_PREFETCH_CTRL_DOUBLE_LINEFILL_INCR_SHIFT	23
++#define L2X0_PREFETCH_CTRL_DATA_PREFETCH_SHIFT		28
++#define L2X0_PREFETCH_CTRL_INST_PREFETCH_SHIFT		29
++#define L2X0_PREFETCH_CTRL_DOUBLE_LINEFILL_SHIFT	30
++
+ #define L2X0_LATENCY_CTRL_SETUP_SHIFT	0
+ #define L2X0_LATENCY_CTRL_RD_SHIFT	4
+ #define L2X0_LATENCY_CTRL_WR_SHIFT	8
+@@ -107,7 +118,7 @@
+ #define L2X0_WAY_SIZE_SHIFT		3
+ 
+ #ifndef __ASSEMBLY__
+-extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
++extern void l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
+ #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
+ extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
+ #else
+diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
+index d847cbbc..c27f1070 100644
+--- a/arch/arm/include/asm/memory.h
++++ b/arch/arm/include/asm/memory.h
+@@ -80,7 +80,7 @@
+  */
+ #define IOREMAP_MAX_ORDER	24
+ 
+-#define CONSISTENT_END		(0xffe00000UL)
++#define CONSISTENT_END		(0xfee00000UL)
+ 
+ #else /* CONFIG_MMU */
+ 
+diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
+index f94784f0..dfedbfc1 100644
+--- a/arch/arm/include/asm/outercache.h
++++ b/arch/arm/include/asm/outercache.h
+@@ -33,6 +33,9 @@ struct outer_cache_fns {
+ #ifdef CONFIG_OUTER_CACHE_SYNC
+ 	void (*sync)(void);
+ #endif
++	void (*clean_all)(void);
++	void (*enable)(void);
++	int (*is_enabled)(void);
+ 	void (*set_debug)(unsigned long);
+ 	void (*resume)(void);
+ };
+@@ -81,6 +84,25 @@ static inline void outer_resume(void)
+ 		outer_cache.resume();
+ }
+ 
++static inline void outer_clean_all(void)
++{
++	if (outer_cache.clean_all)
++		outer_cache.clean_all();
++}
++
++static inline void outer_enable(void)
++{
++	if (outer_cache.enable)
++		outer_cache.enable();
++}
++
++static inline int outer_is_enabled(void)
++{
++	if (outer_cache.is_enabled)
++		return outer_cache.is_enabled();
++	return 0;
++}
++
+ #else
+ 
+ static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
+@@ -93,6 +115,9 @@ static inline void outer_flush_all(void) { }
+ static inline void outer_inv_all(void) { }
+ static inline void outer_disable(void) { }
+ static inline void outer_resume(void) { }
++static inline void outer_clean_all(void) { }
++static inline void outer_enable(void) { }
++static inline int outer_is_enabled(void) { return 0; }
+ 
+ #endif
+ 
+diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
+index 14512e69..762fc66f 100644
+--- a/arch/arm/kernel/atags_parse.c
++++ b/arch/arm/kernel/atags_parse.c
+@@ -46,7 +46,11 @@ static struct {
+ 	{ tag_size(tag_core), ATAG_CORE },
+ 	{ 1, PAGE_SIZE, 0xff },
+ 	{ tag_size(tag_mem32), ATAG_MEM },
++#if defined(CONFIG_AMBARELLA_RAW_BOOT)
++	{ CONFIG_AMBARELLA_MEMORY_SIZE, (DEFAULT_MEM_START + CONFIG_AMBARELLA_PPM_SIZE) },
++#else
+ 	{ MEM_SIZE },
++#endif
+ 	{ 0, ATAG_NONE }
+ };
+ 
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index f935b5f6..fe5223e1 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -75,6 +75,47 @@
+  */
+ 	.arm
+ 
++	.macro	invall_tlb_control, tmp0
++	mov		\tmp0, #0x00
++	mcr		p15, 0, \tmp0, c8, c7, 0		/* Invalidate entire unified TLB */
++	mcr		p15, 0, \tmp0, c8, c6, 0		/* Invalidate entire data TLB */
++	mcr		p15, 0, \tmp0, c8, c5, 0		/* Invalidate entire instruction TLB */
++	.endm
++
++	.macro	invall_cache, name, tmp0, tmp1, tmp2, tmp3, tmp4
++	mov		\tmp0, #0
++	mcr		p15, 0, \tmp0, c7, c5, 6		/* Invalidate entire branch prediction array */
++	mcr		p15, 0, \tmp0, c7, c5, 0		/* Invalidate entire icache */
++	mcr		p15, 2, \tmp0, c0, c0, 0		/* cache size selection register, select dcache */
++	mrc		p15, 1, \tmp0, c0, c0, 0		/* cache size id register */
++	mov		\tmp0, \tmp0, asr #13
++	movw		\tmp2, #0x0fff
++	and		\tmp0, \tmp0, \tmp2
++	cmp		\tmp0, #0x7f
++	moveq		\tmp0, #0x1000
++	beq		size_done_\name
++	cmp		\tmp0, #0xff
++	moveq		\tmp0, #0x2000
++	movne		\tmp0, #0x4000
++size_done_\name:
++	mov		\tmp1, #0
++	mov		\tmp2, #0x40000000
++	mov		\tmp3, #0x80000000
++	mov		\tmp4, #0xc0000000
++inv_dloop_\name:
++	mcr		p15, 0, \tmp1, c7, c6, 2		/* invalidate dcache by set / way */
++	mcr		p15, 0, \tmp2, c7, c6, 2		/* invalidate dcache by set / way */
++	mcr		p15, 0, \tmp3, c7, c6, 2		/* invalidate dcache by set / way */
++	mcr		p15, 0, \tmp4, c7, c6, 2		/* invalidate dcache by set / way */
++	add		\tmp1, \tmp1, #0x20
++	add		\tmp2, \tmp2, #0x20
++	add		\tmp3, \tmp3, #0x20
++	add		\tmp4, \tmp4, #0x20
++	cmp		\tmp1, \tmp0
++	bne		inv_dloop_\name
++	.endm
++
++
+ 	__HEAD
+ ENTRY(stext)
+ 
+@@ -83,6 +124,11 @@ ENTRY(stext)
+  THUMB(	.thumb			)	@ switch to Thumb now.
+  THUMB(1:			)
+ 
++#if defined(CONFIG_AMBARELLA_RAW_BOOT)
++	invall_tlb_control	r3
++	invall_cache		bootstrap, r3, r4, r5, r6, r7
++#endif
++
+ #ifdef CONFIG_ARM_VIRT_EXT
+ 	bl	__hyp_stub_install
+ #endif
+@@ -455,14 +501,12 @@ ENDPROC(__enable_mmu)
+  *
+  * other registers depend on the function called upon completion
+  */
+-	.align	5
+ 	.pushsection	.idmap.text, "ax"
++	.align	5
+ ENTRY(__turn_mmu_on)
+ 	mov	r0, r0
+-	instr_sync
+ 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
+ 	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
+-	instr_sync
+ 	mov	r3, r3
+ 	mov	r3, r13
+ 	mov	pc, r3
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index ac4c2e5e..943660cf 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -223,6 +223,14 @@ void machine_power_off(void)
+ 
+ 	if (pm_power_off)
+ 		pm_power_off();
++
++	/* Give a grace period for failure to restart of 1s */
++	mdelay(1000);
++
++	/* A workaround for power off failed */
++	printk("Power off -- System halted\n");
++	local_irq_disable();
++	while (1);
+ }
+ 
+ /*
+diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
+index fafedd86..3a861fc4 100644
+--- a/arch/arm/kernel/return_address.c
++++ b/arch/arm/kernel/return_address.c
+@@ -60,14 +60,10 @@ void *return_address(unsigned int level)
+ #else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
+ 
+ #if defined(CONFIG_ARM_UNWIND)
+-#warning "TODO: return_address should use unwind tables"
++//To ceaes compile warning
++/* #warning "TODO: return_address should use unwind tables" */
+ #endif
+ 
+-void *return_address(unsigned int level)
+-{
+-	return NULL;
+-}
+-
+ #endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
+ 
+ EXPORT_SYMBOL_GPL(return_address);
+diff --git a/arch/arm/mach-ambarella/Kconfig b/arch/arm/mach-ambarella/Kconfig
+new file mode 100644
+index 00000000..6a7911a0
+--- /dev/null
++++ b/arch/arm/mach-ambarella/Kconfig
+@@ -0,0 +1,481 @@
++#
++# arch/arm/mach-ambarella/Kconfig
++#
++# History:
++#	2006/12/18 - [Charles Chiou] created file
++#
++# Copyright (C) 2004-2009, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++config PLAT_AMBARELLA
++	bool
++	depends on ARCH_AMBARELLA
++	default y
++	select GENERIC_GPIO
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select ARCH_INLINE_SPIN_TRYLOCK
++	select ARCH_INLINE_SPIN_TRYLOCK_BH
++	select ARCH_INLINE_SPIN_LOCK
++	select ARCH_INLINE_SPIN_LOCK_BH
++	select ARCH_INLINE_SPIN_LOCK_IRQ
++	select ARCH_INLINE_SPIN_LOCK_IRQSAVE
++	select ARCH_INLINE_SPIN_UNLOCK
++	select ARCH_INLINE_SPIN_UNLOCK_BH
++	select ARCH_INLINE_SPIN_UNLOCK_IRQ
++	select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
++	select ARCH_INLINE_READ_TRYLOCK
++	select ARCH_INLINE_READ_LOCK
++	select ARCH_INLINE_READ_LOCK_BH
++	select ARCH_INLINE_READ_LOCK_IRQ
++	select ARCH_INLINE_READ_LOCK_IRQSAVE
++	select ARCH_INLINE_READ_UNLOCK
++	select ARCH_INLINE_READ_UNLOCK_BH
++	select ARCH_INLINE_READ_UNLOCK_IRQ
++	select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
++	select ARCH_INLINE_WRITE_TRYLOCK
++	select ARCH_INLINE_WRITE_LOCK
++	select ARCH_INLINE_WRITE_LOCK_BH
++	select ARCH_INLINE_WRITE_LOCK_IRQ
++	select ARCH_INLINE_WRITE_LOCK_IRQSAVE
++	select ARCH_INLINE_WRITE_UNLOCK
++	select ARCH_INLINE_WRITE_UNLOCK_BH
++	select ARCH_INLINE_WRITE_UNLOCK_IRQ
++	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
++	select HAVE_CLK
++	help
++	  Base platform code for any Ambarella device
++
++if PLAT_AMBARELLA
++comment "Ambarella Platform"
++
++config PLAT_AMBARELLA_SUPPORT_VIC
++	bool
++	default n
++	select AMBARELLA_VIC
++
++config PLAT_AMBARELLA_HAVE_ARM11
++	bool
++	default n
++
++config PLAT_AMBARELLA_CORTEX
++	bool
++	default n
++	select CPU_V7
++	select MIGHT_HAVE_CACHE_L2X0
++
++config PLAT_AMBARELLA_CORTEX_SMP
++	bool
++	depends on PLAT_AMBARELLA_CORTEX
++	default n
++	select HAVE_SMP
++	select HAVE_ARM_SCU if SMP
++
++config PLAT_AMBARELLA_LOCAL_TIMERS
++	bool
++	depends on PLAT_AMBARELLA_CORTEX_SMP
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_PM
++	bool
++	default n
++
++config PLAT_AMBARELLA_MEM_START_LOW
++	bool
++	default n
++
++config PLAT_AMBARELLA_AHB_APB_HIGH
++	bool
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	bool
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	bool
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	bool
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_MMAP_AHB64
++	bool
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
++	bool
++	default n
++
++config PLAT_AMBARELLA_ADD_REGISTER_LOCK
++	bool
++	default n
++
++config PLAT_AMBARELLA_SUPPORT_RPROC
++	bool
++	default n
++
++config PLAT_AMBARELLA_S2
++	bool
++	select USB_ARCH_HAS_EHCI if USB_SUPPORT
++	select USB_ARCH_HAS_OHCI if USB_SUPPORT
++	default n
++
++config PLAT_AMBARELLA_A8
++	bool
++	select PLAT_AMBARELLA_MEM_START_LOW
++	select PLAT_AMBARELLA_AHB_APB_HIGH
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
++	default n
++
++choice
++	prompt "Chip REV"
++
++config PLAT_AMBARELLA_A5S
++	bool "A5S"
++	select CPU_V6
++	select CPU_32v6K
++	select PLAT_AMBARELLA_HAVE_ARM11
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	help
++	  Say Y here if you are using Ambarella A5S.
++
++config PLAT_AMBARELLA_A7L
++	bool "A7L"
++	select CPU_V6
++	select CPU_32v6K
++	select PLAT_AMBARELLA_HAVE_ARM11
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	help
++	  Say Y here if you are using Ambarella A7l.
++
++config PLAT_AMBARELLA_S2_ARM11
++	bool "S2 ARM11"
++	select CPU_V6
++	select CPU_32v6K
++	select PLAT_AMBARELLA_HAVE_ARM11
++	select PLAT_AMBARELLA_S2
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AHB64
++	help
++	  Say Y here if you are using Ambarella S2 ARM11.
++
++config PLAT_AMBARELLA_S2_CORTEX
++	bool "S2 Cortex"
++	select ARM_GIC
++	select PLAT_AMBARELLA_HAVE_ARM11
++	select PLAT_AMBARELLA_S2
++	select PLAT_AMBARELLA_CORTEX
++	select PLAT_AMBARELLA_CORTEX_SMP
++	select HAVE_ARM_TWD if LOCAL_TIMERS
++	select PLAT_AMBARELLA_MEM_START_LOW
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	select ARM_ERRATA_754322
++	select ARM_ERRATA_764369 if SMP
++	select ARM_ERRATA_775420
++	select PL310_ERRATA_588369 if CACHE_PL310
++	select PL310_ERRATA_727915 if CACHE_PL310
++	select PL310_ERRATA_753970 if CACHE_PL310
++	select PL310_ERRATA_769419 if CACHE_PL310
++
++	help
++	  Say Y here if you are using Ambarella S2 Cortex.
++
++config PLAT_AMBARELLA_S2E
++	bool "S2E"
++	select PLAT_AMBARELLA_CORTEX
++	select PLAT_AMBARELLA_CORTEX_SMP
++	select PLAT_AMBARELLA_LOCAL_TIMERS if LOCAL_TIMERS
++	select PLAT_AMBARELLA_SUPPORT_PM if PM
++	select AMBARELLA_SREF_FIFO_EXEC	if PM
++	select PLAT_AMBARELLA_MEM_START_LOW
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select USB_ARCH_HAS_EHCI if USB_SUPPORT
++	select USB_ARCH_HAS_OHCI if USB_SUPPORT
++	select ARM_ERRATA_754322
++	select ARM_ERRATA_764369 if SMP
++	select ARM_ERRATA_775420
++	select PL310_ERRATA_588369 if CACHE_PL310
++	select PL310_ERRATA_727915 if CACHE_PL310
++	help
++	  Say Y here if you are using Ambarella S2E.
++
++config PLAT_AMBARELLA_A8_ARM11
++	bool "A8 ARM11"
++	select CPU_V6
++	select CPU_32v6K
++	select PLAT_AMBARELLA_HAVE_ARM11
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_A8
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	help
++	  Say Y here if you are using Ambarella A8 ARM11.
++
++config PLAT_AMBARELLA_A8_CORTEX
++	bool "A8 Cortex"
++	select ARM_GIC
++	select PLAT_AMBARELLA_HAVE_ARM11
++	select PLAT_AMBARELLA_A8
++	select PLAT_AMBARELLA_CORTEX
++	select PLAT_AMBARELLA_CORTEX_SMP
++	select HAVE_ARM_TWD if LOCAL_TIMERS
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	select PLAT_AMBARELLA_SUPPORT_RPROC
++	select AMBARELLA_IO_MAP
++	select AMBARELLA_PPM_UNCACHED
++	select ARM_ERRATA_754322
++	select ARM_ERRATA_764369 if SMP
++	select ARM_ERRATA_775420
++	select PL310_ERRATA_588369 if CACHE_PL310
++	select PL310_ERRATA_727915 if CACHE_PL310
++	select PL310_ERRATA_753970 if CACHE_PL310
++	select PL310_ERRATA_769419 if CACHE_PL310
++	help
++	  Say Y here if you are using Ambarella A8 Cortex.
++
++config PLAT_AMBARELLA_S2L
++	bool "S2L"
++	select PLAT_AMBARELLA_CORTEX
++	select PLAT_AMBARELLA_SUPPORT_PM if PM
++	select PLAT_AMBARELLA_MEM_START_LOW
++	select PLAT_AMBARELLA_AHB_APB_HIGH
++	select AMBARELLA_SREF_FIFO_EXEC if PM
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select USB_ARCH_HAS_EHCI if USB_SUPPORT
++	select USB_ARCH_HAS_OHCI if USB_SUPPORT
++	select PL310_ERRATA_588369 if CACHE_PL310
++	select PL310_ERRATA_727915 if CACHE_PL310
++	help
++	  Say Y here if you are using Ambarella S2L.
++
++config PLAT_AMBARELLA_S3
++	bool "S3"
++	select PLAT_AMBARELLA_CORTEX
++	select PLAT_AMBARELLA_CORTEX_SMP
++	select PLAT_AMBARELLA_LOCAL_TIMERS if LOCAL_TIMERS
++	select PLAT_AMBARELLA_SUPPORT_PM if PM
++	select PLAT_AMBARELLA_MEM_START_LOW
++	select PLAT_AMBARELLA_AHB_APB_HIGH
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select USB_ARCH_HAS_EHCI if USB_SUPPORT
++	select USB_ARCH_HAS_OHCI if USB_SUPPORT
++	select ARM_ERRATA_764369 if SMP
++	select PL310_ERRATA_588369 if CACHE_PL310
++	select PL310_ERRATA_727915 if CACHE_PL310
++	help
++	  Say Y here if you are using Ambarella S3.
++
++config PLAT_AMBARELLA_S3L
++	bool "S3L"
++	select PLAT_AMBARELLA_CORTEX
++	select PLAT_AMBARELLA_SUPPORT_PM if PM
++	select AMBARELLA_SREF_FIFO_EXEC	if PM
++	select PLAT_AMBARELLA_MEM_START_LOW
++	select PLAT_AMBARELLA_AHB_APB_HIGH
++	select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
++	select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
++	select PLAT_AMBARELLA_SUPPORT_VIC
++	select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select USB_ARCH_HAS_EHCI if USB_SUPPORT
++	select USB_ARCH_HAS_OHCI if USB_SUPPORT
++	select PL310_ERRATA_588369 if CACHE_PL310
++	select PL310_ERRATA_727915 if CACHE_PL310
++	help
++	  Say Y here if you are using Ambarella S3L.
++
++endchoice
++
++menu "Generic Platform Configuration"
++
++config AMBARELLA_CALC_PLL
++	bool "Setup PLL by Calculation"
++	select RATIONAL
++	default n
++	help
++	  If you are not sure, say N here.
++
++config AMBARELLA_RAW_BOOT
++	bool "Raw boot mode"
++	default n
++	help
++	  If you are not sure, say N here.
++
++config PLAT_AMBARELLA_LOWER_ARM_PLL
++	bool "Lower ARM11 PLL when use Cortex only"
++	default n
++	depends on PLAT_AMBARELLA_S2_CORTEX
++	help
++	  If you are not sure, say N here.
++
++config AMBARELLA_PMUSERENR_EN
++	bool "Enable userspcae access to PMU"
++	default n
++	help
++	  Enable userspcae access to PMU
++
++config PLAT_AMBARELLA_SUPPORT_GDMA
++	bool "Enable gdma"
++	default n
++	help
++	  Enable gdma
++
++menu "Sys file system support"
++depends on SYSFS
++
++config AMBARELLA_SYS_CACHE_CALL
++	bool "Support Cache Configuration"
++	default n
++	help
++	  If you are not sure, say N here.
++
++endmenu
++
++menu "Proc file system support"
++depends on PROC_FS
++
++config AMBARELLA_PLL_PROC
++	bool "Suport Ambarella PLL proc"
++	default n
++	---help---
++	  /proc/ambarella/clock
++
++	  If you are not sure, say N here.
++
++config AMBARELLA_SUPPORT_AMBENCH
++	bool "Suport Ambarella Test (ambench)"
++	default n
++	help
++	  /proc/ambarella/ambench
++
++	  If you are not sure, say N here.
++
++endmenu
++
++menu "Memory Configuration"
++
++config AMBARELLA_PPM_SIZE
++	hex "PPM SIZE"
++	default 0x00000000
++	range 0x00000000 0x10000000 if VMSPLIT_3G
++	range 0x00000000 0x20000000 if VMSPLIT_2G
++	range 0x00000000 0x60000000 if VMSPLIT_1G
++	help
++	  Specify the size from the start of physical DRAM address to reserve.
++
++config AMBARELLA_MEMORY_SIZE
++	hex "Default MEMORY SIZE"
++	depends on AMBARELLA_RAW_BOOT
++	default 0x08000000
++	range 0x04000000 0x40000000
++	help
++	  Specify the size of physical DRAM for debug.
++
++config AMBARELLA_ZRELADDR
++	hex "ZRELADDR"
++	default 0x00108000
++	help
++	  Specify the kernel entry point start physical address.
++
++config AMBARELLA_TEXTOFS
++	hex "TEXTOFS"
++	default 0x00108000
++	help
++	  Speicify the relative text offset.
++
++config AMBARELLA_PARAMS_PHYS
++	hex "PARAMS PHYS"
++	default 0x000c0000
++	help
++	  Specify the physical address for kernel parameters.
++
++config AMBARELLA_INITRD_PHYS
++	hex "INITRD PHYS"
++	default 0x00a00000
++	help
++	  Specify the physical address for initrd.
++
++config AMBARELLA_IO_MAP
++	bool "Use Ambarella IO Map"
++	default n
++	help
++	  __virt_to_phys & __phys_to_virt will use lookup table.
++
++config AMBARELLA_PPM_UNCACHED
++	bool "Map PPM as MT_DEVICE"
++	default n
++	help
++	  Default MT_MEMORY.
++
++endmenu
++
++config AMBARELLA_TIMER_HZ
++	int "Kernel HZ (jiffies per second)"
++	range 100 1000
++	default 100
++	help
++	  Please test and figure out what you need.
++
++config AMBARELLA_TIMER_HIGHRES
++	bool "High resolution timer wrapper Support"
++	default n
++	depends on HIGH_RES_TIMERS
++	help
++		Add high resolution timer wrapper for non-GPL
++
++config AMBARELLA_EXT_IRQ_NUM
++	int "External IRQ Num"
++	range 0 256
++	default 64
++	help
++	  Depends on your HW design.
++
++config AMBARELLA_EXT_GPIO_NUM
++	int "External GPIO Num"
++	range 0 256
++	default 64
++	help
++	  Depends on your HW design.
++
++config AMBARELLA_SREF_FIFO_EXEC
++	bool "Self refresh code executed in FIO fifo"
++	default n
++	depends on PLAT_AMBARELLA_SUPPORT_PM
++	help
++		Self refresh 2nd solution.
++endmenu
++
++endif
++
+diff --git a/arch/arm/mach-ambarella/Makefile b/arch/arm/mach-ambarella/Makefile
+new file mode 100644
+index 00000000..b8238cba
+--- /dev/null
++++ b/arch/arm/mach-ambarella/Makefile
+@@ -0,0 +1,39 @@
++#
++# arch/arm/mach-ambarella/Makefile
++#
++# Author: Anthony Ginger <hfjiang@ambarella.com>
++#
++# Copyright (C) 2004-2011, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++obj-y						+= fio.o
++obj-y						+= init.o
++obj-y						+= clk.o
++ifeq ($(CONFIG_AMBARELLA_CALC_PLL),y)
++obj-y						+= clk_calc.o
++else
++obj-y						+= clk_table.o
++endif
++obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_PM)		+= pm.o
++obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_PM)		+= sleep.o
++obj-y						+= timer.o
++obj-y						+= adc.o
++
++obj-y						+= soc/
++obj-y						+= smp/
++obj-y						+= misc/
++
+diff --git a/arch/arm/mach-ambarella/Makefile.boot b/arch/arm/mach-ambarella/Makefile.boot
+new file mode 100644
+index 00000000..e31691e9
+--- /dev/null
++++ b/arch/arm/mach-ambarella/Makefile.boot
+@@ -0,0 +1,27 @@
++#
++# arch/arm/mach-ambarella/Makefile.boot
++#
++# History:
++#	2006/12/18 - [Charles Chiou] created file
++#
++# Copyright (C) 2004-2009, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++zreladdr-y		:= $(CONFIG_AMBARELLA_ZRELADDR)
++params_phys-y		:= $(CONFIG_AMBARELLA_PARAMS_PHYS)
++initrd_phys-y		:= $(CONFIG_AMBARELLA_INITRD_PHYS)
++
+diff --git a/arch/arm/mach-ambarella/adc.c b/arch/arm/mach-ambarella/adc.c
+new file mode 100644
+index 00000000..b579e901
+--- /dev/null
++++ b/arch/arm/mach-ambarella/adc.c
+@@ -0,0 +1,510 @@
++/*
++ * arch/arm/plat-ambarella/generic/ambarella_adc_drv.c
++ *
++ * Author: Bing-Liang Hu <blhu@ambarella.com>
++ *
++ * History:
++ *	2014/07/21 - [Cao Rongrong] Re-design the mechanism with client
++ *
++ * Copyright (C) 2014-2019, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/of.h>
++#include <mach/hardware.h>
++#include <plat/adc.h>
++#include <plat/rct.h>
++
++static DEFINE_MUTEX(client_mutex);
++static LIST_HEAD(client_list);
++static struct ambadc_host *ambarella_adc;
++
++static ssize_t ambarella_adc_show(struct device *dev,
++				  struct device_attribute *attr,
++				  char *buf)
++{
++	ssize_t ret = 0;
++	u32 i, data;
++
++	for (i = 0; i < ADC_NUM_CHANNELS; i++) {
++		data = ambarella_adc_read_level(i);
++		ret += sprintf(&buf[ret], "adc%d=0x%x\n", i, data);
++	}
++
++	return ret;
++}
++static DEVICE_ATTR(adcsys, 0444, ambarella_adc_show, NULL);
++
++static int ambarella_adc_fifo_ctrl(u32 fid, u16 fcid)
++{
++	u32 reg=0;
++	u32 reg_val=0;
++
++	switch(fid) {
++	case 0:
++		reg = ADC_FIFO_CTRL_0_REG;
++		reg_val = ADC_FIFO_OVER_INT_EN
++                        | ADC_FIFO_UNDR_INT_EN
++                        | ADC_FIFO_TH
++			| (fcid << ADC_FIFO_ID_SHIFT)
++			| ADC_FIFO_DEPTH;
++		break;
++	case 1:
++		reg = ADC_FIFO_CTRL_1_REG;
++		reg_val = ADC_FIFO_OVER_INT_EN
++                        | ADC_FIFO_UNDR_INT_EN
++                        | ADC_FIFO_TH
++			| (fcid << ADC_FIFO_ID_SHIFT)
++			| ADC_FIFO_DEPTH;
++		break;
++	case 2:
++		reg = ADC_FIFO_CTRL_2_REG;
++		reg_val = ADC_FIFO_OVER_INT_EN
++                        | ADC_FIFO_UNDR_INT_EN
++                        | ADC_FIFO_TH
++			| (fcid << ADC_FIFO_ID_SHIFT)
++			| ADC_FIFO_DEPTH;
++		break;
++		break;
++	case 3:
++		reg = ADC_FIFO_CTRL_3_REG;
++		reg_val = ADC_FIFO_OVER_INT_EN
++                        | ADC_FIFO_UNDR_INT_EN
++                        | ADC_FIFO_TH
++			| (fcid << ADC_FIFO_ID_SHIFT)
++			| ADC_FIFO_DEPTH;
++		break;
++		break;
++	default:
++		pr_err("%s: invalid fifo NO = %d.\n",
++			__func__, fid);
++		return -1;
++	}
++
++	amba_writel(reg, reg_val);
++
++	amba_writel(ADC_FIFO_CTRL_REG, ADC_FIFO_CONTROL_CLEAR);
++	return 0;
++}
++
++static void ambarella_adc_enable(void)
++{
++	/* select adc scaler as clk_adc and power up adc */
++	amba_writel(ADC16_CTRL_REG, 0);
++
++#if (ADC_SUPPORT_SLOT == 1)
++	/* soft reset adc controller, set slot, and then enable it */
++	amba_writel(ADC_CONTROL_REG, ADC_CONTROL_RESET);
++	amba_writel(ADC_SLOT_NUM_REG, 0x0);
++	amba_writel(ADC_SLOT_PERIOD_REG, 0xffff);
++	amba_writel(ADC_SLOT_CTRL_0_REG, 0x0fff);
++#endif
++        //test fifo read in fifo_0
++        if(ambarella_adc->fifo_mode){
++                ambarella_adc_fifo_ctrl(0,1);
++        }
++	amba_setbitsl(ADC_ENABLE_REG, ADC_CONTROL_ENABLE);
++}
++
++static void ambarella_adc_disable(void)
++{
++	amba_clrbitsl(ADC_ENABLE_REG, ADC_CONTROL_ENABLE);
++	amba_writel(ADC16_CTRL_REG, ADC_CTRL_SCALER_POWERDOWN | ADC_CTRL_POWERDOWN);
++}
++
++static void ambarella_adc_start(void)
++{
++	amba_setbitsl(ADC_CONTROL_REG, ADC_CONTROL_MODE | ADC_CONTROL_START);
++}
++
++static void ambarella_adc_stop(void)
++{
++	amba_clrbitsl(ADC_CONTROL_REG, ADC_CONTROL_MODE | ADC_CONTROL_START);
++}
++
++static void ambarella_adc_reset(void)
++{
++        ambarella_adc_disable();
++        ambarella_adc_enable();
++        ambarella_adc_start();
++}
++
++struct ambadc_client *ambarella_adc_register_client(struct device *dev,
++		u32 mode, ambadc_client_callback callback)
++{
++	struct ambadc_host *amb_adc = ambarella_adc;
++	struct ambadc_client *client;
++
++	if (!dev || (mode == AMBADC_CONTINUOUS && !callback)) {
++		dev_err(dev, "dev or callback missing\n");
++		return NULL;
++	}
++
++	client = kzalloc(sizeof(struct ambadc_client), GFP_KERNEL);
++	if (!client) {
++		dev_err(dev, "no memory for adc client\n");
++		return NULL;
++	}
++
++	client->dev = dev;
++	client->dev->parent = amb_adc->dev;
++	client->mode = mode;
++	client->callback = callback;
++	client->host = amb_adc;
++
++	mutex_lock(&client_mutex);
++	list_add_tail(&client->node, &client_list);
++	mutex_unlock(&client_mutex);
++
++	if (mode == AMBADC_CONTINUOUS) {
++		amb_adc->keep_start = true;
++		ambarella_adc_start();
++
++		if (amb_adc->polling_mode) {
++			queue_delayed_work(system_wq,
++				&amb_adc->work, msecs_to_jiffies(20));
++		}
++	}
++
++	return client;
++}
++EXPORT_SYMBOL(ambarella_adc_register_client);
++
++void ambarella_adc_unregister_client(struct ambadc_client *client)
++{
++	struct ambadc_host *amb_adc = client->host;
++	struct ambadc_client *_client;
++	u32 keep_start = 0;
++
++	mutex_lock(&client_mutex);
++
++	list_del(&client->node);
++	kfree(client);
++
++	list_for_each_entry(_client, &client_list, node) {
++		if (_client->mode == AMBADC_CONTINUOUS) {
++			keep_start = 1;
++			break;
++		}
++	}
++
++	mutex_unlock(&client_mutex);
++
++	if (keep_start == 0) {
++		amb_adc->keep_start = false;
++		ambarella_adc_stop();
++	}
++}
++EXPORT_SYMBOL(ambarella_adc_unregister_client);
++
++int ambarella_adc_read_level(u32 ch)
++{
++	struct ambadc_host *amb_adc = ambarella_adc;
++	int data=0;
++        u32 i,count;
++
++	if (ch >= ADC_NUM_CHANNELS)
++		return -EINVAL;
++
++	if (amb_adc == NULL)
++		return -ENODEV;
++
++	if (!amb_adc->keep_start)
++		ambarella_adc_start();
++
++        if(!ambarella_adc->fifo_mode){
++                data = amba_readl(ADC_DATA_REG(ch));
++        } else {
++                count = 0x7ff & amba_readl(ADC_FIFO_STATUS_0_REG);
++                if(count > 4)
++			count -= 4;
++
++                for(i=0;i<count;i++){
++                        data = amba_readl(ADC_FIFO_DATA0_REG + i*4);
++                        // printk("call back [0x%x]=0x%x,count=0x%x,0x%x\n",
++                        //  (ADC_FIFO_DATA0_REG + i*4),data,count,ch);
++                }
++                //data = data/count;
++        }
++
++	if (!amb_adc->keep_start)
++		ambarella_adc_stop();
++
++	return data;
++}
++EXPORT_SYMBOL(ambarella_adc_read_level);
++
++int ambarella_adc_set_threshold(struct ambadc_client *client,
++		u32 ch, u32 low, u32 high)
++{
++	struct ambadc_client *_client;
++	int value, rval = 0;
++
++	if (ch >= ADC_NUM_CHANNELS)
++		return -EINVAL;
++
++	if (client->mode != AMBADC_CONTINUOUS) {
++		dev_err(client->dev, "Invalid adc mode: %d\n", client->mode);
++		return -EINVAL;
++	}
++
++	/* interrupt will be happened when level < low OR level > high */
++	value = ADC_EN_HI(!!high) | ADC_EN_LO(!!low) |
++		    ADC_VAL_HI(high) | ADC_VAL_LO(low);
++
++	mutex_lock(&client_mutex);
++
++	/* it's not allowed that more than one clients want to set different
++	 * threshold for the same adc channel. */
++	list_for_each_entry(_client, &client_list, node) {
++		if (_client == client)
++			continue;
++		/* check if other clients set the threshold for this channel */
++		if (_client->threshold[ch] && (_client->threshold[ch] != value)) {
++			if (value == 0) {
++				rval = 0;
++				goto exit;
++			} else {
++				rval = -EBUSY;
++				goto exit;
++			}
++		}
++	}
++
++        if(!ambarella_adc->fifo_mode)
++                amba_writel(ADC_CHAN_INTR_REG(ch), value);
++
++exit:
++	if (rval == 0)
++		client->threshold[ch] = value;
++
++	mutex_unlock(&client_mutex);
++
++	return rval;
++}
++EXPORT_SYMBOL(ambarella_adc_set_threshold);
++
++static void ambarella_adc_client_callback(u32 ch)
++{
++	struct ambadc_client *client;
++	u32 data;
++
++	data = ambarella_adc_read_level(ch);
++
++	list_for_each_entry(client, &client_list, node) {
++		if (client->callback && client->threshold[ch])
++			client->callback(client, ch, data);
++	}
++}
++
++static void ambarella_adc_polling_work(struct work_struct *work)
++{
++	struct ambadc_host *amb_adc;
++	u32 i;
++
++	amb_adc = container_of(work, struct ambadc_host, work.work);
++
++	for (i = 0; i < ADC_NUM_CHANNELS; i++)
++		ambarella_adc_client_callback(i);
++
++	if (amb_adc->keep_start) {
++		queue_delayed_work(system_wq,
++				&amb_adc->work, msecs_to_jiffies(20));
++	}
++}
++
++static irqreturn_t ambarella_adc_irq(int irq, void *dev_id)
++{
++	u32 i, int_src,rval,chanNo;
++        struct ambadc_host *amb_adc = dev_id;
++
++        chanNo = 0;
++        if(!amb_adc->fifo_mode){
++                int_src = amba_readl(ADC_DATA_INTR_TABLE_REG);
++                amba_writel(ADC_DATA_INTR_TABLE_REG, int_src);
++                chanNo = int_src;
++        }else{
++                rval = amba_readl(ADC_CTRL_INTR_TABLE_REG);
++                if(rval){
++                        ambarella_adc_reset();
++                        return IRQ_HANDLED;
++                }
++                rval = amba_readl(ADC_FIFO_INTR_TABLE_REG);
++                amba_writel(ADC_FIFO_INTR_TABLE_REG, rval);
++
++                for(i=0;i<ADC_FIFO_NUMBER;i++){
++                        if((rval & (1 << i)) == 0)
++                                continue;
++                        rval = amba_readl(ADC_FIFO_CTRL_X_REG(i));
++                        rval = (rval & (0x0000f000)) >> 12;
++                        chanNo = 1 << rval;
++                }
++        }
++
++        for (i = 0; i < ADC_NUM_CHANNELS; i++) {
++                if ((chanNo & (1 << i)) == 0)
++                        continue;
++
++                ambarella_adc_client_callback(i);
++        }
++
++	return IRQ_HANDLED;
++}
++
++static int ambarella_adc_probe(struct platform_device *pdev)
++{
++	struct ambadc_host *amb_adc;
++	struct device_node *np = pdev->dev.of_node;
++	int ret = 0;
++
++	amb_adc = devm_kzalloc(&pdev->dev,
++			sizeof(struct ambadc_host), GFP_KERNEL);
++	if (!amb_adc) {
++		dev_err(&pdev->dev, "Failed to allocate memory!\n");
++		return -ENOMEM;
++	}
++
++	ret = of_property_read_u32(np, "clock-frequency", &amb_adc->clk);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "Get clock-frequency failed!\n");
++		return -ENODEV;
++	}
++
++        //amb_adc->fifo_mode=1;//test fifo mode
++
++	amb_adc->polling_mode = !!of_find_property(np, "amb,polling-mode", NULL);
++	if (amb_adc->polling_mode) {
++		INIT_DELAYED_WORK(&amb_adc->work, ambarella_adc_polling_work);
++	} else {
++		amb_adc->irq = platform_get_irq(pdev, 0);
++		if (amb_adc->irq < 0) {
++			dev_err(&pdev->dev, "Can not get irq !\n");
++			return -ENXIO;
++		}
++
++		ret = devm_request_irq(&pdev->dev, amb_adc->irq,
++				ambarella_adc_irq, IRQF_TRIGGER_HIGH,
++				dev_name(&pdev->dev), amb_adc);
++		if (ret < 0) {
++			dev_err(&pdev->dev, "Can not request irq %d!\n", amb_adc->irq);
++			return -ENXIO;
++		}
++	}
++
++
++	ret = clk_set_rate(clk_get(NULL, "gclk_adc"), amb_adc->clk);
++	if (ret < 0)
++		return ret;
++
++	amb_adc->dev = &pdev->dev;
++
++	ambarella_adc = amb_adc;
++
++	ambarella_adc_enable();
++        if(amb_adc->fifo_mode == 1){
++		amb_adc->keep_start = true;
++		ambarella_adc_start();
++	}
++
++	ret = device_create_file(&pdev->dev, &dev_attr_adcsys);
++	if (ret != 0) {
++		dev_err(&pdev->dev, "can not create file : %d\n", ret);
++		return ret;
++	}
++
++	platform_set_drvdata(pdev, amb_adc);
++
++	dev_info(&pdev->dev, "Ambarella ADC driver init\n");
++
++	return 0;
++}
++
++static int ambarella_adc_remove(struct platform_device *pdev)
++{
++	device_remove_file(&pdev->dev, &dev_attr_adcsys);
++	ambarella_adc_disable();
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_adc_suspend(struct platform_device *pdev,
++				 pm_message_t state)
++{
++	ambarella_adc_disable();
++	return 0;
++}
++
++static int ambarella_adc_resume(struct platform_device *pdev)
++{
++	struct ambadc_host *amb_adc = platform_get_drvdata(pdev);
++	struct ambadc_client *client;
++	u32 ch;
++
++	clk_set_rate(clk_get(NULL, "gclk_adc"), amb_adc->clk);
++	ambarella_adc_enable();
++
++	if (amb_adc->keep_start)
++		ambarella_adc_start();
++
++        if(ambarella_adc->fifo_mode)
++		goto exit;
++
++	for (ch = 0; ch < ADC_NUM_CHANNELS; ch++) {
++		list_for_each_entry(client, &client_list, node) {
++			if (client->threshold[ch] == 0)
++				continue;
++			amba_writel(ADC_CHAN_INTR_REG(ch), client->threshold[ch]);
++		}
++	}
++
++exit:
++	return 0;
++}
++#endif
++
++static const struct of_device_id ambarella_adc_dt_ids[] = {
++	{.compatible = "ambarella,adc", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_adc_dt_ids);
++
++static struct platform_driver ambarella_adc_driver = {
++	.driver	= {
++		.name	= "ambarella-adc",
++		.owner	= THIS_MODULE,
++		.of_match_table	= ambarella_adc_dt_ids,
++	},
++	.probe		= ambarella_adc_probe,
++	.remove		= ambarella_adc_remove,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_adc_suspend,
++	.resume		= ambarella_adc_resume,
++#endif
++};
++
++module_platform_driver(ambarella_adc_driver);
++MODULE_AUTHOR("BingLiang Hu <blhu@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella ADC Driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/arch/arm/mach-ambarella/clk.c b/arch/arm/mach-ambarella/clk.c
+new file mode 100644
+index 00000000..d06365f0
+--- /dev/null
++++ b/arch/arm/mach-ambarella/clk.c
+@@ -0,0 +1,1232 @@
++/*
++ * arch/arm/mach-ambarella/clk.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/list.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++#include <linux/io.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/clk.h>
++#include <asm/uaccess.h>
++#include <mach/hardware.h>
++#include <plat/iav_helper.h>
++#include <plat/sd.h>
++#include <plat/clk.h>
++
++/* ==========================================================================*/
++static LIST_HEAD(ambarella_all_clocks);
++DEFINE_SPINLOCK(ambarella_clock_lock);
++struct ambarella_service pll_service;
++
++/* ==========================================================================*/
++static unsigned int ambarella_clk_ref_freq = REF_CLK_FREQ;
++
++unsigned int ambarella_clk_get_ref_freq(void)
++{
++	return ambarella_clk_ref_freq;
++}
++EXPORT_SYMBOL(ambarella_clk_get_ref_freq);
++
++/* ==========================================================================*/
++
++struct clk_ops ambarella_rct_scaler_ops = {
++	.enable		= NULL,
++	.disable	= NULL,
++	.get_rate	= ambarella_rct_scaler_get_rate,
++	.round_rate	= NULL,
++	.set_rate	= ambarella_rct_scaler_set_rate,
++	.set_parent	= NULL,
++};
++EXPORT_SYMBOL(ambarella_rct_scaler_ops);
++
++struct clk_ops ambarella_rct_pll_ops = {
++	.enable		= ambarella_rct_clk_enable,
++	.disable	= ambarella_rct_clk_disable,
++	.get_rate	= ambarella_rct_clk_get_rate,
++	.round_rate	= NULL,
++	.set_rate	= ambarella_rct_clk_set_rate,
++	.set_parent	= NULL,
++};
++EXPORT_SYMBOL(ambarella_rct_pll_ops);
++
++struct clk_ops ambarella_rct_adj_ops = {
++	.enable		= ambarella_rct_clk_enable,
++	.disable	= ambarella_rct_clk_disable,
++	.get_rate	= ambarella_rct_clk_get_rate,
++	.round_rate	= NULL,
++	.set_rate	= ambarella_rct_clk_adj_rate,
++	.set_parent	= NULL,
++};
++EXPORT_SYMBOL(ambarella_rct_adj_ops);
++
++/* ==========================================================================*/
++
++int ambarella_rct_clk_enable(struct clk *c)
++{
++	union ctrl_reg_u ctrl_reg;
++
++	if (c->ctrl_reg == -1) {
++		return -1;
++	}
++
++	ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++	ctrl_reg.s.power_down = 0;
++	ctrl_reg.s.halt_vco = 0;
++	ctrl_reg.s.write_enable = 1;
++	amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++
++	ctrl_reg.s.write_enable	= 0;
++	amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++
++	c->rate = ambarella_rct_clk_get_rate(c);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_clk_enable);
++
++int ambarella_rct_clk_disable(struct clk *c)
++{
++	union ctrl_reg_u ctrl_reg;
++
++	if (c->ctrl_reg == -1) {
++		return -1;
++	}
++
++	ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++	ctrl_reg.s.power_down = 1;
++	ctrl_reg.s.halt_vco = 1;
++	ctrl_reg.s.write_enable = 1;
++	amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++
++	ctrl_reg.s.write_enable	= 0;
++	amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++
++	c->rate = ambarella_rct_clk_get_rate(c);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_clk_disable);
++
++
++/* ==========================================================================*/
++unsigned long ambarella_rct_scaler_get_rate(struct clk *c)
++{
++	u32 parent_rate, divider;
++
++	if (!c->parent || !c->parent->ops || !c->parent->ops->get_rate)
++		parent_rate = ambarella_clk_get_ref_freq();
++	else
++		parent_rate = c->parent->ops->get_rate(c->parent);
++
++	if (c->divider) {
++		c->rate = parent_rate / c->divider;
++		return c->rate;
++	} else if (c->post_reg != -1) {
++		divider = amba_rct_readl(c->post_reg);
++		if (c->extra_scaler == 1) {
++			divider >>= 4;
++			divider++;
++		}
++		if (divider) {
++			c->rate = parent_rate / divider;
++			return c->rate;
++		}
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_scaler_get_rate);
++
++int ambarella_rct_scaler_set_rate(struct clk *c, unsigned long rate)
++{
++	u32 parent_rate, divider, post_scaler;
++
++	if (!rate)
++		return -1;
++
++	BUG_ON(c->post_reg == -1 || !c->max_divider);
++
++	if (!c->parent || !c->parent->ops || !c->parent->ops->get_rate)
++		parent_rate = ambarella_clk_get_ref_freq();
++	else
++		parent_rate = c->parent->ops->get_rate(c->parent);
++
++	if (c->divider)
++		rate *= c->divider;
++
++	divider = (parent_rate + rate - 1) / rate;
++	if (!divider)
++		return -1;
++
++	post_scaler = min(divider, c->max_divider);
++	if (c->extra_scaler == 1) {
++		post_scaler--;
++		post_scaler <<= 4;
++		amba_rct_writel_en(c->post_reg, post_scaler);
++	} else {
++		amba_rct_writel(c->post_reg, post_scaler);
++	}
++
++	c->rate = ambarella_rct_scaler_get_rate(c);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_scaler_set_rate);
++
++unsigned long ambarella_rct_clk_get_rate(struct clk *c)
++{
++	u32 pre_scaler, post_scaler, intp, sdiv, sout;
++	u64 dividend, divider, frac;
++	union ctrl_reg_u ctrl_reg;
++	union frac_reg_u frac_reg;
++
++	BUG_ON(c->ctrl_reg == -1 || c->frac_reg == -1);
++
++	ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++	if ((ctrl_reg.s.power_down == 1) || (ctrl_reg.s.halt_vco == 1)) {
++		c->rate = 0;
++		return c->rate;
++	}
++
++	frac_reg.w = amba_rct_readl(c->frac_reg);
++
++	if (c->pres_reg != -1) {
++		pre_scaler = amba_rct_readl(c->pres_reg);
++		if (c->extra_scaler == 1) {
++			pre_scaler >>= 4;
++			pre_scaler++;
++		}
++	} else {
++		pre_scaler = 1;
++	}
++
++	if (c->post_reg != -1) {
++		post_scaler = amba_rct_readl(c->post_reg);
++		if (c->extra_scaler == 1) {
++			post_scaler >>= 4;
++			post_scaler++;
++		}
++	} else {
++		post_scaler = 1;
++	}
++
++	if (ctrl_reg.s.bypass || ctrl_reg.s.force_bypass) {
++		c->rate = ambarella_clk_get_ref_freq() / pre_scaler / post_scaler;
++		return c->rate;
++	}
++
++	intp = ctrl_reg.s.intp + 1;
++	sdiv = ctrl_reg.s.sdiv + 1;
++	sout = ctrl_reg.s.sout + 1;
++
++	dividend = (u64)ambarella_clk_get_ref_freq();
++	dividend *= (u64)intp;
++	dividend *= (u64)sdiv;
++	if (ctrl_reg.s.frac_mode) {
++		if (frac_reg.s.nega) {
++			/* Negative */
++			frac = (0x80000000 - frac_reg.s.frac);
++			frac = (ambarella_clk_get_ref_freq() * frac * sdiv);
++			frac >>= 32;
++			dividend = dividend - frac;
++		} else {
++			/* Positive */
++			frac = frac_reg.s.frac;
++			frac = (ambarella_clk_get_ref_freq() * frac * sdiv);
++			frac >>= 32;
++			dividend = dividend + frac;
++		}
++	}
++
++	divider = pre_scaler * sout * post_scaler;
++	if (c->divider)
++		divider *= c->divider;
++
++	if (divider == 0) {
++		c->rate = 0;
++		return c->rate;
++	}
++
++	AMBCLK_DO_DIV(dividend, divider);
++	c->rate = dividend;
++
++	return c->rate;
++}
++EXPORT_SYMBOL(ambarella_rct_clk_get_rate);
++
++
++int ambarella_rct_clk_adj_rate(struct clk *c, unsigned long rate)
++{
++	union ctrl_reg_u ctrl_reg;
++	u32 curr_rate;
++	u32 IntStepPllOut24MHz;
++	u32 TargetIntp;
++
++	/* get current PLL control registers' values */
++	ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++
++	if (ctrl_reg.s.sdiv >= ctrl_reg.s.sout) {
++		while (ctrl_reg.s.sdiv > ctrl_reg.s.sout) {
++			ctrl_reg.s.sdiv--;
++			amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++		}
++		IntStepPllOut24MHz = 1;
++	} else {
++		IntStepPllOut24MHz = (ctrl_reg.s.sout + 1) / (ctrl_reg.s.sdiv + 1);
++	}
++
++	curr_rate = ambarella_rct_clk_get_rate(c);
++	TargetIntp = rate * (ctrl_reg.s.sout + 1) / ((ctrl_reg.s.sdiv + 1) * REF_CLK_FREQ) - 1;
++
++	if (curr_rate > rate) {
++		/* decrease the frequency */
++		while (curr_rate > rate && ctrl_reg.s.intp > 0) {
++			if (ctrl_reg.s.intp - TargetIntp >= IntStepPllOut24MHz)
++				ctrl_reg.s.intp -= IntStepPllOut24MHz;
++			else
++				ctrl_reg.s.intp--;
++
++			amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
++			curr_rate = ambarella_rct_clk_get_rate(c);
++		}
++	} else {
++		/* increase the frequency */
++		if (TargetIntp > 123)
++			TargetIntp = 123;
++
++		while (curr_rate < rate && ctrl_reg.s.intp < 123) {
++			if (TargetIntp - ctrl_reg.s.intp >= IntStepPllOut24MHz)
++				ctrl_reg.s.intp += IntStepPllOut24MHz;
++			else
++				ctrl_reg.s.intp++;
++
++			amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
++			curr_rate = ambarella_rct_clk_get_rate(c);
++		}
++
++		if (curr_rate > rate && ctrl_reg.s.intp > 6) {
++			/* decrease the frequency so that is it is just below expected */
++			ctrl_reg.s.intp--;
++			amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
++		}
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_clk_adj_rate);
++
++/* ==========================================================================*/
++struct clk *clk_get_sys(const char *dev_id, const char *con_id)
++{
++	struct clk *p;
++	struct clk *clk = ERR_PTR(-ENOENT);
++
++	spin_lock(&ambarella_clock_lock);
++	list_for_each_entry(p, &ambarella_all_clocks, list) {
++		if (dev_id && (strcmp(p->name, dev_id) == 0)) {
++			clk = p;
++			break;
++		}
++		if (con_id && (strcmp(p->name, con_id) == 0)) {
++			clk = p;
++			break;
++		}
++	}
++	spin_unlock(&ambarella_clock_lock);
++
++	return clk;
++}
++EXPORT_SYMBOL(clk_get_sys);
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++	struct clk *p;
++	struct clk *clk = ERR_PTR(-ENOENT);
++
++	if (id == NULL) {
++		return clk;
++	}
++
++	spin_lock(&ambarella_clock_lock);
++	list_for_each_entry(p, &ambarella_all_clocks, list) {
++		if (strcmp(p->name, id) == 0) {
++			clk = p;
++			break;
++		}
++	}
++	spin_unlock(&ambarella_clock_lock);
++
++	return clk;
++}
++EXPORT_SYMBOL(clk_get);
++
++void clk_put(struct clk *clk)
++{
++}
++EXPORT_SYMBOL(clk_put);
++
++int clk_enable(struct clk *clk)
++{
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return -EINVAL;
++	}
++
++	clk_enable(clk->parent);
++
++	spin_lock(&ambarella_clock_lock);
++	if (clk->ops && clk->ops->enable) {
++		(clk->ops->enable)(clk);
++	}
++	spin_unlock(&ambarella_clock_lock);
++
++	return 0;
++}
++EXPORT_SYMBOL(clk_enable);
++
++void clk_disable(struct clk *clk)
++{
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return;
++	}
++
++	spin_lock(&ambarella_clock_lock);
++	if (clk->ops && clk->ops->disable) {
++		(clk->ops->disable)(clk);
++	}
++	spin_unlock(&ambarella_clock_lock);
++
++	clk_disable(clk->parent);
++}
++EXPORT_SYMBOL(clk_disable);
++
++unsigned long clk_get_rate(struct clk *clk)
++{
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return 0;
++	}
++
++	if (clk->ops != NULL && clk->ops->get_rate != NULL) {
++		return (clk->ops->get_rate)(clk);
++	}
++
++	if (clk->parent != NULL) {
++		return clk_get_rate(clk->parent);
++	}
++
++	return clk->rate;
++}
++EXPORT_SYMBOL(clk_get_rate);
++
++long clk_round_rate(struct clk *clk, unsigned long rate)
++{
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return rate;
++	}
++
++	if (clk->ops && clk->ops->round_rate) {
++		return (clk->ops->round_rate)(clk, rate);
++	}
++
++	return rate;
++}
++EXPORT_SYMBOL(clk_round_rate);
++
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++	int ret;
++
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return -EINVAL;
++	}
++
++	if ((clk->ops == NULL) || (clk->ops->set_rate == NULL)) {
++		return -EINVAL;
++	}
++
++	spin_lock(&ambarella_clock_lock);
++	ret = (clk->ops->set_rate)(clk, rate);
++	spin_unlock(&ambarella_clock_lock);
++
++	return ret;
++}
++EXPORT_SYMBOL(clk_set_rate);
++
++struct clk *clk_get_parent(struct clk *clk)
++{
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return ERR_PTR(-EINVAL);
++	}
++
++	return clk->parent;
++}
++EXPORT_SYMBOL(clk_get_parent);
++
++int clk_set_parent(struct clk *clk, struct clk *parent)
++{
++	int ret = 0;
++
++	if (IS_ERR(clk) || (clk == NULL)) {
++		return -EINVAL;
++	}
++
++	spin_lock(&ambarella_clock_lock);
++	if (clk->ops && clk->ops->set_parent) {
++		ret = (clk->ops->set_parent)(clk, parent);
++	}
++	spin_unlock(&ambarella_clock_lock);
++
++	return ret;
++}
++EXPORT_SYMBOL(clk_set_parent);
++
++int ambarella_clk_add(struct clk *clk)
++{
++	struct clk *p;
++
++	if (IS_ERR(clk) || (clk == NULL))
++		return -EINVAL;
++
++	spin_lock(&ambarella_clock_lock);
++	list_for_each_entry(p, &ambarella_all_clocks, list) {
++		if (clk == p) {
++			pr_err("clk %s is existed\n", clk->name);
++			spin_unlock(&ambarella_clock_lock);
++			return -EEXIST;
++		}
++	}
++	list_add(&clk->list, &ambarella_all_clocks);
++	spin_unlock(&ambarella_clock_lock);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_clk_add);
++
++/* ==========================================================================*/
++#if defined(CONFIG_AMBARELLA_PLL_PROC)
++static int ambarella_clock_proc_show(struct seq_file *m, void *v)
++{
++	int retlen = 0;
++	struct clk *p;
++
++	retlen += seq_printf(m, "\nClock Information:\n");
++	spin_lock(&ambarella_clock_lock);
++	list_for_each_entry_reverse(p, &ambarella_all_clocks, list) {
++		retlen += seq_printf(m, "\t%s:\t%lu Hz\n",
++			p->name, p->ops->get_rate(p));
++	}
++	spin_unlock(&ambarella_clock_lock);
++
++	return retlen;
++}
++
++static int ambarella_clock_proc_write(struct file *file,
++	const char __user *buffer, size_t count, loff_t *ppos)
++{
++	struct clk *gclk;
++	char *buf, clk_name[32];
++	int freq, rval = count;
++
++	pr_warn("!!!DANGEROUS!!! You must know what you are doning!\n");
++
++	buf = kmalloc(count, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++
++	if (copy_from_user(buf, buffer, count)) {
++		rval = -EFAULT;
++		goto exit;
++	}
++
++	sscanf(buf, "%s %d", clk_name, &freq);
++
++	gclk = clk_get(NULL, clk_name);
++	if (IS_ERR(gclk)) {
++		pr_err("Invalid clk name\n");
++		rval = -EINVAL;
++		goto exit;
++	}
++
++	clk_set_rate(gclk, freq);
++
++exit:
++	kfree(buf);
++	return rval;
++}
++
++static int ambarella_clock_proc_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, ambarella_clock_proc_show, PDE_DATA(inode));
++}
++
++static const struct file_operations proc_clock_fops = {
++	.open = ambarella_clock_proc_open,
++	.read = seq_read,
++	.llseek = seq_lseek,
++	.write = ambarella_clock_proc_write,
++};
++#endif
++
++/* ==========================================================================*/
++int __init ambarella_clk_init(void)
++{
++	int ret_val = 0;
++
++#if defined(CONFIG_AMBARELLA_PLL_PROC)
++	proc_create_data("clock", S_IRUGO, get_ambarella_proc_dir(),
++		&proc_clock_fops, NULL);
++#endif
++
++	return ret_val;
++}
++
++/* ==========================================================================*/
++
++static struct clk pll_out_core = {
++	.parent		= NULL,
++	.name		= "pll_out_core",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= PLL_CORE_CTRL_REG,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= PLL_CORE_FRAC_REG,
++	.ctrl2_reg	= PLL_CORE_CTRL2_REG,
++	.ctrl3_reg	= PLL_CORE_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 6,
++	.divider	= 0,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.table		= ambarella_pll_int_table,
++	.table_size	= ARRAY_SIZE(ambarella_pll_int_table),
++	.ops		= &ambarella_rct_adj_ops,
++};
++
++static struct clk gclk_core = {
++	.parent		= &pll_out_core,
++	.name		= "gclk_core",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++#if ((CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E))
++	.post_reg	= SCALER_CORE_POST_REG,
++#else
++	.post_reg	= -1,
++#endif
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++#if ((CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E))
++	.divider	= 0,
++	.max_divider	= (1 << 4) - 1,
++#else
++	.divider	= 2,
++	.max_divider	= 0,
++#endif
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_ahb = {
++	.parent		= &gclk_core,
++	.name		= "gclk_ahb",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++#if (CHIP_REV == A5S)
++	.divider	= 1,
++#else
++	.divider	= 2,
++#endif
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_apb = {
++	.parent		= &gclk_ahb,
++	.name		= "gclk_apb",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 2,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_ddr = {
++	.parent		= NULL,
++	.name		= "gclk_ddr",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= PLL_DDR_CTRL_REG,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= PLL_DDR_FRAC_REG,
++	.ctrl2_reg	= PLL_DDR_CTRL2_REG,
++	.ctrl3_reg	= PLL_DDR_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 5,
++	.divider	= 2,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.table		= ambarella_pll_int_table,
++	.table_size	= ARRAY_SIZE(ambarella_pll_int_table),
++	.ops		= &ambarella_rct_adj_ops,
++};
++
++/* ==========================================================================*/
++#if defined(CONFIG_PLAT_AMBARELLA_CORTEX)
++static struct clk gclk_cortex = {
++	.parent		= NULL,
++	.name		= "gclk_cortex",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= PLL_CORTEX_CTRL_REG,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= PLL_CORTEX_FRAC_REG,
++	.ctrl2_reg	= PLL_CORTEX_CTRL2_REG,
++	.ctrl3_reg	= PLL_CORTEX_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 2,
++	.divider	= 0,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.table		= ambarella_pll_int_table,
++	.table_size	= ARRAY_SIZE(ambarella_pll_int_table),
++	.ops		= &ambarella_rct_adj_ops,
++};
++static struct clk gclk_axi = {
++	.parent		= &gclk_cortex,
++	.name		= "gclk_axi",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 3,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++#if defined(CONFIG_HAVE_ARM_TWD)
++static struct clk clk_smp_twd = {
++	.parent		= &gclk_axi,
++	.name		= "smp_twd",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 1,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++#endif
++#endif
++
++static struct clk gclk_idsp = {
++	.parent		= NULL,
++	.name		= "gclk_idsp",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= PLL_IDSP_CTRL_REG,
++	.pres_reg	= -1,
++	.post_reg	= SCALER_IDSP_POST_REG,
++	.frac_reg	= PLL_IDSP_FRAC_REG,
++	.ctrl2_reg	= PLL_IDSP_CTRL2_REG,
++	.ctrl3_reg	= PLL_IDSP_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 4,
++	.divider	= 0,
++	.max_divider	= (1 << 4) - 1,
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	.extra_scaler	= 1,
++#else
++	.extra_scaler	= 0,
++#endif
++	.table		= ambarella_pll_int_table,
++	.table_size	= ARRAY_SIZE(ambarella_pll_int_table),
++	.ops		= &ambarella_rct_pll_ops,
++};
++
++#ifdef CONFIG_AMBARELLA_CALC_PLL
++static struct clk gclk_so = {
++	.parent		= NULL,
++	.name		= "gclk_so",
++	.rate		= 0,
++	.frac_mode	= 1,
++	.ctrl_reg	= PLL_SENSOR_CTRL_REG,
++	.pres_reg	= SCALER_SENSOR_PRE_REG,
++	.post_reg	= SCALER_SENSOR_POST_REG,
++	.frac_reg	= PLL_SENSOR_FRAC_REG,
++	.ctrl2_reg	= PLL_SENSOR_CTRL2_REG,
++	.ctrl3_reg	= PLL_SENSOR_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 3,
++	.divider	= 0,
++	.max_divider	= (1 << 4) - 1,
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	.max_divider	= (1 << 4) - 1,
++	.extra_scaler	= 1,
++#else
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++#endif
++	.ops		= &ambarella_rct_pll_ops,
++};
++
++static struct clk gclk_vo = {
++	.parent		= NULL,
++	.name		= "gclk_vo",
++	.rate		= 0,
++	.frac_mode	= 1,
++	.ctrl_reg	= PLL_HDMI_CTRL_REG,
++	.pres_reg	= SCALER_HDMI_PRE_REG,
++	.post_reg	= -1,
++	.frac_reg	= PLL_HDMI_FRAC_REG,
++	.ctrl2_reg	= PLL_HDMI_CTRL2_REG,
++#if (CHIP_REV == S2E) || (CHIP_REV == S3L)
++	.ctrl2_val	= 0x3f770b00,
++#endif
++	.ctrl3_reg	= PLL_HDMI_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 8,
++	.divider	= 10,
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	.max_divider	= (1 << 4) - 1,
++	.extra_scaler	= 1,
++#else
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++#endif
++	.ops		= &ambarella_rct_pll_ops,
++};
++
++static struct clk gclk_vo2 = {
++	.parent		= NULL,
++	.name		= "gclk_vo2",
++	.rate		= 0,
++	.frac_mode	= 1,
++	.ctrl_reg	= PLL_VIDEO2_CTRL_REG,
++	.pres_reg	= SCALER_VIDEO2_PRE_REG,
++	.post_reg	= SCALER_VIDEO2_POST_REG,
++	.frac_reg	= PLL_VIDEO2_FRAC_REG,
++	.ctrl2_reg	= PLL_VIDEO2_CTRL2_REG,
++	.ctrl3_reg	= PLL_VIDEO2_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 0,
++	.divider	= 0,
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	.max_divider	= (1 << 4) - 1,
++	.extra_scaler	= 1,
++#else
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++#endif
++	.ops		= &ambarella_rct_pll_ops,
++};
++#endif
++
++static struct clk gclk_uart = {
++#if (CHIP_REV == S2E)
++	.parent		= &gclk_idsp,
++#else
++	.parent		= NULL,
++#endif
++	.name		= "gclk_uart",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= CG_UART_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 24) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_audio = {
++	.parent		= NULL,
++	.name		= "gclk_audio",
++	.rate		= 0,
++	.frac_mode	= 1,
++	.ctrl_reg	= PLL_AUDIO_CTRL_REG,
++	.pres_reg	= SCALER_AUDIO_PRE_REG,
++	.post_reg	= SCALER_AUDIO_POST_REG,
++	.frac_reg	= PLL_AUDIO_FRAC_REG,
++	.ctrl2_reg	= PLL_AUDIO_CTRL2_REG,
++	.ctrl3_reg	= PLL_AUDIO_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 7,
++	.divider	= 0,
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	.max_divider	= (1 << 4) - 1,
++	.extra_scaler	= 1,
++#else
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++#endif
++	.table		= ambarella_pll_frac_table,
++	.table_size	= ARRAY_SIZE(ambarella_pll_frac_table),
++	.ops		= &ambarella_rct_pll_ops,
++};
++
++#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++static struct clk pll_out_sd = {
++	.parent		= NULL,
++	.name		= "pll_out_sd",
++	.rate		= 0,
++	.frac_mode	= 1,
++	.ctrl_reg	= PLL_SD_CTRL_REG,
++	.pres_reg	= -1,
++	.post_reg	= -1,
++	.frac_reg	= PLL_SD_FRAC_REG,
++	.ctrl2_reg	= PLL_SD_CTRL2_REG,
++	.ctrl3_reg	= PLL_SD_CTRL3_REG,
++	.lock_reg	= PLL_LOCK_REG,
++	.lock_bit	= 12,
++	.divider	= 0,
++	.max_divider	= 0,
++	.extra_scaler	= 0,
++	.table		= ambarella_pll_int_table,
++	.table_size	= ARRAY_SIZE(ambarella_pll_int_table),
++	.ops		= &ambarella_rct_pll_ops,
++};
++#endif
++
++#if (SD_SUPPORT_SDXC == 1)
++static struct clk gclk_sdxc = {
++	.parent		= &pll_out_sd,
++	.name		= "gclk_sdxc",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= SCALER_SDXC_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++#endif
++
++#if (SD_SUPPORT_SDIO == 1)
++static struct clk gclk_sdio = {
++#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3)
++	.parent		= &pll_out_sd,
++#else
++	.parent		= &pll_out_core,
++#endif
++	.name		= "gclk_sdio",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= SCALER_SDIO_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++#endif
++
++static struct clk gclk_sd = {
++#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	.parent		= &pll_out_sd,
++#else
++	.parent		= &pll_out_core,
++#endif
++	.name		= "gclk_sd",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= SCALER_SD48_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_ir = {
++	.parent		= NULL,
++	.name		= "gclk_ir",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= CG_IR_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 24) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_adc = {
++	.parent		= NULL,
++	.name		= "gclk_adc",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= SCALER_ADC_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 2,
++	.max_divider	= (1 << 16) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_ssi = {	/* for SSI master */
++#if (CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++	.parent		= &gclk_apb,
++#else
++	.parent		= &pll_out_core,
++#endif
++	.name		= "gclk_ssi",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= CG_SSI_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 24) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static struct clk gclk_ssi2 = {	/* for SSI slave */
++#if (CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++	.parent		= &gclk_apb,
++#else
++	.parent		= &pll_out_core,
++#endif
++	.name		= "gclk_ssi2",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= CG_SSI2_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 24) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++static struct clk gclk_ssi3 = {	/* for SPINOR */
++	/* TODO: parent is determined by CLK_REF_SSI3_REG */
++	.parent		= &pll_out_core,
++	.name		= "gclk_ssi3",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= CG_SSI3_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 24) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++#endif
++
++static struct clk gclk_pwm = {
++	.parent		= &gclk_apb,
++	.name		= "gclk_pwm",
++	.rate		= 0,
++	.frac_mode	= 0,
++	.ctrl_reg	= -1,
++	.pres_reg	= -1,
++	.post_reg	= CG_PWM_REG,
++	.frac_reg	= -1,
++	.ctrl2_reg	= -1,
++	.ctrl3_reg	= -1,
++	.lock_reg	= -1,
++	.lock_bit	= 0,
++	.divider	= 0,
++	.max_divider	= (1 << 24) - 1,
++	.extra_scaler	= 0,
++	.ops		= &ambarella_rct_scaler_ops,
++};
++
++static int ambarella_pll_service(void *arg, void *result)
++{
++	struct ambsvc_pll *pll_svc = arg;
++	struct clk *clk;
++	int rval = 0;
++
++	BUG_ON(!pll_svc || !pll_svc->name);
++
++	clk = clk_get(NULL, pll_svc->name);
++	if (IS_ERR(clk)) {
++		pr_err("%s: ERR get %s\n", __func__, pll_svc->name);
++		return -EINVAL;
++	}
++
++	switch (pll_svc->svc_id) {
++	case AMBSVC_PLL_GET_RATE:
++		pll_svc->rate = clk_get_rate(clk);
++		break;
++	case AMBSVC_PLL_SET_RATE:
++		clk_set_rate(clk, pll_svc->rate);
++		break;
++
++	default:
++		pr_err("%s: Invalid pll service (%d)\n", __func__, pll_svc->svc_id);
++		rval = -EINVAL;
++		break;
++	}
++
++	return rval;
++}
++
++void ambarella_init_early(void)
++{
++	ambarella_clk_add(&pll_out_core);
++#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	ambarella_clk_add(&pll_out_sd);
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_CORTEX)
++	ambarella_clk_add(&gclk_cortex);
++	ambarella_clk_add(&gclk_axi);
++#if defined(CONFIG_HAVE_ARM_TWD)
++	ambarella_clk_add(&clk_smp_twd);
++#endif
++#endif
++	ambarella_clk_add(&gclk_ddr);
++	ambarella_clk_add(&gclk_core);
++	ambarella_clk_add(&gclk_ahb);
++	ambarella_clk_add(&gclk_apb);
++	ambarella_clk_add(&gclk_idsp);
++#ifdef CONFIG_AMBARELLA_CALC_PLL
++	amba_rct_writel(CLK_SI_INPUT_MODE_REG, 0x0);
++#if (CHIP_REV == S2E)
++	amba_rct_setbitsl(HDMI_CLOCK_CTRL_REG, 0x1);
++#endif
++	ambarella_clk_add(&gclk_so);
++	ambarella_clk_add(&gclk_vo2);	/* for lcd */
++	ambarella_clk_add(&gclk_vo);	/* for tv */
++#endif
++#if (CHIP_REV == S2E)
++	amba_rct_writel(UART_CLK_SRC_SEL_REG, UART_CLK_SRC_IDSP);
++#endif
++	ambarella_clk_add(&gclk_uart);
++	ambarella_clk_add(&gclk_audio);
++#if (SD_SUPPORT_SDXC == 1)
++	ambarella_clk_add(&gclk_sdxc);
++#endif
++#if (SD_SUPPORT_SDIO == 1)
++	ambarella_clk_add(&gclk_sdio);
++#endif
++	ambarella_clk_add(&gclk_sd);
++	ambarella_clk_add(&gclk_ir);
++	ambarella_clk_add(&gclk_adc);
++	ambarella_clk_add(&gclk_ssi);
++	ambarella_clk_add(&gclk_ssi2);
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++	ambarella_clk_add(&gclk_ssi3);
++#endif
++	ambarella_clk_add(&gclk_pwm);
++
++	/* register ambarella clk service for private operation */
++	pll_service.service = AMBARELLA_SERVICE_PLL;
++	pll_service.func = ambarella_pll_service;
++	ambarella_register_service(&pll_service);
++}
++
+diff --git a/arch/arm/mach-ambarella/clk_calc.c b/arch/arm/mach-ambarella/clk_calc.c
+new file mode 100644
+index 00000000..790e4453
+--- /dev/null
++++ b/arch/arm/mach-ambarella/clk_calc.c
+@@ -0,0 +1,162 @@
++/*
++ * arch/arm/mach-ambarella/pll_calc.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/io.h>
++#include <linux/clk.h>
++#include <linux/rational.h>
++#include <mach/init.h>
++#include <plat/clk.h>
++#include <plat/fio.h>
++#include <plat/sd.h>
++#include <plat/spi.h>
++
++/* these two tables are actually not used */
++struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE];
++struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE];
++
++int ambarella_rct_clk_set_rate(struct clk *c, unsigned long rate)
++{
++	unsigned long rate_int, pre_scaler = 1, post_scaler = 1;
++	unsigned long intp, sdiv = 1, sout = 1;
++	u32 ctrl2, ctrl3, fix_divider = c->divider ? c->divider : 1;
++	u64 dividend, divider, diff;
++	union ctrl_reg_u ctrl_reg;
++	union frac_reg_u frac_reg;
++
++	BUG_ON(c->ctrl_reg == -1 || c->ctrl2_reg == -1 || c->ctrl3_reg == -1);
++
++	rate *= fix_divider;
++
++	if (rate < REF_CLK_FREQ && c->post_reg != -1) {
++		rate *= 16;
++		post_scaler = 16;
++	}
++
++	if (rate < REF_CLK_FREQ) {
++		pr_err("Error: target rate is too slow: %ld!\n", rate);
++		return -1;
++	}
++
++	//TODO: temporary solution for s3l 4Kp30 hdmi vout
++	if(rate == (PLL_CLK_296_703MHZ * fix_divider)){
++		pre_scaler = 4;
++		intp = 0x63;
++		sdiv = 5;
++		sout = 1;
++		c->frac_mode = 0;
++	}else{
++                /* fvco should be less than 1.5GHz, so we use 64 as max_numerator,
++                 * although the actual bit width of pll_intp is 7 */
++                rational_best_approximation(rate, REF_CLK_FREQ, 64, 16, &intp, &sout);
++
++                /* fvco should be faster than 700MHz, otherwise pll out is not stable */
++                while (REF_CLK_FREQ / 1000000 * intp * sdiv / pre_scaler < 700) {
++                        if (sout > 8 || intp > 64)
++                                break;
++                        intp *= 2;
++                        sout *= 2;
++                }
++
++                BUG_ON(pre_scaler > 16 || post_scaler > 16);
++                BUG_ON(intp > 64 || sdiv > 16 || sout > 16 || sdiv > 16);
++        }
++
++	if (c->pres_reg != -1) {
++		if (c->extra_scaler == 1)
++			amba_rct_writel_en(c->pres_reg, (pre_scaler - 1) << 4);
++		else
++			amba_rct_writel(c->pres_reg, pre_scaler);
++	}
++
++	if (c->post_reg != -1) {
++		if (c->extra_scaler == 1)
++			amba_rct_writel_en(c->post_reg, (post_scaler - 1) << 4);
++		else
++			amba_rct_writel(c->post_reg, post_scaler);
++	}
++
++	ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++	ctrl_reg.s.intp = intp - 1;
++	ctrl_reg.s.sdiv = sdiv - 1;
++	ctrl_reg.s.sout = sout - 1;
++	ctrl_reg.s.bypass = 0;
++	ctrl_reg.s.frac_mode = 0;
++	ctrl_reg.s.force_reset = 0;
++	ctrl_reg.s.power_down = 0;
++	ctrl_reg.s.halt_vco = 0;
++	ctrl_reg.s.tristate = 0;
++	ctrl_reg.s.force_lock = 1;
++	ctrl_reg.s.force_bypass = 0;
++	ctrl_reg.s.write_enable = 0;
++	amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
++
++	if (c->frac_mode) {
++		rate_int = ambarella_rct_clk_get_rate(c) * fix_divider * post_scaler;
++		if (rate_int <= rate)
++			diff = rate - rate_int;
++		else
++			diff = rate_int - rate;
++
++		if (diff) {
++			dividend = diff * pre_scaler * sout;
++			dividend = dividend << 32;
++			divider = (u64)sdiv * REF_CLK_FREQ;
++			dividend = DIV_ROUND_CLOSEST_ULL(dividend, divider);
++			if (rate_int <= rate) {
++				frac_reg.s.nega	= 0;
++				frac_reg.s.frac	= dividend;
++			} else {
++				frac_reg.s.nega	= 1;
++				frac_reg.s.frac	= 0x80000000 - dividend;
++			}
++			amba_rct_writel(c->frac_reg, frac_reg.w);
++
++			ctrl_reg.s.frac_mode = 1;
++		}
++
++		amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
++	}
++
++	ctrl2 = c->ctrl2_val ? c->ctrl2_val : 0x3f770000;
++	ctrl3 = c->ctrl3_val ? c->ctrl3_val : ctrl_reg.s.frac_mode ? 0x00069300 : 0x00068300;
++	if(rate == (PLL_CLK_296_703MHZ * fix_divider)){
++		ctrl2 = 0x3f700e00;
++		ctrl3 = 0x00068306;
++	}
++	amba_rct_writel(c->ctrl2_reg, ctrl2);
++	amba_rct_writel(c->ctrl3_reg, ctrl3);
++
++	c->rate = ambarella_rct_clk_get_rate(c);
++
++	/* check if result rate is precise or not */
++	if (abs(c->rate - rate / fix_divider / post_scaler) > 10) {
++		pr_warn("%s: rate is not very precise: %lld, %ld\n",
++			c->name, c->rate, rate / fix_divider / post_scaler);
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_clk_set_rate);
++
+diff --git a/arch/arm/mach-ambarella/clk_table.c b/arch/arm/mach-ambarella/clk_table.c
+new file mode 100644
+index 00000000..9d7e325f
+--- /dev/null
++++ b/arch/arm/mach-ambarella/clk_table.c
+@@ -0,0 +1,2543 @@
++/*
++ * arch/arm/mach-ambarella/clk_table.c
++ *
++ * Author: Anthony Ginger <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/module.h>
++#include <linux/io.h>
++#include <plat/clk.h>
++
++int ambarella_rct_clk_set_rate(struct clk *c, unsigned long rate)
++{
++	u32 pre_scaler, post_scaler, middle;
++	u32 intp, sdiv, sout, post, ctrl2, ctrl3;
++	u64 dividend, divider, diff;
++	union ctrl_reg_u ctrl_reg;
++	union frac_reg_u frac_reg;
++
++	if (!rate)
++		return -1;
++
++	BUG_ON(c->ctrl_reg == -1 || c->ctrl2_reg == -1 || c->ctrl3_reg == -1);
++	BUG_ON(c->post_reg != -1 && !c->max_divider);
++	BUG_ON(!c->table || c->table_size == 0);
++#if 0
++	if (c->divider)
++		rate *= c->divider;
++#endif
++	if (c->pres_reg != -1) {
++		if (c->pres_val) {
++			pre_scaler = c->pres_val;
++			if (c->extra_scaler == 1)
++				amba_rct_writel_en(c->pres_reg, (pre_scaler - 1) << 4);
++			else
++				amba_rct_writel(c->pres_reg, pre_scaler);
++		} else {
++			pre_scaler = amba_rct_readl(c->pres_reg);
++			if (c->extra_scaler == 1) {
++				pre_scaler >>= 4;
++				pre_scaler++;
++			}
++		}
++	} else {
++		pre_scaler = 1;
++	}
++
++	middle = ambarella_rct_find_pll_table_index(rate,
++			pre_scaler, c->table, c->table_size);
++	intp = c->table[middle].intp;
++	sdiv = c->table[middle].sdiv;
++	sout = c->table[middle].sout;
++	post = c->post_val ? c->post_val : c->table[middle].post;
++
++	ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++	ctrl_reg.s.intp = intp;
++	ctrl_reg.s.sdiv = sdiv;
++	ctrl_reg.s.sout = sout;
++	ctrl_reg.s.bypass = 0;
++	ctrl_reg.s.frac_mode = 0;
++	ctrl_reg.s.force_reset = 0;
++	ctrl_reg.s.power_down = 0;
++	ctrl_reg.s.halt_vco = 0;
++	ctrl_reg.s.tristate = 0;
++	ctrl_reg.s.force_lock = 1;
++	ctrl_reg.s.force_bypass = 0;
++	ctrl_reg.s.write_enable = 0;
++	amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
++
++	if (c->post_reg != -1) {
++		post_scaler = min(post, c->max_divider);
++		if (c->extra_scaler == 1)
++			amba_rct_writel_en(c->post_reg, (post_scaler - 1) << 4);
++		else
++			amba_rct_writel(c->post_reg, post_scaler);
++	}
++
++	if (c->frac_mode) {
++		c->rate = ambarella_rct_clk_get_rate(c);
++		if (c->rate < rate)
++			diff = rate - c->rate;
++		else
++			diff = c->rate - rate;
++
++		dividend = diff * pre_scaler * (sout + 1) * post;
++		if (c->divider)
++			dividend *= c->divider;
++		dividend = dividend << 32;
++		divider = (u64)ambarella_clk_get_ref_freq() * (sdiv + 1);
++		AMBCLK_DO_DIV_ROUND(dividend, divider);
++		if (c->rate <= rate) {
++			frac_reg.s.nega	= 0;
++			frac_reg.s.frac	= dividend;
++		} else {
++			frac_reg.s.nega	= 1;
++			frac_reg.s.frac	= 0x80000000 - dividend;
++		}
++		amba_rct_writel(c->frac_reg, frac_reg.w);
++
++		ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
++		if (diff)
++			ctrl_reg.s.frac_mode = 1;
++		else
++			ctrl_reg.s.frac_mode = 0;
++
++		ctrl_reg.s.force_lock = 1;
++		ctrl_reg.s.write_enable = 1;
++		amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++
++		ctrl_reg.s.write_enable	= 0;
++		amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
++	}
++
++	ctrl2 = c->ctrl2_val ? c->ctrl2_val : 0x3f770000;
++	ctrl3 = c->ctrl3_val ? c->ctrl3_val : ctrl_reg.s.frac_mode ? 0x00069300 : 0x00068300;
++	amba_rct_writel(c->ctrl2_reg, ctrl2);
++	amba_rct_writel(c->ctrl3_reg, ctrl3);
++
++	c->rate = ambarella_rct_clk_get_rate(c);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_rct_clk_set_rate);
++
++u32 ambarella_rct_find_pll_table_index(unsigned long rate, u32 pre_scaler,
++	const struct pll_table *table, u32 table_size)
++{
++	u64 dividend;
++	u64 divider;
++	u32 start;
++	u32 middle;
++	u32 end;
++	u32 index_limit;
++	u64 diff = 0;
++	u64 diff_low = 0xFFFFFFFFFFFFFFFF;
++	u64 diff_high = 0xFFFFFFFFFFFFFFFF;
++
++	pr_debug("pre_scaler = [0x%08X]\n", pre_scaler);
++
++	dividend = rate;
++	dividend *= pre_scaler;
++	dividend *= (1000 * 1000 * 1000);
++	divider = ambarella_clk_get_ref_freq() / (1000 * 1000);
++	AMBCLK_DO_DIV(dividend, divider);
++
++	index_limit = (table_size - 1);
++	start = 0;
++	end = index_limit;
++	middle = table_size / 2;
++	while (table[middle].multiplier != dividend) {
++		if (table[middle].multiplier < dividend) {
++			start = middle;
++		} else {
++			end = middle;
++		}
++		middle = (start + end) / 2;
++		if (middle == start || middle == end) {
++			break;
++		}
++	}
++	if ((middle > 0) && ((middle + 1) <= index_limit)) {
++		if (table[middle - 1].multiplier < dividend) {
++			diff_low = dividend - table[middle - 1].multiplier;
++		} else {
++			diff_low = table[middle - 1].multiplier - dividend;
++		}
++		if (table[middle].multiplier < dividend) {
++			diff = dividend - table[middle].multiplier;
++		} else {
++			diff = table[middle].multiplier - dividend;
++		}
++		if (table[middle + 1].multiplier < dividend) {
++			diff_high = dividend - table[middle + 1].multiplier;
++		} else {
++			diff_high = table[middle + 1].multiplier - dividend;
++		}
++		pr_debug("multiplier[%u] = [%llu]\n", (middle - 1),
++			table[middle - 1].multiplier);
++		pr_debug("multiplier[%u] = [%llu]\n", (middle),
++			table[middle].multiplier);
++		pr_debug("multiplier[%u] = [%llu]\n", (middle + 1),
++			table[middle + 1].multiplier);
++	} else if ((middle == 0) && ((middle + 1) <= index_limit)) {
++		if (table[middle].multiplier < dividend) {
++			diff = dividend - table[middle].multiplier;
++		} else {
++			diff = table[middle].multiplier - dividend;
++		}
++		if (table[middle + 1].multiplier < dividend) {
++			diff_high = dividend - table[middle + 1].multiplier;
++		} else {
++			diff_high = table[middle + 1].multiplier - dividend;
++		}
++		pr_debug("multiplier[%u] = [%llu]\n", (middle),
++			table[middle].multiplier);
++		pr_debug("multiplier[%u] = [%llu]\n", (middle + 1),
++			table[middle + 1].multiplier);
++	} else if ((middle > 0) && ((middle + 1) > index_limit)) {
++		if (table[middle - 1].multiplier < dividend) {
++			diff_low = dividend - table[middle - 1].multiplier;
++		} else {
++			diff_low = table[middle - 1].multiplier - dividend;
++		}
++		if (table[middle].multiplier < dividend) {
++			diff = dividend - table[middle].multiplier;
++		} else {
++			diff = table[middle].multiplier - dividend;
++		}
++		pr_debug("multiplier[%u] = [%llu]\n", (middle - 1),
++			table[middle - 1].multiplier);
++		pr_debug("multiplier[%u] = [%llu]\n", (middle),
++			table[middle].multiplier);
++	}
++	pr_debug("diff_low = [%llu]\n", diff_low);
++	pr_debug("diff = [%llu]\n", diff);
++	pr_debug("diff_high = [%llu]\n", diff_high);
++	if (diff_low < diff) {
++		if (middle) {
++			middle--;
++		}
++	}
++	if (diff_high < diff) {
++		middle++;
++		if (middle > index_limit) {
++			middle = index_limit;
++		}
++	}
++	pr_debug("middle = [%u]\n", middle);
++
++	return middle;
++}
++EXPORT_SYMBOL(ambarella_rct_find_pll_table_index);
++
++/* ==========================================================================*/
++
++struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE] =
++{
++	{    1000000000000000,   13,    0,   13,    1},
++	{    1500000000000000,   13,    2,   27,    1},
++	{    2000000000000000,   13,    0,    6,    1},
++	{    2500000000000000,   14,    0,    5,    1},
++	{    3000000000000000,   13,    2,   13,    1},
++	{    3500000000000000,   13,    0,    3,    1},
++	{    4000000000000000,   13,    1,    6,    1},
++	{    4500000000000000,   14,    2,    9,    1},
++	{    5000000000000000,   14,    0,    2,    1},
++	{    5500000000000000,   21,    0,    3,    1},
++	{    6000000000000000,   13,    2,    6,    1},
++	{    6500000000000000,   25,    0,    3,    1},
++	{    7000000000000000,   13,    0,    1,    1},
++	{    7500000000000000,   14,    0,    1,    1},
++	{    8000000000000000,   15,    0,    1,    1},
++	{    8500000000000000,   16,    0,    1,    1},
++	{    9000000000000000,   14,    2,    4,    1},
++	{    9500000000000000,   18,    0,    1,    1},
++	{   10000000000000000,   14,    1,    2,    1},
++	{   10500000000000000,   13,    2,    3,    1},
++	{   11000000000000000,   21,    0,    1,    1},
++	{   11500000000000000,   22,    0,    1,    1},
++	{   12000000000000000,   15,    2,    3,    1},
++	{   12500000000000000,   24,    0,    1,    1},
++	{   13000000000000000,   25,    0,    1,    1},
++	{   13500000000000000,   17,    2,    3,    1},
++	{   14000000000000000,   13,    0,    0,    1},
++	{   14500000000000000,   28,    0,    1,    1},
++	{   15000000000000000,   14,    0,    0,    1},
++	{   15500000000000000,   30,    0,    1,    1},
++	{   16000000000000000,   15,    0,    0,    1},
++	{   16500000000000000,   21,    2,    3,    1},
++	{   17000000000000000,   16,    0,    0,    1},
++	{   17500000000000000,   34,    0,    1,    1},
++	{   18000000000000000,   17,    0,    0,    1},
++	{   18500000000000000,   36,    0,    1,    1},
++	{   19000000000000000,   18,    0,    0,    1},
++	{   19500000000000000,   25,    2,    3,    1},
++	{   20000000000000000,   19,    0,    0,    1},
++	{   20500000000000000,   40,    0,    1,    1},
++	{   21000000000000000,   13,    2,    1,    1},
++	{   21500000000000000,   42,    0,    1,    1},
++	{   22000000000000000,   21,    0,    0,    1},
++	{   22500000000000000,   14,    2,    1,    1},
++	{   23000000000000000,   22,    0,    0,    1},
++	{   23500000000000000,   46,    0,    1,    1},
++	{   24000000000000000,   15,    2,    1,    1},
++	{   24500000000000000,   48,    0,    1,    1},
++	{   25000000000000000,   24,    0,    0,    1},
++	{   25500000000000000,   16,    2,    1,    1},
++	{   26000000000000000,   25,    0,    0,    1},
++	{   27000000000000000,   17,    2,    1,    1},
++	{   28000000000000000,   13,    1,    0,    1},
++	{   28500000000000000,   18,    2,    1,    1},
++	{   29000000000000000,   28,    0,    0,    1},
++	{   30000000000000000,   14,    1,    0,    1},
++	{   31000000000000000,   30,    0,    0,    1},
++	{   31500000000000000,   20,    2,    1,    1},
++	{   32000000000000000,   15,    1,    0,    1},
++	{   33000000000000000,   21,    2,    1,    1},
++	{   34000000000000000,   16,    1,    0,    1},
++	{   34500000000000000,   22,    2,    1,    1},
++	{   35000000000000000,   34,    0,    0,    1},
++	{   36000000000000000,   17,    1,    0,    1},
++	{   37000000000000000,   36,    0,    0,    1},
++	{   37500000000000000,   24,    2,    1,    1},
++	{   38000000000000000,   18,    1,    0,    1},
++	{   39000000000000000,   25,    2,    1,    1},
++	{   40000000000000000,   19,    1,    0,    1},
++	{   40500000000000000,   26,    2,    1,    1},
++	{   41000000000000000,   40,    0,    0,    1},
++	{   42000000000000000,   13,    2,    0,    1},
++	{   43000000000000000,   42,    0,    0,    1},
++	{   43500000000000000,   28,    2,    1,    1},
++	{   44000000000000000,   21,    1,    0,    1},
++	{   45000000000000000,   14,    2,    0,    1},
++	{   46000000000000000,   22,    1,    0,    1},
++	{   46500000000000000,   30,    2,    1,    1},
++	{   47000000000000000,   46,    0,    0,    1},
++	{   48000000000000000,   15,    2,    0,    1},
++	{   49000000000000000,   48,    0,    0,    1},
++	{   49500000000000000,   32,    2,    1,    1},
++	{   50000000000000000,   24,    1,    0,    1},
++	{   51000000000000000,   16,    2,    0,    1},
++	{   52000000000000000,   25,    1,    0,    1},
++	{   52500000000000000,   34,    2,    1,    1},
++	{   54000000000000000,   17,    2,    0,    1},
++	{   55500000000000000,   36,    2,    1,    1},
++	{   56000000000000000,   27,    1,    0,    1},
++	{   57000000000000000,   18,    2,    0,    1},
++	{   58000000000000000,   28,    1,    0,    1},
++	{   58500000000000000,   38,    2,    1,    1},
++	{   60000000000000000,   19,    2,    0,    1},
++};
++EXPORT_SYMBOL(ambarella_pll_int_table);
++
++
++struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE] =
++{
++	{    16601562500000,	  0,	 0,	 3,	15 },
++	{    16732282936573,	  0,	 0,	 3,	15 },
++	{    16865080222486,	  0,	 2,	15,	11 },
++	{    17000000923872,	  0,	 2,	15,	11 },
++	{    17137097194791,	  0,	 1,	 8,	13 },
++	{    17276423051953,	  0,	 1,	 8,	13 },
++	{    17418032512068,	  0,	 1,	 8,	13 },
++	{    17561983317137,	  0,	 2,	12,	13 },
++	{    17708333209157,	  0,	 2,	12,	13 },
++	{    17847768962383,	  0,	 0,	 3,	14 },
++	{    17989417538047,	  0,	 0,	 3,	14 },
++	{    18133332952857,	  0,	 0,	 4,	11 },
++	{    18279569223523,	  0,	 0,	 4,	11 },
++	{    18428184092045,	  0,	 0,	 5,	 9 },
++	{    18579235300422,	  0,	 0,	 5,	 9 },
++	{    18732782453299,	  0,	 2,	15,	10 },
++	{    18973214551806,	  0,	 1,	 6,	15 },
++	{    19122609868646,	  0,	 1,	 6,	15 },
++	{    19274376332760,	  0,	 0,	 3,	13 },
++	{    19428571686149,	  0,	 2,	10,	14 },
++	{    19585253670812,	  0,	 2,	10,	14 },
++	{    19744483754039,	  0,	 0,	 4,	10 },
++	{    19906323403120,	  0,	 0,	 4,	10 },
++	{    20070837810636,	  0,	 0,	 4,	10 },
++	{    20238095894456,	  0,	 1,	 8,	11 },
++	{    20432692021132,	  0,	 0,	 6,	 7 },
++	{    20593579858541,	  0,	 3,	12,	15 },
++	{    20757021382451,	  0,	 0,	 3,	12 },
++	{    20923076197505,	  0,	 2,	10,	13 },
++	{    21091811358929,	  0,	 2,	10,	13 },
++	{    21263290196657,	  0,	 2,	 9,	14 },
++	{    21437577903271,	  0,	 2,	 9,	14 },
++	{    21614748984575,	  0,	 2,	 9,	14 },
++	{    21794872358441,	  0,	 1,	 6,	13 },
++	{    22135416045785,	  0,	 0,	 2,	15 },
++	{    22309711202979,	  0,	 4,	15,	14 },
++	{    22486772388220,	  0,	 4,	15,	14 },
++	{    22666666656733,	  0,	 0,	 3,	11 },
++	{    22849462926388,	  0,	 0,	 3,	11 },
++	{    23035230115056,	  0,	 2,	 9,	13 },
++	{    23224044591188,	  0,	 2,	 9,	13 },
++	{    23415977135301,	  0,	 2,	15,	 8 },
++	{    23611111566424,	  0,	 3,	12,	13 },
++	{    23809524253011,	  0,	 0,	 2,	14 },
++	{    24147726595402,	  0,	 3,	10,	15 },
++	{    24337867274880,	  0,	 3,	10,	15 },
++	{    24531025439501,	  0,	 1,	 8,	 9 },
++	{    24727271869779,	  0,	 1,	 8,	 9 },
++	{    24926686659455,	  0,	 0,	 3,	10 },
++	{    25129342451692,	  0,	 0,	 3,	10 },
++	{    25335321202874,	  0,	 4,	13,	14 },
++	{    25544703006744,	  0,	 4,	13,	14 },
++	{    25757575407624,	  0,	 0,	 2,	13 },
++	{    25974025949836,	  0,	 1,	 6,	11 },
++	{    26194144040346,	  0,	 4,	15,	12 },
++	{    26562500745058,	  0,	 1,	 4,	15 },
++	{    26771653443575,	  0,	 2,	 7,	14 },
++	{    26984127238393,	  0,	 2,	 7,	14 },
++	{    27200000360608,	  0,	 2,	 9,	11 },
++	{    27419354766607,	  0,	 4,	12,	14 },
++	{    27642276138067,	  0,	 0,	 2,	12 },
++	{    27868852019310,	  0,	 0,	 2,	12 },
++	{    28099173679948,	  0,	 3,	10,	13 },
++	{    28333334252238,	  0,	 4,	15,	11 },
++	{    28571428731084,	  0,	 0,	 4,	 7 },
++	{    28813559561968,	  0,	 2,	 7,	13 },
++	{    29059829190373,	  0,	 6,	15,	15 },
++	{    29513888061047,	  0,	 4,	12,	13 },
++	{    29746280983090,	  0,	 4,	11,	14 },
++	{    29982363805175,	  0,	 2,	 9,	10 },
++	{    30222222208977,	  0,	 0,	 2,	11 },
++	{    30465949326754,	  0,	 2,	 6,	14 },
++	{    30713640153408,	  0,	 1,	 4,	13 },
++	{    30965391546488,	  0,	 6,	14,	15 },
++	{    31221304088831,	  0,	 0,	 3,	 8 },
++	{    31481482088566,	  0,	 0,	 3,	 8 },
++	{    31746033579111,	  0,	 1,	 6,	 9 },
++	{    32015066593885,	  0,	 4,	11,	13 },
++	{    32288700342177,	  0,	 4,	10,	14 },
++	{    32567050307989,	  0,	 4,	10,	14 },
++	{    32850243151188,	  0,	 2,	 6,	13 },
++	{    33203125000000,	  0,	 0,	 1,	15 },
++	{    33464565873146,	  0,	 0,	 1,	15 },
++	{    33730160444975,	  0,	 6,	15,	13 },
++	{    34000001847744,	  0,	 2,	 7,	11 },
++	{    34274194389582,	  0,	 3,	 8,	13 },
++	{    34552846103907,	  0,	 4,	11,	12 },
++	{    34836065024136,	  0,	 4,	11,	12 },
++	{    35123966634274,	  0,	 4,	10,	13 },
++	{    35416666418314,	  0,	 5,	12,	13 },
++	{    35714287310839,	  0,	 0,	 1,	14 },
++	{    36016948521137,	  0,	 6,	12,	15 },
++	{    36324787884951,	  0,	 1,	 4,	11 },
++	{    36637932062149,	  0,	 6,	15,	12 },
++	{    36956522613764,	  0,	 0,	 2,	 9 },
++	{    37280701100826,	  0,	 2,	 7,	10 },
++	{    37610620260239,	  0,	 2,	 7,	10 },
++	{    37946429103613,	  0,	 4,	10,	12 },
++	{    38245219737291,	  0,	 3,	 6,	15 },
++	{    38548752665520,	  0,	 0,	 1,	13 },
++	{    38857143372297,	  0,	 6,	11,	15 },
++	{    39170507341623,	  0,	 4,	15,	 8 },
++	{    39488967508078,	  0,	 4,	 8,	14 },
++	{    39812646806240,	  0,	 6,	15,	11 },
++	{    40141675621271,	  0,	 8,	15,	14 },
++	{    40476191788912,	  0,	 3,	 8,	11 },
++	{    40816325694323,	  0,	 1,	 6,	 7 },
++	{    41162226349115,	  0,	 7,	12,	15 },
++	{    41514042764902,	  0,	 6,	12,	13 },
++	{    41871920228004,	  0,	 5,	10,	13 },
++	{    42236026376486,	  0,	 6,	10,	15 },
++	{    42606517672539,	  0,	 4,	 8,	13 },
++	{    42983565479517,	  0,	 2,	 4,	14 },
++	{    43367348611355,	  0,	 8,	15,	13 },
++	{    43758042156696,	  0,	 6,	15,	10 },
++	{    44270832091570,	  0,	 1,	 2,	15 },
++	{    44619422405958,	  0,	 4,	 7,	14 },
++	{    44973544776440,	  0,	 6,	11,	13 },
++	{    45333333313465,	  0,	 0,	 1,	11 },
++	{    45698925852776,	  0,	10,	15,	15 },
++	{    46070460230112,	  0,	 2,	 4,	13 },
++	{    46448089182377,	  0,	 4,	 8,	12 },
++	{    46831954270601,	  0,	 2,	 7,	 8 },
++	{    47222223132849,	  0,	 7,	12,	13 },
++	{    47619048506021,	  0,	 0,	 2,	 7 },
++	{    48022598028183,	  0,	 4,	 7,	13 },
++	{    48433046787977,	  0,	 7,	10,	15 },
++	{    48850573599339,	  0,	10,	14,	15 },
++	{    49275361001492,	  0,	 3,	 8,	 9 },
++	{    49707602709532,	  0,	 5,	10,	11 },
++	{    50147492438555,	  0,	 0,	 1,	10 },
++	{    50595238804817,	  0,	 4,	 8,	11 },
++	{    51051050424576,	  0,	 4,	 6,	14 },
++	{    51515150815248,	  0,	 1,	 2,	13 },
++	{    51987767219543,	  0,	 3,	 6,	11 },
++	{    52469134330750,	  0,	10,	13,	15 },
++	{    53125001490116,	  0,	 6,	10,	12 },
++	{    53543306887150,	  0,	 2,	 3,	14 },
++	{    53968254476786,	  0,	 6,	 9,	13 },
++	{    54400000721216,	  0,	 2,	 4,	11 },
++	{    54838709533215,	  0,	 4,	 6,	13 },
++	{    55284552276134,	  0,	 0,	 1,	 9 },
++	{    55737704038620,	  0,	 0,	 1,	 9 },
++	{    56198347359896,	  0,	 8,	15,	10 },
++	{    56666668504477,	  0,	 4,	 7,	11 },
++	{    57142857462168,	  0,	 1,	 4,	 7 },
++	{    57627119123936,	  0,	 2,	 3,	13 },
++	{    58119658380747,	  0,	12,	15,	14 },
++	{    58620691299438,	  0,	 8,	10,	14 },
++	{    59130433946848,	  0,	 9,	12,	13 },
++	{    59649121016264,	  0,	 4,	 5,	14 },
++	{    60176990926266,	  0,	 2,	 4,	10 },
++	{    60714285820723,	  0,	 1,	 2,	11 },
++	{    61261262744665,	  0,	 2,	 6,	 7 },
++	{    61818182468414,	  0,	12,	13,	15 },
++	{    62385320663452,	  0,	 0,	 1,	 8 },
++	{    62962964177132,	  0,	 8,	10,	13 },
++	{    63551403582096,	  0,	 3,	 6,	 9 },
++	{    64150944352150,	  0,	 4,	 5,	13 },
++	{    64761906862258,	  0,	 6,	 8,	12 },
++	{    65384618937969,	  0,	10,	11,	14 },
++	{    65891474485397,	  0,	 5,	 6,	13 },
++	{    66406250000000,	  0,	12,	13,	14 },
++	{    66929131746292,	  0,	14,	15,	14 },
++	{    67460320889950,	  0,	 6,	 7,	13 },
++	{    68000003695488,	  0,	 2,	 3,	11 },
++	{    68548388779163,	  0,	 7,	 8,	13 },
++	{    69105692207813,	  0,	 8,	 9,	13 },
++	{    69672130048274,	  0,	 4,	 5,	12 },
++	{    70247933268547,	  0,	 8,	15,	 8 },
++	{    70833332836628,	 16,	 0,	15,	15 },
++	{    71428574621677,	  0,	 0,	 0,	14 },
++	{    72033897042274,	  0,	14,	15,	13 },
++	{    72649575769901,	  0,	 3,	 4,	11 },
++	{    73275864124298,	  0,	10,	 9,	15 },
++	{    73913045227528,	  0,	12,	15,	11 },
++	{    74561402201653,	  0,	 8,	10,	11 },
++	{    75221240520477,	  0,	 2,	 3,	10 },
++	{    75892858207226,	 16,	 0,	15,	14 },
++	{    76576575636864,	  0,	14,	13,	14 },
++	{    77272728085518,	  0,	12,	11,	14 },
++	{    77981650829315,	  0,	 5,	 6,	11 },
++	{    78703701496124,	  0,	12,	10,	15 },
++	{    79439252614975,	  0,	 4,	 6,	 9 },
++	{    80188676714897,	  0,	 8,	 7,	14 },
++	{    80952383577824,	 16,	 0,	13,	15 },
++	{    81730768084526,	 16,	 0,	15,	13 },
++	{    82524269819260,	  0,	14,	12,	14 },
++	{    83333335816860,	  0,	 0,	 0,	12 },
++	{    84158413112164,	  0,	11,	10,	13 },
++	{    85000000894070,	 16,	 0,	13,	14 },
++	{    85858583450317,	  0,	10,	15,	 8 },
++	{    86734697222710,	 16,	 0,	13,	14 },
++	{    87628863751888,	  0,	 6,	 7,	10 },
++	{    88541664183140,	 16,	 0,	15,	12 },
++	{    89238844811916,	  0,	 4,	 3,	14 },
++	{    89947089552879,	  0,	 8,	 9,	10 },
++	{    90666666626930,	 18,	 0,	13,	15 },
++	{    91397851705551,	 18,	 0,	15,	13 },
++	{    92140920460224,	  0,	 5,	 4,	13 },
++	{    92896178364754,	  0,	12,	 9,	14 },
++	{    93663908541203,	  0,	 2,	 3,	 8 },
++	{    94444446265697,	 16,	 0,	11,	15 },
++	{    95238097012043,	  0,	 1,	 2,	 7 },
++	{    96045196056366,	  0,	 4,	 3,	13 },
++	{    96866093575954,	 18,	 0,	13,	14 },
++	{    97701147198677,	  1,	10,	14,	15 },
++	{    98550722002983,	  0,	12,	10,	12 },
++	{    99415205419064,	  0,	11,	10,	11 },
++	{   100294984877110,	  0,	 0,	 0,	10 },
++	{   101190477609634,	 16,	 0,	11,	14 },
++	{   102102100849152,	  0,	 4,	 6,	 7 },
++	{   103030301630497,	 16,	 0,	10,	15 },
++	{   103975534439087,	  0,	 7,	 6,	11 },
++	{   104938268661499,	  0,	14,	10,	13 },
++	{   105919003486633,	  0,	 6,	 5,	11 },
++	{   106918238103390,	  0,	 2,	 1,	14 },
++	{   107936508953571,	 18,	 0,	15,	11 },
++	{   108974359929562,	 16,	 0,	11,	13 },
++	{   110032364726067,	  0,	10,	 9,	10 },
++	{   111111111938953,	  0,	 0,	 0,	 9 },
++	{   112211219966412,	  0,	10,	 6,	14 },
++	{   113333337008953,	 16,	 0,	 9,	15 },
++	{   114478111267090,	  0,	10,	 7,	12 },
++	{   115646257996559,	  0,	13,	10,	11 },
++	{   116838485002518,	  0,	 8,	 6,	11 },
++	{   118055552244186,	 16,	 0,	11,	12 },
++	{   119298242032528,	  2,	 6,	15,	11 },
++	{   120567373931408,	  2,	 8,	15,	14 },
++	{   121863797307014,	 18,	 0,	11,	13 },
++	{   123188406229019,	  0,	 7,	 4,	13 },
++	{   124542124569416,	  1,	13,	14,	15 },
++	{   125925928354263,	 16,	 0,	 8,	15 },
++	{   127340823411942,	  0,	 6,	 4,	11 },
++	{   128787875175475,	 16,	 0,	10,	12 },
++	{   130268201231956,	  4,	 4,	15,	12 },
++	{   131782948970795,	  0,	11,	 6,	13 },
++	{   132812500000000,	 16,	 1,	15,	16 },
++	{   133858263492584,	  0,	14,	 7,	14 },
++	{   134920641779900,	 16,	 0,	 8,	14 },
++	{   136000007390976,	 22,	 0,	12,	13 },
++	{   137096777558327,	 22,	 0,	11,	14 },
++	{   138211384415627,	 28,	 0,	13,	15 },
++	{   139344260096549,	 22,	 0,	10,	15 },
++	{   140495866537094,	 17,	 1,	15,	16 },
++	{   141666665673256,	 16,	 1,	15,	15 },
++	{   142857149243355,	  0,	 0,	 0,	 7 },
++	{   144067794084549,	 18,	 0,	10,	12 },
++	{   145299151539803,	 16,	 0,	 8,	13 },
++	{   146551728248596,	  0,	10,	 4,	15 },
++	{   147826090455055,	 18,	 1,	15,	16 },
++	{   149122804403305,	 17,	 1,	15,	15 },
++	{   150442481040955,	 16,	 1,	14,	15 },
++	{   151785716414452,	 16,	 1,	15,	14 },
++	{   153153151273727,	  0,	14,	 6,	14 },
++	{   154545456171036,	 16,	 0,	 9,	11 },
++	{   155963301658630,	19,	 1,	15,	 16},
++	{   157407402992249,	18,	 1,	15,	 15},
++	{   158878505229950,	17,	 1,	14,	 15},
++	{   160377353429794,	17,	 1,	15,	 14},
++	{   161904767155647,	16,	 1,	14,	 14},
++	{   163461536169052,	16,	 1,	15,	 13},
++	{   165048539638519,	36,	 0,	15,	14 },
++	{   166666671633720,	19,	 1,	15,	 15},
++	{   168316826224327,	18,	 1,	14,	 15},
++	{   170000001788139,	18,	 1,	15,	 14},
++	{   171717166900635,	17,	 1,	14,	 14},
++	{   173469394445419,	16,	 1,	14,	 13},
++	{   175257727503777,	20,	 1,	15,	 15},
++	{   177083328366280,	16,	 1,	15,	 12},
++	{   178947374224663,	19,	 1,	15,	 14},
++	{   180851057171822,	18,	 1,	14,	 14},
++	{   182795703411102,	18,	 1,	15,	 13},
++	{   184782609343529,	17,	 1,	14,	 13},
++	{   186813190579414,	17,	 1,	15,	 12},
++	{   188888892531395,	16,	 1,	14,	 12},
++	{   191011235117912,	19,	 1,	15,	 13},
++	{   193181812763214,	16,	 1,	15,	 11},
++	{   195402294397354,	18,	 1,	14,	 13},
++	{   197674423456192,	18,	 1,	15,	 12},
++	{   200000002980232,	17,	 1,	14,	 12},
++	{   202380955219269,	16,	 1,	13,	 12},
++	{   204819276928902,	16,	 1,	14,	 11},
++	{   207317069172859,	19,	 1,	15,	 12},
++	{   209876537322998,	18,	 1,	14,	 12},
++	{   212500005960464,	16,	 1,	15,	 10},
++	{   215189874172211,	18,	 1,	15,	 11},
++	{   217948719859123,	17,	 1,	14,	 11},
++	{   220779225230217,	16,	 1,	13,	 11},
++	{   223684206604958,	17,	 1,	15,	 10},
++	{   226666674017906,	16,	 1,	14,	 10},
++	{   229729726910591,	18,	 1,	14,	 11},
++	{   232876718044281,	17,	 1,	13,	 11},
++	{   236111104488373,	16,	 1,	15,	  9},
++	{   239436626434326,	17,	 1,	14,	 10},
++	{   242857143282890,	16,	 1,	13,	 10},
++	{   246376812458038,	18,	 1,	13,	 11},
++	{   250000000000000,	16,	 1,	14,	  9},
++	{   253731340169907,	18,	 1,	14,	 10},
++	{   255639106035233,	17,	 1,	13,	 10},
++	{   257575750350951,	16,	 1,	11,	 11},
++	{   261538475751877,	16,	 1,	12,	 10},
++	{   263565897941589,	18,	 1,	15,	  9},
++	{   265625000000000,	16,	 1,	15,	  8},
++	{   267716526985168,	20,	 1,	12,	 12},
++	{   269841283559798,	16,	 1,	13,	  9},
++	{   272000014781952,	17,	 1,	11,	 11},
++	{   274193555116653,	21,	 1,	15,	 10},
++	{   276422768831253,	19,	 1,	15,	  9},
++	{   278688520193099,	20,	 1,	14,	 10},
++	{   280991733074188,	17,	 1,	15,	  8},
++	{   283333331346512,	16,	 1,	14,	  8},
++	{   285714298486710,	17,	 1,	13,	  9},
++	{   288135588169098,	18,	 1,	11,	 11},
++	{   290598303079605,	16,	 1,	12,	  9},
++	{   293103456497192,	21,	 1,	14,	 10},
++	{   295652180910110,	18,	 1,	15,	  8},
++	{   298245608806610,	17,	 1,	14,	  8},
++	{   300884962081909,	18,	 1,	13,	  9},
++	{   303571432828903,	16,	 1,	15,	  7},
++	{   306306302547455,	17,	 1,	12,	  9},
++	{   309090912342072,	20,	 1,	14,	  9},
++	{   311926603317261,	19,	 1,	15,	  8},
++	{   314814805984497,	18,	 1,	14,	  8},
++	{   317757010459900,	19,	 1,	13,	  9},
++	{   320754706859589,	17,	 1,	15,	  7},
++	{   323809534311295,	16,	 1,	14,	  7},
++	{   326923072338104,	16,	 1,	12,	  8},
++	{   330097079277039,	19,	 1,	10,	 11},
++	{   333333343267441,	19,	 1,	14,	  8},
++	{   336633652448654,	21,	 1,	12,	 10},
++	{   340000003576279,	18,	 1,	15,	  7},
++	{   343434333801270,	17,	 1,	14,	  7},
++	{   346938788890839,	16,	 1,	13,	  7},
++	{   350515455007553,	20,	 1,	14,	  8},
++	{   354166656732559,	16,	 1,	15,	  6},
++	{   357894748449326,	19,	 1,	15,	  7},
++	{   361702114343643,	18,	 1,	14,	  7},
++	{   365591406822205,	17,	 1,	13,	  7},
++	{   369565218687057,	19,	 1,	11,	  9},
++	{   373626381158829,	17,	 1,	15,	  6},
++	{   377777785062790,	16,	 1,	14,	  6},
++	{   382022470235825,	19,	 1,	14,	  7},
++	{   386363625526428,	18,	 1,	13,	  7},
++	{   390804588794708,	21,	 1,	15,	  7},
++	{   395348846912384,	18,	 1,	15,	  6},
++	{   400000005960464,	17,	 1,	14,	  6},
++	{   404761910438538,	16,	 1,	13,	  6},
++	{   409638553857803,	19,	 1,	13,	  7},
++	{   414634138345718,	19,	 1,	15,	  6},
++	{   419753074645996,	18,	 1,	14,	  6},
++	{   425000011920929,	16,	 1,	15,	  5},
++	{   430379748344421,	17,	 1,	13,	  6},
++	{   435897439718246,	16,	 1,	12,	  6},
++	{   441558450460434,	19,	 1,	14,	  6},
++	{   447368413209915,	17,	 1,	15,	  5},
++	{   453333348035812,	16,	 1,	14,	  5},
++	{   459459453821182,	17,	 1,	12,	  6},
++	{   465753436088562,	20,	 1,	14,	  6},
++	{   472222208976746,	18,	 1,	15,	  5},
++	{   478873252868652,	17,	 1,	14,	  5},
++	{   485714286565781,	16,	 1,	13,	  5},
++	{   492753624916077,	18,	 1,	10,	  7},
++	{   500000000000000,	19,	 1,	15,	  5},
++	{   507462680339813,	18,	 1,	14,	  5},
++	{   515151500701903,	17,	 1,	13,	  5},
++	{   523076951503754,	16,	 1,	12,	  5},
++	{   531250000000000,	16,	 1,	15,	  4},
++	{   539682567119597,	18,	 1,	13,	  5},
++	{   548387110233307,	21,	 1,	15,	  5},
++	{   552631556987762,	 78,	 0,	10,	 13},
++	{   557377040386199,	17,	 1,	12,	  5},
++	{   566666662693024,	16,	 1,	14,	  4},
++	{   571428596973419,	19,	 1,	13,	  5},
++	{   576271176338196,	18,	 1,	10,	  6},
++	{   580645143985748,	18,	 1,	12,	  5},
++	{   586206912994385,	21,	 1,	14,	  5},
++	{   591549277305603,	23,	 1,	 8,	  9},
++	{   596491217613220,	17,	 1,	14,	  4},
++	{   607142865657806,	16,	 1,	13,	  4},
++	{   612903237342834,	19,	 1,	12,	  5},
++	{   618181824684143,	16,	 1,	10,	  5},
++	{   622950792312622,	19,	 1,	15,	  4},
++	{   629629611968994,	18,	 1,	14,	  4},
++	{   634920656681061,	20,	 1,	10,	  6},
++	{   641509413719177,	17,	 1,	13,	  4},
++	{   647058844566345,	 28,	 4,	15,	 14},
++	{   653846144676208,	16,	 1,	12,	  4},
++	{   666666686534882,	19,	 1,	14,	  4},
++	{   680000007152557,	18,	 1,	13,	  4},
++	{   688524603843689,	21,	 1,	15,	  4},
++	{   693877577781677,	17,	 1,	12,	  4},
++	{   701754391193390,	20,	 1,	14,	  4},
++	{   708333313465118,	16,	 1,	15,	  3},
++	{   716981112957001,	19,	 1,	13,	  4},
++	{   723404228687286,	17,	 1,	 9,	  5},
++	{   730769217014313,	18,	 1,	12,	  4},
++	{   739130437374115,	23,	 1,	12,	  5},
++	{   745098054409027,	20,	 1,	13,	  4},
++	{   755555570125580,	16,	 1,	14,	  3},
++	{   765957474708557,	19,	 1,	12,	  4},
++	{   772727251052856,	16,	 1,	10,	  4},
++	{   782608687877655,	21,	 1,	13,	  4},
++	{   790697693824768,	18,	 1,	15,	  3},
++	{   800000011920929,	17,	 1,	14,	  3},
++	{   809523820877075,	16,	 1,	13,	  3},
++	{   818181812763214,	17,	 1,	10,	  4},
++	{   829268276691437,	19,	 1,	15,	  3},
++	{   837209284305573,	20,	 1,	 9,	  5},
++	{   850000023841858,	18,	 1,	14,	  3},
++	{   857142865657806,	17,	 1,	13,	  3},
++	{   863636374473572,	18,	 1,	10,	  4},
++	{   871794879436493,	16,	 1,	12,	  3},
++	{   883720934391022,	19,	 1,	14,	  3},
++	{   894736826419830,	17,	 1,	 9,	  4},
++	{   904761910438538,	18,	 1,	13,	  3},
++	{   918918907642365,	17,	 1,	12,	  3},
++	{   926829278469086,	20,	 1,	14,	  3},
++	{   936170220375061,	22,	 1,	 6,	  7},
++	{   944444417953491,	16,	 1,	11,	  3},
++	{   952380955219269,	19,	 1,	13,	  3},
++	{   959999978542328,	23,	 1,	 9,	  5},
++	{   971428573131561,	18,	 1,	12,	  3},
++	{   978723406791687,	23,	 1,	 6,	  7},
++	{  1000000000000000,	17,	 1,	11,	  3},
++	{  1022222280502318,	22,	 1,	14,	  3},
++	{  1030303001403809,	16,	 1,	10,	  3},
++	{  1043478250503540,	 30,	 6,	15,	13 },
++	{  1052631616592407,	21,	 1,	13,	  3},
++	{  1062500000000000,	16,	 1,	15,	  2},
++	{  1076923131942749,	20,	 1,	12,	  3},
++	{  1085714340209961,	23,	 1,	10,	  4},
++	{  1096774220466614,	17,	 1,	10,	  3},
++	{  1105263113975524,	 78,	 1,	10,	13 },
++	{  1117647051811218,	19,	 1,	11,	  3},
++	{  1133333325386047,	16,	 1,	14,	  2},
++	{  1142857193946838,	23,	 1,	13,	  3},
++	{  1151515126228333,	18,	 1,	10,	  3},
++	{  1161290287971497,	20,	 1,	11,	  3},
++	{  1172413825988770,	22,	 1,	12,	  3},
++	{  1187500000000000,	18,	 1,	15,	  2},
++	{  1200000047683716,	17,	 1,	14,	  2},
++	{  1214285731315613,	16,	 1,	13,	  2},
++	{  1225806474685669,	23,	 1,	12,	  3},
++	{  1241379261016846,	19,	 1,	15,	  2},
++	{  1259259223937988,	18,	 1,	14,	  2},
++	{  1272727251052856,	20,	 1,	10,	  3},
++	{  1285714268684387,	17,	 1,	13,	  2},
++	{  1297297239303588,	 22,	10,	12,	15 },
++	{  1307692289352417,	16,	 1,	12,	  2},
++	{  1333333373069763,	19,	 1,	14,	  2},
++	{  1360000014305115,	18,	 1,	13,	  2},
++	{  1371428608894348,	23,	 1,	 6,	  5},
++	{  1384615421295166,	17,	 1,	12,	  2},
++	{  1399999976158142,	20,	 1,	14,	  2},
++	{  1416666626930237,	16,	 1,	11,	  2},
++	{  1428571462631226,	19,	 1,	13,	  2},
++	{  1440000057220459,	17,	 1,	 4,	  5},
++	{  1461538434028625,	18,	 1,	12,	  2},
++	{  1478260874748230,	19,	 1,	 8,	  3},
++	{  1500000000000000,	17,	 1,	11,	  2},
++	{  1519999980926514,	18,	 1,	 4,	  5},
++	{  1533333301544189,	22,	 1,	14,	  2},
++	{  1545454502105713,	16,	 1,	10,	  2},
++	{  1565217375755310,	21,	 1,	13,	  2},
++	{  1583333373069763,	18,	 1,	11,	  2},
++	{  1600000023841858,	23,	 1,	14,	  2},
++	{  1619047641754150,	20,	 1,	12,	  2},
++	{  1636363625526428,	17,	 1,	10,	  2},
++	{  1652173876762390,	 36,	 4,	 7,	14 },
++	{  1666666626930237,	19,	 1,	11,	  2},
++	{  1679999947547913,	21,	 1,	12,	  2},
++	{  1700000047683716,	16,	 1,	 9,	  2},
++	{  1714285731315613,	23,	 1,	13,	  2},
++	{  1727272748947144,	18,	 1,	10,	  2},
++	{  1750000000000000,	20,	 1,	11,	  2},
++	{  1769230723381042,	22,	 1,	12,	  2},
++	{  1789473652839661,	17,	 1,	 9,	  2},
++	{  1809523820877075,	19,	 1,	10,	  2},
++	{  1826086997985839,	21,	 1,	11,	  2},
++	{  1840000033378601,	23,	 1,	12,	  2},
++	{  1888888835906982,	16,	 1,	 8,	  2},
++	{  1904761910438538,	20,	 1,	10,	  2},
++	{  1919999957084656,	23,	 1,	 4,	  5},
++	{  2000000000000000,	17,	 1,	 8,	  2},
++	{  2086956501007080,	 36,	10,	12,	15 },
++	{  2105263233184814,	20,	 1,	 9,	  2},
++	{  2125000000000000,	16,	 1,	15,	  1},
++	{  2190476179122924,	23,	 1,	10,	  2},
++	{  2210526227951049,	21,	 1,	 9,	  2},
++	{  2235294103622437,	19,	 1,	 8,	  2},
++	{  2266666650772095,	16,	 1,	14,	  1},
++	{  2285714387893677,	23,	 1,	 6,	  3},
++	{  2315789461135864,	22,	 1,	 9,	  2},
++	{  2333333253860474,	20,	 1,	 8,	  2},
++	{  2352941274642944,	 18,	12,	 6,	15 },
++	{  2375000000000000,	18,	 1,	15,	  1},
++	{  2400000095367432,	17,	 1,	14,	  1},
++	{  2428571462631226,	16,	 1,	13,	  1},
++	{  2470588207244873,	 82,	 4,	11,	14 },
++	{  2500000000000000,	19,	 1,	15,	  1},
++	{  2533333301544189,	18,	 1,	14,	  1},
++	{  2571428537368774,	17,	 1,	13,	  1},
++	{  2615384578704834,	16,	 1,	12,	  1},
++	{  2666666746139526,	19,	 1,	14,	  1},
++	{  2714285612106323,	18,	 1,	13,	  1},
++	{  2769230842590332,	17,	 1,	12,	  1},
++	{  2799999952316284,	20,	 1,	14,	  1},
++	{  2833333253860474,	16,	 1,	11,	  1},
++	{  2857142925262451,	19,	 1,	13,	  1},
++	{  2923076868057251,	18,	 1,	12,	  1},
++	{  3000000000000000,	17,	 1,	11,	  1},
++	{  3066666603088379,	22,	 1,	14,	  1},
++	{  3090909004211426,	16,	 1,	10,	  1},
++	{  3142857074737549,	21,	 1,	13,	  1},
++	{  3166666746139526,	18,	 1,	11,	  1},
++	{  3200000047683716,	23,	 1,	14,	  1},
++	{  3230769157409668,	20,	 1,	12,	  1},
++	{  3272727251052856,	17,	 1,	10,	  1},
++	{  3333333253860474,	19,	 1,	11,	  1},
++	{  3400000095367432,	16,	 1,	 9,	  1},
++	{  3428571462631226,	23,	 1,	13,	  1},
++	{  3454545497894287,	18,	 1,	10,	  1},
++	{  3500000000000000,	20,	 1,	11,	  1},
++	{  3538461446762085,	22,	 1,	12,	  1},
++	{  3599999904632568,	17,	 1,	 9,	  1},
++	{  3636363744735718,	19,	 1,	10,	  1},
++	{  3666666746139526,	21,	 1,	11,	  1},
++	{  3777777671813965,	16,	 1,	 8,	  1},
++	{  3818181753158569,	20,	 1,	10,	  1},
++	{  4000000000000000,	17,	 1,	 8,	  1},
++	{  4199999809265136,	20,	 1,	 9,	  1},
++	{  4250000000000000,	16,	 1,	 7,	  1},
++	{  4363636493682861,	23,	 1,	10,	  1},
++	{  4400000095367431,	21,	 1,	 9,	  1},
++	{  4444444656372070,	19,	 1,	 8,	  1},
++	{  4500000000000000,	17,	 1,	 7,	  1},
++	{  4599999904632568,	22,	 1,	 9,	  1},
++	{  4666666507720947,	20,	 1,	 8,	  1},
++	{  4750000000000000,	18,	 1,	 7,	  1},
++	{  4800000190734863,	23,	 1,	 9,	  1},
++	{  4857142925262451,	16,	 1,	 6,	  1},
++	{  5000000000000000,	19,	 1,	 7,	  1},
++	{  5142857074737549,	17,	 1,	 6,	  1},
++	{  5250000000000000,	20,	 1,	 7,	  1},
++	{  5333333492279053,	23,	 1,	 8,	  1},
++	{  5428571224212646,	18,	 1,	 6,	  1},
++	{  5500000000000000,	21,	 1,	 7,	  1},
++	{  5666666507720947,	16,	 1,	 5,	  1},
++	{  5714285850524902,	19,	 1,	 6,	  1},
++	{  6000000000000000,	17,	 1,	 5,	  1},
++	{  6285714149475098,	21,	 1,	 6,	  1},
++	{  6333333492279053,	18,	 1,	 5,	  1},
++	{  6571428775787354,	22,	 1,	 6,	  1},
++	{  6666666507720947,	19,	 1,	 5,	  1},
++	{  6800000190734863,	16,	 1,	 4,	  1},
++	{  6857142925262451,	23,	 1,	 6,	  1},
++	{  7000000000000000,	20,	 1,	 5,	  1},
++	{  7199999809265137,	17,	 1,	 4,	  1},
++	{  7333333492279053,	21,	 1,	 5,	  1},
++	{  7599999904632568,	18,	 1,	 4,	  1},
++	{  7666666507720947,	22,	 1,	 5,	  1},
++	{  8000000000000000,	19,	 1,	 4,	  1},
++	{  8399999618530273,	20,	 1,	 4,	  1},
++	{  8500000000000000,	16,	 1,	 3,	  1},
++	{  8800000190734863,	21,	 1,	 4,	  1},
++	{  9000000000000000,	17,	 1,	 3,	  1},
++	{  9199999809265136,	22,	 1,	 4,	  1},
++	{  9500000000000000,	18,	 1,	 3,	  1},
++	{  9600000381469726,	23,	 1,	 4,	  1},
++	{ 10000000000000000,	19,	 1,	 3,	  1},
++	{ 10500000000000000,	20,	 1,	 3,	  1},
++	{ 11000000000000000,	21,	 1,	 3,	  1},
++	{ 11333333015441894,	16,	 1,	 2,	  1},
++	{ 11500000000000000,	22,	 1,	 3,	  1},
++	{ 12000000000000000,	17,	 1,	 2,	  1},
++	{ 12666666984558106,	18,	 1,	 2,	  1},
++	{ 13333333015441894,	19,	 1,	 2,	  1},
++	{ 14000000000000000,	20,	 1,	 2,	  1},
++	{ 14666666984558106,	21,	 1,	 2,	  1},
++	{ 15333333015441894,	22,	 1,	 2,	  1},
++	{ 16000000000000000,	23,	 1,	 2,	  1},
++	{ 17000000000000000,	16,	 1,	 1,	  1},
++	{ 18000000000000000,	17,	 1,	 1,	  1},
++	{ 19000000000000000,	18,	 1,	 1,	  1},
++	{ 20000000000000000,	19,	 1,	 1,	  1},
++	{ 21000000000000000,	20,	 1,	 1,	  1},
++	{ 22000000000000000,	21,	 1,	 1,	  1},
++	{ 23000000000000000,	22,	 1,	 1,	  1},
++	{ 24000000000000000,	23,	 1,	 1,	  1},
++};
++EXPORT_SYMBOL(ambarella_pll_frac_table);
++
++struct pll_table ambarella_pll_vout_table[AMBARELLA_PLL_VOUT_TABLE_SIZE] = {
++	{  1000000000000000,   9,  0,  0, 1},// 0.000000
++	{  1007407426834106,  46,  2, 13, 1},// 0.026262
++	{  1014925360679626,  65,  1, 12, 1},// 0.045250
++	{  1019999980926514,  50,  0,  4, 1},// 0.000002
++	{  1022556424140930,  91,  0,  8, 1},// 0.032683
++	{  1027027010917664, 112,  0, 10, 1},// 0.023925
++	{  1030303001403809, 102,  0,  9, 1},// 0.029409
++	{  1033783793449402,  30,  0,  2, 1},// 0.043574
++	{  1037037014961243,  82,  0,  7, 1},// 0.044645
++	{  1040816307067871,  51,  0,  4, 1},// 0.078430
++	{  1043478250503540,  72,  0,  6, 1},// 0.059523
++	{  1046153903007507,  67,  1, 12, 1},// 0.000005
++	{  1049999952316284,  20,  0,  1, 1},// 0.000005
++	{  1054263591766357, 115,  0, 10, 1},// 0.026736
++	{  1058823585510254, 126,  0, 11, 1},// 0.046302
++	{  1062500000000000,  84,  0,  7, 1},// 0.000000
++	{  1066666722297668,  31,  0,  2, 1},// 0.000005
++	{  1070866107940674,  74,  0,  6, 1},// 0.052524
++	{  1074626922607422,  42,  0,  3, 1},// 0.034717
++	{  1079365134239197,  53,  0,  4, 1},// 0.058818
++	{  1082089543342590, 118,  0, 10, 1},// 0.025078
++	{  1085106372833252,  46,  2, 12, 1},// 0.045248
++	{  1088000059127808,  86,  0,  7, 1},// 0.045961
++	{  1092857122421265,  50,  2, 13, 1},// 0.000002
++	{  1096774220466614,  34,  4, 15, 1},// 0.275738
++	{  1101449251174927,  10,  0,  0, 1},// 0.131577
++	{  1105691075325012,  58,  2, 15, 1},// 0.050550
++	{  1108695626258850,  18,  6, 11, 1},// 0.032677
++	{  1111888170242310,  88,  0,  7, 1},// 0.055026
++	{  1114754080772400,  77,  0,  6, 1},// 0.042015
++	{  1117647051811218, 122,  0, 10, 1},// 0.047848
++	{  1120567321777344,  55,  0,  4, 1},// 0.050628
++	{  1123966932296753,  72,  1, 12, 1},// 0.079185
++	{  1127118587493896, 123,  0, 10, 1},// 0.013676
++	{  1130434751510620,  48,  2, 12, 1},// 0.029589
++	{  1133333325386047,  33,  0,  2, 1},// 0.000001
++	{  1136752128601074, 124,  0, 10, 1},// 0.034176
++	{  1139705896377563,  56,  0,  4, 1},// 0.025805
++	{  1142857193946838,  79,  0,  6, 1},// 0.000004
++	{  1146551728248596,  85,  1, 14, 1},// 0.010025
++	{  1149606347084045,  22,  0,  1, 1},// 0.034242
++	{  1152542352676392,  74,  1, 12, 1},// 0.113124
++	{  1155555605888367, 103,  0,  8, 1},// 0.000004
++	{  1159090876579285,  57,  0,  4, 1},// 0.078434
++	{  1162393212318420,  92,  0,  7, 1},// 0.009187
++	{  1166666626930237,  34,  0,  2, 1},// 0.000003
++	{  1172413825988770,  42,  2, 10, 1},// 0.026735
++	{  1176923036575317,  50,  2, 12, 1},// 0.000003
++	{  1182608723640442,  70,  0,  5, 1},// 0.061272
++	{  1186046481132507,  82,  0,  6, 1},// 0.028009
++	{  1189189195632935, 106,  0,  8, 1},// 0.025253
++	{  1192982435226440,  30,  4, 12, 1},// 0.056559
++	{  1196850419044495,  11,  0,  0, 1},// 0.263156
++	{  1200000047683716,  11,  0,  0, 1},// 0.000004
++	{  1203539848327637,  11,  0,  0, 1},// 0.294120
++	{  1206896543502808,  12, 12, 13, 1},// 0.020409
++	{  1210084080696106, 120,  0,  9, 1},// 0.006948
++	{  1214285731315613,  84,  0,  6, 1},// 0.000001
++	{  1220338940620422,  60,  0,  4, 1},// 0.027774
++	{  1225225210189819,  48,  0,  3, 1},// 0.018381
++	{  1230769276618958,  79,  1, 12, 1},// 0.000004
++	{  1236363649368286,  67,  1, 10, 1},// 0.000001
++	{  1239669442176819,  61,  0,  4, 1},// 0.026665
++	{  1243902444839478, 111,  0,  8, 1},// 0.043573
++	{  1247706413269043,  16, 10, 14, 1},// 0.083333
++	{  1254098415374756,  68,  1, 10, 1},// 0.035646
++	{  1259259223937988,  62,  0,  4, 1},// 0.058826
++	{  1264462828636169,  58,  2, 13, 1},// 0.014007
++	{  1267857193946838,  28,  6, 15, 1},// 0.070419
++	{  1271028041839600,  88,  0,  6, 1},// 0.031512
++	{  1274999976158142,  50,  0,  3, 1},// 0.000002
++	{  1278846144676208, 114,  0,  8, 1},// 0.083541
++	{  1283018827438354,  76,  0,  5, 1},// 0.024513
++	{  1286956548690796, 102,  0,  7, 1},// 0.042228
++	{  1291262149810791,  70,  1, 10, 1},// 0.027342
++	{  1295238137245178,  68,  2, 15, 1},// 0.114893
++	{  1299145340919495,  12,  0,  0, 1},// 0.065786
++	{  1303921580314636,  18, 10, 15, 1},// 0.178571
++	{  1307692289352417,  84,  1, 12, 1},// 0.000001
++	{  1312500000000000, 104,  0,  7, 1},// 0.000000
++	{  1316831707954407,  78,  0,  5, 1},// 0.012533
++	{  1320388317108154,  65,  0,  4, 1},// 0.029409
++	{  1324324369430542,  52,  0,  3, 1},// 0.051017
++	{  1330000042915344,  18,  6,  9, 1},// 0.000003
++	{  1333333373069763,  39,  0,  2, 1},// 0.000003
++	{  1342105269432068,  22,  6, 11, 1},// 0.032680
++	{  1346534609794617, 100,  1, 14, 1},// 0.009807
++	{  1350000023841858,  26,  0,  1, 1},// 0.000002
++	{  1353982329368591,  87,  1, 12, 1},// 0.010057
++	{  1360000014305115,  67,  0,  4, 1},// 0.000001
++	{  1366071462631226,  40,  0,  2, 1},// 0.043570
++	{  1373737335205078, 102,  1, 14, 1},// 0.029409
++	{  1378378391265869, 123,  0,  8, 1},// 0.043574
++	{  1383928537368774,  82,  0,  5, 1},// 0.043008
++	{  1387755155563354, 110,  0,  7, 1},// 0.018386
++	{  1394495368003845,  18, 10, 14, 1},// 0.083330
++	{  1398058295249939,  13,  0,  0, 1},// 0.138886
++	{  1402061820030212,  13,  0,  0, 1},// 0.147056
++	{  1407407402992249,  60,  2, 12, 1},// 0.020243
++	{  1411764740943909, 126,  0,  8, 1},// 0.046299
++	{  1416666626930237,  84,  0,  5, 1},// 0.000003
++	{  1420560717582703,  70,  0,  4, 1},// 0.039472
++	{  1425742626190186,  56,  0,  3, 1},// 0.052087
++	{  1431578993797302,  92,  1, 12, 1},// 0.056564
++	{  1436170220375061,  78,  1, 10, 1},// 0.013467
++	{  1440000057220459,  71,  0,  4, 1},// 0.000004
++	{  1446808457374573,  30,  6, 14, 1},// 0.009800
++	{  1450549483299255,  28,  0,  1, 1},// 0.037881
++	{  1457142829895020, 101,  0,  6, 1},// 0.000002
++	{  1462365627288818, 116,  0,  7, 1},// 0.009189
++	{  1466666698455811,  43,  0,  2, 1},// 0.000002
++	{  1471153855323792, 102,  0,  6, 1},// 0.018674
++	{  1478260874748230,  68,  2, 13, 1},// 0.021008
++	{  1485436916351318, 103,  0,  6, 1},// 0.018673
++	{  1490196108818054,  81,  1, 10, 1},// 0.047845
++	{  1494505524635315, 111,  1, 14, 1},// 0.078433
++	{  1500000000000000,  14,  0,  0, 1},// 0.000000
++	{  1504950523376465, 112,  1, 14, 1},// 0.114033
++	{  1511111140251160,  67,  1,  8, 1},// 0.000002
++	{  1515789508819580,  90,  0,  5, 1},// 0.057868
++	{  1519999980926514,  75,  0,  4, 1},// 0.000001
++	{  1528089880943298, 106,  0,  6, 1},// 0.031513
++	{  1531914949417114,  48,  4, 15, 1},// 0.043406
++	{  1538461565971375,  99,  1, 12, 1},// 0.000002
++	{  1545454502105713,  84,  1, 10, 1},// 0.000003
++	{  1551020383834839,  30,  0,  1, 1},// 0.065788
++	{  1555555582046509,  69,  1,  8, 1},// 0.000002
++	{  1563218355178833,  85,  1, 10, 1},// 0.026740
++	{  1568181872367859, 101,  1, 12, 1},// 0.066886
++	{  1573033690452576, 117,  1, 14, 1},// 0.019049
++	{  1577319622039795,  40,  4, 12, 1},// 0.025140
++	{  1581395387649536,  22, 10, 15, 1},// 0.009194
++	{  1587628841400146, 126,  0,  7, 1},// 0.008115
++	{  1593750000000000,  84,  2, 15, 1},// 0.000000
++	{  1600000023841858,  15,  0,  0, 1},// 0.000001
++	{  1604166626930237,  74,  2, 13, 1},// 0.185531
++	{  1610526323318481,  22,  6,  9, 1},// 0.032680
++	{  1614583373069763, 112,  0,  6, 1},// 0.018436
++	{  1619047641754150,  36,  6, 15, 1},// 0.018384
++	{  1623529434204102,  72,  1,  8, 1},// 0.080517
++	{  1627659559249878, 113,  0,  6, 1},// 0.056023
++	{  1634408593177795,  48,  0,  2, 1},// 0.065789
++	{  1638554215431213,  70,  2, 12, 1},// 0.005656
++	{  1645161271095276,  73,  1,  8, 1},// 0.043572
++	{  1652173876762390, 123,  1, 14, 1},// 0.070178
++	{  1658536553382874, 115,  0,  6, 1},// 0.084032
++	{  1663043498992920,  18,  6,  7, 1},// 0.032681
++	{  1674418568611145,  66,  0,  3, 1},// 0.034724
++	{  1679012298583984,  46,  4, 13, 1},// 0.026258
++	{  1683544278144836, 100,  0,  5, 1},// 0.012530
++	{  1688888907432556,  75,  1,  8, 1},// 0.000001
++	{  1694117665290833, 126,  1, 14, 1},// 0.046297
++	{  1700000047683716,  16,  0,  0, 1},// 0.000003
++	{  1705128192901611,  90,  2, 15, 1},// 0.065790
++	{  1709677457809448,  56,  2,  9, 1},// 0.018866
++	{  1714285731315613, 119,  0,  6, 1},// 0.000001
++	{  1721518993377686,  30,  4,  8, 1},// 0.040849
++	{  1727272748947144,  94,  1, 10, 1},// 0.000001
++	{  1733333349227905,  51,  0,  2, 1},// 0.000001
++	{  1738636374473572, 112,  1, 12, 1},// 0.010056
++	{  1743589758872986,  92,  2, 15, 1},// 0.009190
++	{  1750000000000000,  34,  0,  1, 1},// 0.000000
++	{  1758620738983154,  87,  0,  4, 1},// 0.078429
++	{  1766233801841736,  52,  0,  2, 1},// 0.024508
++	{  1773333311080933,  37,  6, 14, 1},// 0.000001
++	{  1779069781303406,  82,  2, 13, 1},// 0.028012
++	{  1783783793449402, 106,  0,  5, 1},// 0.025253
++	{  1789473652839661,  22,  6,  8, 1},// 0.032678
++	{  1794871807098389,  40,  6, 15, 1},// 0.062501
++	{  1799999952316284,  17,  0,  0, 1},// 0.000003
++	{  1808219194412231,  30,  6, 11, 1},// 0.006312
++	{  1813333392143250,  67,  3, 14, 1},// 0.000003
++	{  1821428537368774,  84,  2, 13, 1},// 0.000002
++	{  1831325292587280, 118,  1, 12, 1},// 0.030364
++	{  1837837815284729,  48,  2,  7, 1},// 0.018381
++	{  1843373537063599,  58,  4, 15, 1},// 0.020422
++	{  1848837256431580,  36,  0,  1, 1},// 0.062891
++	{  1853658556938171, 101,  1, 10, 1},// 0.047846
++	{  1863013744354248,  40,  4, 10, 1},// 0.033420
++	{  1870129823684692,  16, 10,  9, 1},// 0.006942
++	{  1876543164253235, 121,  1, 12, 1},// 0.020245
++	{  1883116841316223, 112,  0,  5, 1},// 0.011496
++	{  1888888835906982,  84,  1,  8, 1},// 0.000003
++	{  1894736886024475, 100,  2, 15, 1},// 0.052086
++	{  1899999976158142,  18,  0,  0, 1},// 0.000001
++	{  1909090876579285, 104,  1, 10, 1},// 0.000002
++	{  1915493011474609,  82,  2, 12, 1},// 0.005659
++	{  1922077894210815, 124,  1, 12, 1},// 0.051977
++	{  1927536249160767, 105,  1, 10, 1},// 0.013671
++	{  1936708807945251,  70,  2, 10, 1},// 0.017823
++	{  1942857146263123,  67,  1,  6, 1},// 0.000000
++	{  1948717951774597,  38,  0,  1, 1},// 0.065789
++	{  1955882310867310,  87,  1,  8, 1},// 0.016706
++	{  1961538434028625,  84,  2, 12, 1},// 0.000001
++	{  1971014499664307,  68,  1,  6, 1},// 0.021008
++	{  1987012982368469,  52,  2,  7, 1},// 0.024510
++	{  2000000000000000,  19,  0,  0, 1},// 0.000000
++	{  2013157844543457,  22,  6,  7, 1},// 0.032677
++	{  2029850721359253,  28,  6,  9, 1},// 0.007354
++	{  2039999961853027, 101,  0,  4, 1},// 0.000002
++	{  2046153783798218,  37,  6, 12, 1},// 0.000003
++	{  2054054021835327,  88,  2, 12, 1},// 0.010120
++	{  2060606002807617, 102,  0,  4, 1},// 0.029409
++	{  2067567586898804,  61,  0,  2, 1},// 0.043574
++	{  2078125000000000,  16, 10,  8, 1},// 0.016708
++	{  2086956501007080,  72,  1,  6, 1},// 0.059523
++	{  2092307806015015,  67,  3, 12, 1},// 0.000005
++	{  2099999904632568,  20,  0,  0, 1},// 0.000005
++	{  2111111164093018,  94,  1,  8, 1},// 0.000003
++	{  2117647171020508, 126,  0,  5, 1},// 0.046302
++	{  2125000000000000,  84,  0,  3, 1},// 0.000000
++	{  2130434751510620,  70,  2,  9, 1},// 0.020407
++	{  2140845060348511, 106,  0,  4, 1},// 0.039473
++	{  2149253845214844,  42,  0,  1, 1},// 0.034717
++	{  2158730268478394,  36,  6, 11, 1},// 0.018387
++	{  2164179086685181, 100,  2, 13, 1},// 0.004927
++	{  2171428680419922,  75,  1,  6, 1},// 0.000005
++	{  2177419424057007,  97,  1,  8, 1},// 0.016458
++	{  2185714244842529,  50,  2,  6, 1},// 0.000002
++	{  2193548440933228, 116,  2, 15, 1},// 0.009189
++	{  2202898502349854,  21,  0,  0, 1},// 0.131577
++	{  2208955287933350,  80,  2, 10, 1},// 0.006140
++	{  2217391252517700,  18,  6,  5, 1},// 0.032677
++	{  2229508161544800,  77,  1,  6, 1},// 0.042015
++	{  2235294103622437, 122,  1, 10, 1},// 0.047848
++	{  2242424249649048, 100,  1,  8, 1},// 0.090090
++	{  2250000000000000,  44,  0,  1, 1},// 0.000000
++	{  2258064508438110,  78,  1,  6, 1},// 0.040816
++	{  2266666650772095,  67,  0,  2, 1},// 0.000001
++	{  2275861978530884,  90,  0,  3, 1},// 0.037875
++	{  2283581972122192,  98,  2, 12, 1},// 0.045254
++	{  2293103456497192,  85,  3, 14, 1},// 0.010025
++	{  2305084705352783, 122,  2, 15, 1},// 0.050553
++	{  2311475515365601, 103,  1,  8, 1},// 0.015765
++	{  2318181753158569,  84,  2, 10, 1},// 0.000003
++	{  2333333253860474,  69,  0,  2, 1},// 0.000003
++	{  2344827651977539,  85,  2, 10, 1},// 0.026735
++	{  2353846073150635, 101,  2, 12, 1},// 0.000003
++	{  2360655784606934, 117,  0,  4, 1},// 0.027780
++	{  2368421077728271,  76,  3, 12, 1},// 0.034187
++	{  2375000000000000,  94,  0,  3, 1},// 0.000000
++	{  2385964870452881,  61,  4, 12, 1},// 0.056559
++	{  2392857074737549,  66,  4, 13, 1},// 0.000003
++	{  2400000095367432,  23,  0,  0, 1},// 0.000004
++	{  2409836053848267,  52,  4, 10, 1},// 0.030921
++	{  2418181896209717,  37,  6, 10, 1},// 0.000003
++	{  2428571462631226,  84,  1,  6, 1},// 0.000001
++	{  2440677881240845, 121,  0,  4, 1},// 0.027774
++	{  2451612949371338,  48,  0,  1, 1},// 0.065791
++	{  2462962865829468, 114,  2, 13, 1},// 0.053710
++	{  2472727298736572,  67,  3, 10, 1},// 0.000001
++	{  2482758522033691,  90,  2, 10, 1},// 0.037875
++	{  2491803169250488,  22, 12, 11, 1},// 0.005478
++	{  2500000000000000,  24,  0,  0, 1},// 0.000000
++	{  2508196830749512,  42,  6, 11, 1},// 0.005442
++	{  2518518447875977,  30, 12, 15, 1},// 0.009194
++	{  2526315689086914, 100,  0,  3, 1},// 0.052079
++	{  2533333301544189,  75,  0,  2, 1},// 0.000001
++	{  2542372941970825,  88,  1,  6, 1},// 0.019045
++	{  2549999952316284,  50,  0,  1, 1},// 0.000002
++	{  2557692289352417, 114,  1,  8, 1},// 0.083541
++	{  2566037654876709,  76,  0,  2, 1},// 0.024513
++	{  2576271295547485,  66,  4, 12, 1},// 0.025299
++	{  2586206912994385,  96,  3, 14, 1},// 0.017777
++	{  2593220233917236, 120,  2, 13, 1},// 0.014002
++	{  2599999904632568,  25,  0,  0, 1},// 0.000004
++	{  2607843160629272, 112,  2, 12, 1},// 0.005785
++	{  2615384578704834,  84,  3, 12, 1},// 0.000001
++	{  2625000000000000, 104,  0,  3, 1},// 0.000000
++	{  2637931108474731,  48,  6, 12, 1},// 0.020108
++	{  2647058725357056,  85,  3, 12, 1},// 0.034184
++	{  2660000085830688,  18,  6,  4, 1},// 0.000003
++	{  2666666746139526,  79,  0,  2, 1},// 0.000003
++	{  2684210538864136,  22,  6,  5, 1},// 0.032680
++	{  2692307710647583,  69,  4, 12, 1},// 0.000001
++	{  2701754331588745,  26,  0,  0, 1},// 0.064933
++	{  2711538553237915, 121,  1,  8, 1},// 0.015764
++	{  2720000028610229,  67,  1,  4, 1},// 0.000001
++	{  2732142925262451,  81,  0,  2, 1},// 0.043570
++	{  2745098114013672,  18, 12,  8, 1},// 0.023812
++	{  2755102157592773, 123,  1,  8, 1},// 0.016457
++	{  2763636350631714,  75,  3, 10, 1},// 0.000000
++	{  2775510311126709, 110,  0,  3, 1},// 0.018386
++	{  2785714387893677,  64,  2,  6, 1},// 0.000004
++	{  2799999952316284,  27,  0,  0, 1},// 0.000002
++	{  2807692289352417,  72,  4, 12, 1},// 0.000001
++	{  2814814805984497, 121,  2, 12, 1},// 0.020243
++	{  2823529481887817, 126,  1,  8, 1},// 0.046299
++	{  2833333253860474,  84,  0,  2, 1},// 0.000003
++	{  2843137264251709,  90,  4, 15, 1},// 0.021551
++	{  2857142925262451,  99,  1,  6, 1},// 0.000002
++	{  2867924451828003,  50,  8, 15, 1},// 0.028786
++	{  2880000114440918,  71,  1,  4, 1},// 0.000004
++	{  2893616914749146,  61,  6, 14, 1},// 0.009800
++	{  2905660390853882,  92,  4, 15, 1},// 0.020292
++	{  2913043498992920, 101,  1,  6, 1},// 0.042643
++	{  2923076868057251,  94,  3, 12, 1},// 0.000002
++	{  2933333396911621,  87,  0,  2, 1},// 0.000002
++	{  2942307710647583, 102,  1,  6, 1},// 0.018674
++	{  2956521749496460,  42, 10, 15, 1},// 0.009192
++	{  2980392217636108,  52,  8, 15, 1},// 0.028781
++	{  3000000000000000,  29,  0,  0, 1},// 0.000000
++	{  3022222280502319,  67,  3,  8, 1},// 0.000002
++	{  3039999961853027,  75,  1,  4, 1},// 0.000001
++	{  3059999942779541,  50,  2,  4, 1},// 0.000002
++	{  3069767475128174,  56,  6, 12, 1},// 0.017484
++	{  3079999923706055,  76,  1,  4, 1},// 0.000002
++	{  3090909004211426,  84,  3, 10, 1},// 0.000003
++	{  3102040767669678,  30,  0,  0, 1},// 0.065788
++	{  3111111164093018,  69,  3,  8, 1},// 0.000002
++	{  3122448921203613,  57,  6, 12, 1},// 0.020112
++	{  3130434751510620,  36, 10, 12, 1},// 0.010685
++	{  3142857074737549, 109,  1,  6, 1},// 0.000002
++	{  3152173995971680,  42, 10, 14, 1},// 0.036779
++	{  3162790775299072,  22, 10,  7, 1},// 0.009194
++	{  3173913002014160, 118,  3, 14, 1},// 0.018264
++	{  3187500000000000,  84,  2,  7, 1},// 0.000000
++	{  3200000047683716,  31,  0,  0, 1},// 0.000001
++	{  3208333253860474,  76,  4, 11, 1},// 0.000002
++	{  3219512224197388,  22,  6,  4, 1},// 0.015151
++	{  3229166746139526, 112,  1,  6, 1},// 0.018436
++	{  3238095283508301,  36,  6,  7, 1},// 0.018384
++	{  3255319118499756,  46,  8, 12, 1},// 0.045248
++	{  3272727251052856, 119,  2, 10, 1},// 0.000001
++	{  3285714387893677, 114,  1,  6, 1},// 0.000003
++	{  3295454502105713,  37, 12, 14, 1},// 0.064367
++	{  3304347753524780, 123,  3, 14, 1},// 0.070178
++	{  3317073106765747,  72,  4, 10, 1},// 0.033424
++	{  3326086997985840,  18,  6,  3, 1},// 0.032681
++	{  3348837137222290,  66,  0,  1, 1},// 0.034724
++	{  3365853548049927, 100,  0,  2, 1},// 0.024158
++	{  3377777814865112,  75,  3,  8, 1},// 0.000001
++	{  3391304254531860,  36, 10, 11, 1},// 0.010687
++	{  3400000095367432,  33,  0,  0, 1},// 0.000003
++	{  3410256385803223,  30, 10,  9, 1},// 0.007518
++	{  3428571462631226, 119,  1,  6, 1},// 0.000001
++	{  3444444417953491,  61,  4,  8, 1},// 0.000001
++	{  3454545497894287,  94,  3, 10, 1},// 0.000001
++	{  3466666698455811, 103,  0,  2, 1},// 0.000001
++	{  3477272748947144, 112,  3, 12, 1},// 0.010056
++	{  3487179517745972,  92,  2,  7, 1},// 0.009190
++	{  3500000000000000,  34,  0,  0, 1},// 0.000000
++	{  3512195110321045,  78,  3,  8, 1},// 0.030864
++	{  3522727251052856,  46,  2,  3, 1},// 0.064517
++	{  3534883737564087,  98,  4, 13, 1},// 0.023496
++	{  3545454502105713,  77,  4, 10, 1},// 0.000001
++	{  3558139562606812,  60,  6, 11, 1},// 0.005446
++	{  3567567586898804, 106,  0,  2, 1},// 0.025253
++	{  3578947305679321,  45,  6,  8, 1},// 0.032678
++	{  3589743614196777,  78,  4, 10, 1},// 0.032467
++	{  3599999904632568,  35,  0,  0, 1},// 0.000003
++	{  3609755992889404,  64,  4,  8, 1},// 0.037540
++	{  3619047641754150,  30,  6,  5, 1},// 0.065790
++	{  3631578922271729, 117,  3, 12, 1},// 0.022296
++	{  3642857074737549,  84,  2,  6, 1},// 0.000002
++	{  3658536672592163, 127,  1,  6, 1},// 0.038098
++	{  3675675630569458,  48,  2,  3, 1},// 0.018381
++	{  3692307710647583, 119,  3, 12, 1},// 0.000000
++	{  3707317113876343,  88,  4, 11, 1},// 0.027411
++	{  3717948675155640,  92,  1,  4, 1},// 0.055174
++	{  3731707334518433,  96,  4, 12, 1},// 0.025139
++	{  3743589639663696, 102,  3, 10, 1},// 0.049816
++	{  3756097555160522,  25, 12,  8, 1},// 0.014430
++	{  3777777671813965,  84,  3,  8, 1},// 0.000003
++	{  3789473772048950,  30, 10,  8, 1},// 0.015434
++	{  3799999952316284,  37,  0,  0, 1},// 0.000001
++	{  3810810804367065,  48,  6,  8, 1},// 0.007880
++	{  3825000047683716,  50,  2,  3, 1},// 0.000001
++	{  3837837934494019,  95,  1,  4, 1},// 0.056336
++	{  3849999904632568,  76,  0,  1, 1},// 0.000002
++	{  3868421077728271,  42,  8,  9, 1},// 0.040816
++	{  3885714292526245,  67,  3,  6, 1},// 0.000000
++	{  3897435903549194,  38,  0,  0, 1},// 0.065789
++	{  3911764621734619,  87,  3,  8, 1},// 0.016706
++	{  3923076868057251,  97,  1,  4, 1},// 0.078430
++	{  3948717832565308,  78,  0,  1, 1},// 0.032470
++	{  3972972869873047,  52,  2,  3, 1},// 0.051023
++	{  4000000000000000,  39,  0,  0, 1},// 0.000000
++	{  4026315689086914,  22,  6,  3, 1},// 0.032677
++	{  4052631378173828,  80,  0,  1, 1},// 0.064930
++	{  4083333492279053,  48,  4,  5, 1},// 0.000004
++	{  4108108043670654, 112,  3, 10, 1},// 0.023925
++	{  4121212005615234,  52,  6,  8, 1},// 0.024513
++	{  4135135173797607,  90,  4, 10, 1},// 0.029708
++	{  4156250000000000,  33, 10,  8, 1},// 0.016708
++	{  4166666507720947, 124,  0,  2, 1},// 0.000004
++	{  4181818008422852, 114,  3, 10, 1},// 0.000004
++	{  4199999809265137,  41,  0,  0, 1},// 0.000005
++	{  4222222328186035,  94,  3,  8, 1},// 0.000003
++	{  4235294342041016, 126,  0,  2, 1},// 0.046302
++	{  4250000000000000,  84,  0,  1, 1},// 0.000000
++	{  4264705657958984,  66,  6, 10, 1},// 0.025073
++	{  4277777671813965,  76,  4,  8, 1},// 0.000002
++	{  4290322780609131,  38, 10,  9, 1},// 0.007523
++	{  4312500000000000, 114,  2,  7, 1},// 0.000000
++	{  4323529243469238, 107,  1,  4, 1},// 0.081629
++	{  4342857360839844,  75,  3,  6, 1},// 0.000005
++	{  4354838848114014,  97,  3,  8, 1},// 0.016458
++	{  4371428489685059, 101,  2,  6, 1},// 0.000002
++	{  4387096881866455, 116,  2,  7, 1},// 0.009189
++	{  4400000095367432,  43,  0,  0, 1},// 0.000002
++	{  4411764621734619,  62,  6,  9, 1},// 0.039998
++	{  4433333396911621,  18,  6,  2, 1},// 0.000001
++	{  4454545497894287,  97,  4, 10, 1},// 0.000001
++	{  4470588207244873, 122,  3, 10, 1},// 0.047848
++	{  4484848499298096, 100,  3,  8, 1},// 0.090090
++	{  4500000000000000,  44,  0,  0, 1},// 0.000000
++	{  4516129016876221,  78,  3,  6, 1},// 0.040816
++	{  4533333301544189,  67,  1,  2, 1},// 0.000001
++	{  4551723957061768,  90,  0,  1, 1},// 0.037875
++	{  4586206912994385, 106,  2,  6, 1},// 0.010741
++	{  4606060504913330,  82,  4,  8, 1},// 0.109651
++	{  4620689868927002,  76,  2,  4, 1},// 0.014930
++	{  4636363506317139,  52,  6,  7, 1},// 0.024513
++	{  4666666507720947,  69,  1,  2, 1},// 0.000003
++	{  4689655303955078,  66,  6,  9, 1},// 0.007350
++	{  4714285850524902, 109,  2,  6, 1},// 0.000003
++	{  4727272510528564,  62,  2,  3, 1},// 0.048072
++	{  4750000000000000,  94,  0,  1, 1},// 0.000000
++	{  4781250000000000,  40,  6,  5, 1},// 0.043573
++	{  4800000190734863,  47,  0,  0, 1},// 0.000004
++	{  4812500000000000,  76,  4,  7, 1},// 0.000000
++	{  4827586174011230,  25, 12,  6, 1},// 0.020409
++	{  4843750000000000, 108,  3,  8, 1},// 0.014337
++	{  4857142925262451,  84,  3,  6, 1},// 0.000001
++	{  4875000000000000,  64,  2,  3, 1},// 0.000000
++	{  4888888835906982, 109,  3,  8, 1},// 0.000001
++	{  4903225898742676,  48,  0,  0, 1},// 0.065791
++	{  4935483932495117,  78,  4,  7, 1},// 0.040848
++	{  4965517044067383,  70,  6,  9, 1},// 0.090282
++	{  5000000000000000,  49,  0,  0, 1},// 0.000000
++	{  5037036895751953,  30, 12,  7, 1},// 0.009194
++	{  5066666603088379,  75,  1,  2, 1},// 0.000001
++	{  5099999904632568,  50,  0,  0, 1},// 0.000002
++	{  5115384578704834, 114,  3,  8, 1},// 0.083541
++	{  5129032135009766,  40,  4,  3, 1},// 0.078614
++	{  5142857074737549, 119,  2,  6, 1},// 0.000001
++	{  5166666507720947,  30,  4,  2, 1},// 0.000003
++	{  5185184955596924, 120,  2,  6, 1},// 0.010209
++	{  5199999809265137,  51,  0,  0, 1},// 0.000004
++	{  5214285850524902,  72,  4,  6, 1},// 0.000003
++	{  5230769157409668, 121,  2,  6, 1},// 0.042015
++	{  5250000000000000, 104,  0,  1, 1},// 0.000000
++	{  5275862216949463,  94,  4,  8, 1},// 0.036308
++	{  5300000190734863,  52,  0,  0, 1},// 0.000004
++	{  5320000171661377,  37,  6,  4, 1},// 0.000003
++	{  5333333492279053,  79,  1,  2, 1},// 0.000003
++	{  5357142925262451, 124,  2,  6, 1},// 0.000001
++	{  5384615421295166,  28, 12,  6, 1},// 0.020407
++	{  5400000095367432,  53,  0,  0, 1},// 0.000002
++	{  5423077106475830, 121,  3,  8, 1},// 0.015764
++	{  5440000057220459,  67,  3,  4, 1},// 0.000001
++	{  5464285850524902,  81,  1,  2, 1},// 0.043570
++	{  5481481552124023,  46,  6,  5, 1},// 0.033782
++	{  5500000000000000,  54,  0,  0, 1},// 0.000000
++	{  5519999980926514,  91,  2,  4, 1},// 0.000000
++	{  5538461685180664,  96,  3,  6, 1},// 0.079362
++	{  5555555343627930, 124,  3,  8, 1},// 0.000004
++	{  5571428775787354,  77,  4,  6, 1},// 0.000004
++	{  5599999904632568,  55,  0,  0, 1},// 0.000002
++	{  5615384578704834,  74,  2,  3, 1},// 0.171234
++	{  5629629611968994,  12, 12,  2, 1},// 0.065790
++	{  5666666507720947,  84,  1,  2, 1},// 0.000003
++	{  5703703880310059,  56,  0,  0, 1},// 0.064938
++	{  5739130496978760,  40,  6,  4, 1},// 0.015150
++	{  5760000228881836,  95,  2,  4, 1},// 0.000004
++	{  5782608509063721,  80,  4,  6, 1},// 0.053709
++	{  5800000190734863,  57,  0,  0, 1},// 0.000003
++	{  5826086997985840, 101,  3,  6, 1},// 0.042643
++	{  5846153736114502, 116,  0,  1, 1},// 0.065791
++	{  5869565010070801,  87,  1,  2, 1},// 0.049379
++	{  5884615421295166, 102,  3,  6, 1},// 0.018674
++	{  5913043498992920,  42, 10,  7, 1},// 0.009192
++	{  5961538314819336,  52,  8,  7, 1},// 0.016131
++	{  6000000000000000,  59,  0,  0, 1},// 0.000000
++	{  6045454502105713,  46,  8,  6, 1},// 0.042964
++	{  6079999923706055,  75,  3,  4, 1},// 0.000001
++	{  6119999885559082, 101,  2,  4, 1},// 0.000002
++	{  6136363506317139,  91,  1,  2, 1},// 0.049381
++	{  6159999847412109,  76,  3,  4, 1},// 0.000002
++	{  6181818008422852,  52,  6,  5, 1},// 0.024513
++	{  6199999809265137,  61,  0,  0, 1},// 0.000003
++	{  6239999771118164, 103,  2,  4, 1},// 0.000004
++	{  6260869503021240,  72,  5,  6, 1},// 0.059523
++	{  6285714149475098, 109,  3,  6, 1},// 0.000002
++	{  6304347991943359,  62,  0,  0, 1},// 0.068968
++	{  6333333492279053,  94,  1,  2, 1},// 0.000003
++	{  6375000000000000,  84,  2,  3, 1},// 0.000000
++	{  6391304492950439,  63,  0,  0, 1},// 0.136052
++	{  6416666507720947,  76,  4,  5, 1},// 0.000002
++	{  6434782505035400,  45,  6,  4, 1},// 0.081083
++	{  6458333492279053, 112,  3,  6, 1},// 0.018436
++	{  6476190567016602,  36,  6,  3, 1},// 0.018384
++	{  6500000000000000,  64,  0,  0, 1},// 0.000000
++	{  6521739006042480,  86,  2,  3, 1},// 0.050002
++	{  6545454502105713, 108,  2,  4, 1},// 0.083333
++	{  6571428775787354, 114,  3,  6, 1},// 0.000003
++	{  6590909004211426,  78,  4,  5, 1},// 0.114941
++	{  6608695507049561,  65,  0,  0, 1},// 0.131577
++	{  6652173995971680,  18,  6,  1, 1},// 0.032681
++	{  6681818008422852, 116,  3,  6, 1},// 0.058312
++	{  6699999809265137,  66,  0,  0, 1},// 0.000003
++	{  6727272510528564, 100,  1,  2, 1},// 0.090093
++	{  6750000000000000,  44,  2,  1, 1},// 0.000000
++	{  6782608509063721,  36, 10,  5, 1},// 0.010687
++	{  6800000190734863,  67,  0,  0, 1},// 0.000003
++	{  6818181991577148,  30, 10,  4, 1},// 0.026664
++	{  6857142925262451, 119,  3,  6, 1},// 0.000001
++	{  6909090995788574, 120,  3,  6, 1},// 0.075187
++	{  6954545497894287, 115,  2,  4, 1},// 0.078431
++	{  7000000000000000,  69,  0,  0, 1},// 0.000000
++	{  7045454502105713,  46,  2,  1, 1},// 0.064517
++	{  7090909004211426, 123,  3,  6, 1},// 0.073259
++	{  7157894611358643,  12, 10,  1, 1},// 0.110292
++	{  7181818008422852,  40,  6,  3, 1},// 0.094934
++	{  7199999809265137,  71,  0,  0, 1},// 0.000003
++	{  7238095283508301,  30,  6,  2, 1},// 0.065790
++	{  7263157844543457, 120,  2,  4, 1},// 0.043478
++	{  7285714149475098,  90,  3,  4, 1},// 0.078430
++	{  7349999904632568,  48,  2,  1, 1},// 0.000001
++	{  7368421077728271,  16, 12,  2, 1},// 0.023810
++	{  7388888835906982, 122,  2,  4, 1},// 0.120300
++	{  7428571224212646,  98,  2,  3, 1},// 0.048074
++	{  7473684310913086,  22, 12,  3, 1},// 0.017604
++	{  7500000000000000,  74,  0,  0, 1},// 0.000000
++	{  7523809432983398,  42,  6,  3, 1},// 0.015824
++	{  7555555343627930, 125,  2,  4, 1},// 0.058826
++	{  7578947544097900, 100,  2,  3, 1},// 0.052086
++	{  7599999904632568,  75,  0,  0, 1},// 0.000001
++	{  7650000095367432,  50,  2,  1, 1},// 0.000001
++	{  7699999809265137,  76,  0,  0, 1},// 0.000002
++	{  7736842155456543,  42,  8,  4, 1},// 0.040816
++	{  7777777671813965,  96,  3,  4, 1},// 0.228570
++	{  7800000190734863,  77,  0,  0, 1},// 0.000002
++	{  7823529243469238,  66,  6,  5, 1},// 0.087717
++	{  7894736766815186,  78,  0,  0, 1},// 0.066668
++	{  7941176414489746, 118,  1,  2, 1},// 0.098765
++	{  8000000000000000,  79,  0,  0, 1},// 0.000000
++	{  8052631378173828,  22,  6,  1, 1},// 0.032677
++	{  8105262756347656,  80,  0,  0, 1},// 0.064930
++	{  8166666984558105,  48,  4,  2, 1},// 0.000004
++	{  8210526466369629,  81,  0,  0, 1},// 0.128207
++	{  8235294342041016,  18, 12,  2, 1},// 0.023812
++	{  8312500000000000, 103,  3,  4, 1},// 0.090226
++	{  8333333015441895, 124,  1,  2, 1},// 0.000004
++	{  8368420600891113,  66,  4,  3, 1},// 0.078622
++	{  8444444656372070,  12, 12,  1, 1},// 0.065787
++	{  8470588684082031, 126,  1,  2, 1},// 0.046302
++	{  8500000000000000,  84,  0,  0, 1},// 0.000000
++	{  8529411315917969, 127,  1,  2, 1},// 0.045982
++	{  8555555343627930, 106,  3,  4, 1},// 0.051951
++	{  8588234901428223,  38, 10,  4, 1},// 0.095886
++	{  8625000000000000, 114,  2,  3, 1},// 0.000000
++	{  8647058486938477, 107,  3,  4, 1},// 0.081629
++	{  8705882072448730,  86,  0,  0, 1},// 0.067564
++	{  8750000000000000,  34,  4,  1, 1},// 0.000000
++	{  8777777671813965, 116,  2,  3, 1},// 0.031644
++	{  8800000190734863,  87,  0,  0, 1},// 0.000002
++	{  8823529243469238,  62,  6,  4, 1},// 0.039998
++	{  8866666793823242,  37,  6,  2, 1},// 0.000001
++	{  8941176414489746,  66,  3,  2, 1},// 0.087719
++	{  9000000000000000,  89,  0,  0, 1},// 0.000000
++	{  9066666603088379,  67,  3,  2, 1},// 0.000001
++	{  9117647171020508, 113,  3,  4, 1},// 0.025805
++	{  9187500000000000,  50,  8,  4, 1},// 0.081633
++	{  9250000000000000,  36,  4,  1, 1},// 0.000000
++	{  9294117927551270,  92,  0,  0, 1},// 0.063288
++	{  9333333015441895,  69,  3,  2, 1},// 0.000003
++	{  9375000000000000, 124,  2,  3, 1},// 0.000000
++	{  9399999618530273,  93,  0,  0, 1},// 0.000004
++	{  9428571701049805,  28, 12,  3, 1},// 0.037882
++	{  9466666221618652,  70,  3,  2, 1},// 0.000005
++	{  9500000000000000,  94,  0,  0, 1},// 0.000000
++	{  9562500000000000,  40,  6,  2, 1},// 0.043573
++	{  9600000381469727,  95,  0,  0, 1},// 0.000004
++	{  9625000000000000,  76,  4,  3, 1},// 0.000000
++	{  9666666984558105,  57,  4,  2, 1},// 0.000003
++	{  9714285850524902,  80,  5,  4, 1},// 0.058822
++	{  9750000000000000,  64,  2,  1, 1},// 0.000000
++	{  9800000190734863,  97,  0,  0, 1},// 0.000002
++	{  9857142448425293,  73,  3,  2, 1},// 0.096623
++	{  9937500000000000,  70,  6,  4, 1},// 0.025157
++	{ 10000000000000000,  99,  0,  0, 1},// 0.000000
++	{ 10071428298950195,  30, 12,  3, 1},// 0.035464
++	{ 10133333206176758,  75,  3,  2, 1},// 0.000001
++	{ 10199999809265137, 101,  0,  0, 1},// 0.000002
++	{ 10230769157409668,  40,  4,  1, 1},// 0.187971
++	{ 10285714149475098, 102,  0,  0, 1},// 0.138890
++	{ 10357142448425293,  68,  2,  1, 1},// 0.068962
++	{ 10399999618530273, 103,  0,  0, 1},// 0.000004
++	{ 10428571701049805,  18, 10,  1, 1},// 0.205477
++	{ 10461538314819336,  18, 10,  1, 1},// 0.110293
++	{ 10500000000000000, 104,  0,  0, 1},// 0.000000
++	{ 10533333778381348,  78,  3,  2, 1},// 0.000004
++	{ 10571428298950195,  46,  8,  3, 1},// 0.033786
++	{ 10615385055541992,  84,  4,  3, 1},// 0.090576
++	{ 10714285850524902,  38, 10,  3, 1},// 0.099999
++	{ 10769230842590332,  42,  4,  1, 1},// 0.178572
++	{ 10857142448425293,  30,  6,  1, 1},// 0.065786
++	{ 10928571701049805,  81,  3,  2, 1},// 0.043570
++	{ 11000000000000000, 109,  0,  0, 1},// 0.000000
++	{ 11076923370361328,  82,  3,  2, 1},// 0.092595
++	{ 11142857551574707,  88,  4,  3, 1},// 0.160260
++	{ 11250000000000000,  74,  2,  1, 1},// 0.000000
++	{ 11285714149475098,  40, 10,  3, 1},// 0.094936
++	{ 11333333015441895,  84,  3,  2, 1},// 0.000003
++	{ 11384614944458008,  90,  4,  3, 1},// 0.084456
++	{ 11500000000000000, 114,  0,  0, 1},// 0.000000
++	{ 11538461685180664,  76,  2,  1, 1},// 0.099999
++	{ 11692307472229004, 116,  0,  0, 1},// 0.065791
++	{ 11769230842590332,  46,  4,  1, 1},// 0.163399
++	{ 11846154212951660,  78,  2,  1, 1},// 0.032464
++	{ 11923076629638672,  52,  8,  3, 1},// 0.016131
++	{ 12000000000000000, 119,  0,  0, 1},// 0.000000
++	{ 12090909004211426, 120,  0,  0, 1},// 0.075189
++	{ 12181818008422852,  72,  4,  2, 1},// 0.124377
++	{ 12250000000000000,  48,  4,  1, 1},// 0.000000
++	{ 12362637333333333,  52,  6,  2, 1},// 0.032593 vout
++	{ 12363636016845703,  52,  6,  2, 1},// 0.024513
++	{ 12375000000000000,  98,  4,  3, 1},// 0.000000 vout
++	{ 12500000000000000, 124,  0,  0, 1},// 0.000000
++	{ 12545454978942871,  93,  3,  2, 1},// 0.096622
++	{ 12666666984558105,  94,  3,  2, 1},// 0.000003
++	{ 12750000000000000,  84,  2,  1, 1},// 0.000000
++	{ 12833333015441895,  76,  4,  2, 1},// 0.000002
++	{ 12916666984558105,  96,  3,  2, 1},// 0.129030
++	{ 13000000000000000,  64,  1,  0, 1},// 0.000000
++	{ 13090909004211426,  97,  3,  2, 1},// 0.185185
++	{ 13166666984558105,  78,  4,  2, 1},// 0.000002
++	{ 13199999809265137,  65,  1,  0, 1},// 0.000001
++	{ 13250000000000000,  52,  4,  1, 1},// 0.000000
++	{ 13300000190734863,  18,  6,  0, 1},// 0.000001
++	{ 13363636016845703,  88,  2,  1, 1},// 0.102038
++	{ 13399999618530273,  66,  1,  0, 1},// 0.000003
++	{ 13454545021057129, 100,  3,  2, 1},// 0.090093
++	{ 13500000000000000,  44,  2,  0, 1},// 0.000000
++	{ 13600000381469727,  67,  1,  0, 1},// 0.000003
++	{ 13636363983154297,  90,  2,  1, 1},// 0.099997
++	{ 13818181991577148,  82,  4,  2, 1},// 0.109648
++	{ 13909090995788574,  37, 10,  2, 1},// 0.174291
++	{ 14000000000000000,  69,  1,  0, 1},// 0.000000
++	{ 14090909004211426,  46,  2,  0, 1},// 0.064517
++	{ 14181818008422852,  84,  4,  2, 1},// 0.106836
++	{ 14363636016845703,  40,  6,  1, 1},// 0.094934
++	{ 14399999618530273,  71,  1,  0, 1},// 0.000003
++	{ 14454545021057129,  61,  6,  2, 1},// 0.083860
++	{ 14500000000000000,  28,  4,  0, 1},// 0.000000
++	{ 14600000381469727,  72,  1,  0, 1},// 0.000003
++	{ 14699999809265137,  48,  2,  0, 1},// 0.000001
++	{ 14777777671813965,  73,  1,  0, 1},// 0.150377
++	{ 14888889312744141,  98,  2,  1, 1},// 0.261197
++	{ 15000000000000000,  74,  1,  0, 1},// 0.000000
++	{ 15111110687255859, 100,  2,  1, 1},// 0.257356
++	{ 15199999809265137,  75,  1,  0, 1},// 0.000001
++	{ 15300000190734863,  50,  2,  0, 1},// 0.000001
++	{ 15399999618530273,  76,  1,  0, 1},// 0.000002
++	{ 15500000000000000,  30,  4,  0, 1},// 0.000000
++	{ 15555555343627930,  77,  1,  0, 1},// 0.285716
++	{ 15600000381469727,  77,  1,  0, 1},// 0.000002
++	{ 15666666984558105,  93,  4,  2, 1},// 0.000002
++	{ 15777777671813965,  42, 10,  2, 1},// 0.070422
++	{ 15899999618530273,  52,  2,  0, 1},// 0.000002
++	{ 16000000000000000,  79,  1,  0, 1},// 0.000000
++	{ 16111110687255859,  22,  6,  0, 1},// 0.068963
++	{ 16222221374511719,  80,  1,  0, 1},// 0.136981
++	{ 16333333969116211,  97,  4,  2, 1},// 0.000004
++	{ 16444444656372070,  46,  6,  1, 1},// 0.033782
++	{ 16500000000000000,  54,  2,  0, 1},// 0.000000
++	{ 16625000000000000,  82,  1,  0, 1},// 0.150376
++	{ 16666666030883789, 124,  3,  2, 1},// 0.000004
++	{ 16750000000000000,  66,  4,  1, 1},// 0.000000
++	{ 16888889312744141,  12, 12,  0, 1},// 0.065787
++	{ 17000000000000000,  84,  1,  0, 1},// 0.000000
++	{ 17111110687255859,  56,  2,  0, 1},// 0.064933
++	{ 17250000000000000, 114,  2,  1, 1},// 0.000000
++	{ 17333333969116211,  86,  1,  0, 1},// 0.384612
++	{ 17500000000000000,  34,  4,  0, 1},// 0.000000
++	{ 17555555343627930, 116,  2,  1, 1},// 0.031644
++	{ 17625000000000000,  87,  1,  0, 1},// 0.141844
++	{ 17750000000000000,  70,  4,  1, 1},// 0.000000
++	{ 18000000000000000,  89,  1,  0, 1},// 0.000000
++	{ 18125000000000000, 120,  2,  1, 1},// 0.137931
++	{ 18250000000000000,  72,  4,  1, 1},// 0.000000
++	{ 18375000000000000,  91,  1,  0, 1},// 0.136054
++	{ 18500000000000000,  36,  4,  0, 1},// 0.000000
++	{ 18750000000000000, 124,  2,  1, 1},// 0.000000
++	{ 18857143402099609,  28, 12,  1, 1},// 0.037882
++	{ 19000000000000000,  94,  1,  0, 1},// 0.000000
++	{ 19125000000000000,  95,  1,  0, 1},// 0.392157
++	{ 19250000000000000,  76,  4,  1, 1},// 0.000000
++	{ 19375000000000000,  96,  1,  0, 1},// 0.129032
++	{ 19428571701049805,  96,  1,  0, 1},// 0.147060
++	{ 19500000000000000,  64,  2,  0, 1},// 0.000000
++	{ 19714284896850586,  78,  4,  1, 1},// 0.181164
++	{ 19875000000000000,  98,  1,  0, 1},// 0.377358
++	{ 20000000000000000,  99,  1,  0, 1},// 0.000000
++	{ 20142856597900391,  30, 12,  1, 1},// 0.035464
++	{ 20285715103149414,  28,  6,  0, 1},// 0.070419
++	{ 20571428298950195, 102,  1,  0, 1},// 0.138890
++	{ 20714284896850586,  68,  2,  0, 1},// 0.068962
++	{ 20857143402099609,  18, 10,  0, 1},// 0.205477
++	{ 21000000000000000, 104,  1,  0, 1},// 0.000000
++	{ 21142856597900391,  46,  8,  1, 1},// 0.033786
++	{ 21428571701049805,  38, 10,  1, 1},// 0.099999
++	{ 21714284896850586,  30,  6,  0, 1},// 0.065786
++	{ 21857143402099609,  72,  2,  0, 1},// 0.196076
++	{ 22000000000000000, 109,  1,  0, 1},// 0.000000
++	{ 22166666030883789, 110,  1,  0, 1},// 0.150379
++	{ 22285715103149414,  88,  4,  1, 1},// 0.160260
++	{ 22500000000000000,  74,  2,  0, 1},// 0.000000
++	{ 22571428298950195,  40, 10,  1, 1},// 0.094936
++	{ 22666666030883789, 112,  1,  0, 1},// 0.294115
++	{ 23000000000000000, 114,  1,  0, 1},// 0.000000
++	{ 23333333969116211, 116,  1,  0, 1},// 0.285712
++	{ 23500000000000000,  46,  4,  0, 1},// 0.000000
++	{ 23666666030883789,  42, 10,  1, 1},// 0.070420
++	{ 24000000000000000, 119,  1,  0, 1},// 0.000000
++	{ 24166666030883789,  68,  6,  1, 1},// 0.068963
++	{ 24333333969116211,  80,  2,  0, 1},// 0.136989
++	{ 24500000000000000,  48,  4,  0, 1},// 0.000000
++	{ 24666666030883789,  18, 12,  0, 1},// 0.135138
++	{ 24725274666666666,  98,  4,  1, 1},// 0.100000 vout
++	{ 24750000000000000,  98,  4,  1, 1},// 0.000000 vout
++	{ 25000000000000000, 124,  1,  0, 1},// 0.000000
++	{ 25333333969116211,  22, 10,  0, 1},// 0.131581
++	{ 25500000000000000,  84,  2,  0, 1},// 0.000000
++	{ 25666666030883789, 127,  1,  0, 1},// 0.259738
++	{ 25833333969116211,  85,  2,  0, 1},// 0.129035
++	{ 26000000000000000,  64,  3,  0, 1},// 0.000000
++	{ 26333333969116211,  87,  2,  0, 1},// 0.253162
++	{ 26399999618530273,  87,  2,  0, 1},// 0.000001
++	{ 26500000000000000,  52,  4,  0, 1},// 0.000000
++	{ 26600000381469727,  37,  6,  0, 1},// 0.000001
++	{ 26799999237060547,  66,  3,  0, 1},// 0.000003
++	{ 27000000000000000,  89,  2,  0, 1},// 0.000000
++	{ 27200000762939453,  67,  3,  0, 1},// 0.000003
++	{ 27600000381469727,  91,  2,  0, 1},// 0.000001
++	{ 28000000000000000,  69,  3,  0, 1},// 0.000000
++	{ 28200000762939453,  93,  2,  0, 1},// 0.000003
++	{ 28399999618530273,  70,  3,  0, 1},// 0.000001
++	{ 28799999237060547,  95,  2,  0, 1},// 0.000003
++	{ 29000000000000000,  57,  4,  0, 1},// 0.000000
++	{ 29200000762939453,  72,  3,  0, 1},// 0.000003
++	{ 29399999618530273,  97,  2,  0, 1},// 0.000001
++	{ 29600000381469727,  73,  3,  0, 1},// 0.000001
++	{ 30000000000000000,  99,  2,  0, 1},// 0.000000
++	{ 30399999618530273,  75,  3,  0, 1},// 0.000001
++	{ 30600000381469727, 101,  2,  0, 1},// 0.000001
++	{ 30799999237060547,  76,  3,  0, 1},// 0.000002
++	{ 31000000000000000,  61,  4,  0, 1},// 0.000000
++	{ 31200000762939453, 103,  2,  0, 1},// 0.000002
++	{ 31600000381469727,  78,  3,  0, 1},// 0.000001
++	{ 31799999237060547, 105,  2,  0, 1},// 0.000002
++	{ 33000000000000000, 109,  2,  0, 1},// 0.000000
++	{ 33250000000000000, 110,  2,  0, 1},// 0.150376
++	{ 33500000000000000,  66,  4,  0, 1},// 0.000000
++	{ 33750000000000000,  25, 12,  0, 1},// 0.148148
++	{ 34000000000000000,  84,  3,  0, 1},// 0.000000
++	{ 34500000000000000, 114,  2,  0, 1},// 0.000000
++	{ 35000000000000000,  69,  4,  0, 1},// 0.000000
++	{ 35250000000000000,  87,  3,  0, 1},// 0.141844
++	{ 35500000000000000,  70,  4,  0, 1},// 0.000000
++	{ 36000000000000000, 119,  2,  0, 1},// 0.000000
++	{ 36250000000000000, 120,  2,  0, 1},// 0.137931
++	{ 36500000000000000,  72,  4,  0, 1},// 0.000000
++	{ 36750000000000000,  91,  3,  0, 1},// 0.136054
++	{ 37000000000000000,  73,  4,  0, 1},// 0.000000
++	{ 37500000000000000, 124,  2,  0, 1},// 0.000000
++	{ 38000000000000000,  94,  3,  0, 1},// 0.000000
++	{ 38250000000000000, 126,  2,  0, 1},// 0.392157
++	{ 38500000000000000,  76,  4,  0, 1},// 0.000000
++	{ 38750000000000000,  96,  3,  0, 1},// 0.129032
++	{ 39000000000000000,  77,  4,  0, 1},// 0.000000
++	{ 39500000000000000,  78,  4,  0, 1},// 0.000000
++	{ 39750000000000000,  98,  3,  0, 1},// 0.377358
++	{ 44000000000000000, 109,  3,  0, 1},// 0.000000
++	{ 44333332061767578, 110,  3,  0, 1},// 0.150379
++	{ 44666667938232422, 111,  3,  0, 1},// 0.298505
++	{ 45000000000000000,  89,  4,  0, 1},// 0.000000
++	{ 45333332061767578, 112,  3,  0, 1},// 0.294115
++	{ 46000000000000000, 114,  3,  0, 1},// 0.000000
++	{ 46666667938232422, 116,  3,  0, 1},// 0.285712
++	{ 47000000000000000,  93,  4,  0, 1},// 0.000000
++	{ 47333332061767578,  42, 10,  0, 1},// 0.070420
++	{ 48000000000000000, 119,  3,  0, 1},// 0.000000
++	{ 48333332061767578,  68,  6,  0, 1},// 0.068963
++	{ 48666667938232422,  80,  5,  0, 1},// 0.136989
++	{ 49000000000000000,  97,  4,  0, 1},// 0.000000
++	{ 49333332061767578,  37, 12,  0, 1},// 0.135138
++	{ 50000000000000000, 124,  3,  0, 1},// 0.000000
++	{ 50666667938232422, 124,  3,  0, 1},// 1.315792
++	{ 51000000000000000, 124,  3,  0, 1},// 1.960784
++	{ 51333332061767578, 124,  3,  0, 1},// 2.597400
++	{ 51666667938232422, 124,  3,  0, 1},// 3.225809
++	{ 52000000000000000, 124,  3,  0, 1},// 3.846154
++	{ 52666667938232422, 124,  3,  0, 1},// 5.063293
++	{ 53000000000000000, 124,  3,  0, 1},// 5.660377
++} ;
++EXPORT_SYMBOL(ambarella_pll_vout_table);
++
++struct pll_table ambarella_pll_vout2_table[AMBARELLA_PLL_VOUT2_TABLE_SIZE] = {
++	{1000000000000000,	78,	1,	1,	79},
++	{1007407426834106,	77,	1,	4,	31},
++	{1014925360679626,	78,	1,	12,	12},
++	{1019999980926514,	78,	1,	4,	31},
++	{1022556424140930,	67,	1,	6,	19},
++	{1027027010917664,	78,	1,	13,	11},
++	{1030303001403809,	78,	1,	8,	17},
++	{1033783793449402,	75,	1,	6,	21},
++	{1037037014961243,	78,	1,	7,	19},
++	{1040816307067871,	77,	1,	14,	10},
++	{1043478250503540,	71,	1,	5,	23},
++	{1046153903007507,	76,	1,	6,	21},
++	{1049999952316284,	74,	1,	12,	11},
++	{1054263591766357,	78,	1,	14,	10},
++	{1058823585510254,	77,	1,	6,	21},
++	{1062500000000000,	76,	1,	4,	29},
++	{1066666722297668,	78,	1,	3,	37},
++	{1070866107940674,	76,	1,	15,	9},
++	{1074626922607422,	78,	1,	6,	21},
++	{1079365134239197,	75,	1,	2,	47},
++	{1082089543342590,	78,	1,	1,	73},
++	{1085106372833252,	75,	1,	13,	10},
++	{1088000059127808,	78,	1,	4,	29},
++	{1092857122421265,	77,	1,	12,	11},
++	{1096774220466614,	78,	1,	15,	9},
++	{1101449251174927,	76,	1,	13,	10},
++	{1105691075325012,	78,	1,	12,	11},
++	{1108695626258850,	74,	1,	14,	9},
++	{1111888170242310,	78,	1,	1,	71},
++	{1114754080772400,	76,	1,	5,	23},
++	{1117647051811218,	75,	1,	7,	17},
++	{1120567321777344,	78,	1,	2,	47},
++	{1123966932296753,	75,	1,	14,	9},
++	{1127118587493896,	78,	1,	13,	10},
++	{1130434751510620,	77,	1,	5,	23},
++	{1133333325386047,	75,	1,	1,	67},
++	{1136752128601074,	74,	1,	11,	11},
++	{1139705896377563,	76,	1,	14,	9},
++	{1142857193946838,	78,	1,	5,	23},
++	{1146551728248596,	77,	1,	7,	17},
++	{1149606347084045,	75,	1,	11,	11},
++	{1152542352676392,	74,	1,	12,	10},
++	{1155555605888367,	77,	1,	14,	9},
++	{1159090876579285,	78,	1,	7,	17},
++	{1162393212318420,	77,	1,	1,	67},
++	{1166666626930237,	76,	1,	11,	11},
++	{1172413825988770,	78,	1,	14,	9},
++	{1176923036575317,	78,	1,	1,	67},
++	{1182608723640442,	77,	1,	11,	11},
++	{1186046481132507,	78,	1,	6,	19},
++	{1189189195632935,	74,	1,	13,	9},
++	{1192982435226440,	76,	1,	2,	43},
++	{1196850419044495,	78,	1,	11,	11},
++	{1200000047683716,	77,	1,	12,	10},
++	{1203539848327637,	76,	1,	15,	8},
++	{1206896543502808,	77,	1,	2,	43},
++	{1210084080696106,	76,	1,	0,	127},
++	{1214285731315613,	78,	1,	12,	10},
++	{1220338940620422,	77,	1,	15,	8},
++	{1225225210189819,	78,	1,	2,	43},
++	{1230769276618958,	77,	1,	0,	127},
++	{1236363649368286,	78,	1,	15,	8},
++	{1239669442176819,	76,	1,	3,	31},
++	{1243902444839478,	78,	1,	0,	127},
++	{1247706413269043,	77,	1,	4,	25},
++	{1254098415374756,	78,	1,	13,	9},
++	{1259259223937988,	77,	1,	3,	31},
++	{1264462828636169,	78,	1,	4,	25},
++	{1267857193946838,	77,	1,	2,	41},
++	{1271028041839600,	78,	1,	3,	31},
++	{1274999976158142,	75,	1,	6,	17},
++	{1278846144676208,	77,	1,	1,	61},
++	{1283018827438354,	78,	1,	2,	41},
++	{1286956548690796,	77,	1,	10,	11},
++	{1291262149810791,	76,	1,	6,	17},
++	{1295238137245178,	78,	1,	1,	61},
++	{1299145340919495,	77,	1,	14,	8},
++	{1303921580314636,	78,	1,	10,	11},
++	{1307692289352417,	77,	1,	6,	17},
++	{1312500000000000,	72,	1,	2,	37},
++	{1316831707954407,	78,	1,	14,	8},
++	{1320388317108154,	77,	1,	1,	59},
++	{1324324369430542,	76,	1,	3,	29},
++	{1330000042915344,	78,	1,	6,	17},
++	{1333333373069763,	77,	1,	12,	9},
++	{1342105269432068,	78,	1,	1,	59},
++	{1346534609794617,	71,	1,	0,	107},
++	{1350000023841858,	78,	1,	12,	9},
++	{1353982329368591,	77,	1,	4,	23},
++	{1360000014305115,	78,	1,	3,	29},
++	{1366071462631226,	77,	1,	5,	19},
++	{1373737335205078,	78,	1,	4,	23},
++	{1378378391265869,	77,	1,	0,	113},
++	{1383928537368774,	78,	1,	5,	19},
++	{1387755155563354,	74,	1,	11,	9},
++	{1394495368003845,	77,	1,	15,	7},
++	{1398058295249939,	78,	1,	0,	113},
++	{1402061820030212,	77,	1,	2,	37},
++	{1407407402992249,	78,	1,	15,	7},
++	{1411764740943909,	76,	1,	0,	109},
++	{1416666626930237,	77,	1,	10,	10},
++	{1420560717582703,	78,	1,	2,	37},
++	{1425742626190186,	76,	1,	11,	9},
++	{1431578993797302,	77,	1,	0,	109},
++	{1436170220375061,	78,	1,	10,	10},
++	{1440000057220459,	74,	1,	12,	8},
++	{1446808457374573,	78,	1,	0,	109},
++	{1450549483299255,	76,	1,	1,	53},
++	{1457142829895020,	77,	1,	0,	107},
++	{1462365627288818,	78,	1,	11,	9},
++	{1466666698455811,	76,	1,	14,	7},
++	{1471153855323792,	77,	1,	1,	53},
++	{1478260874748230,	78,	1,	0,	107},
++	{1485436916351318,	77,	1,	14,	7},
++	{1490196108818054,	78,	1,	1,	53},
++	{1494505524635315,	76,	1,	0,	103},
++	{1500000000000000,	77,	1,	12,	8},
++	{1504950523376465,	78,	1,	14,	7},
++	{1511111140251160,	77,	1,	0,	103},
++	{1515789508819580,	78,	1,	12,	8},
++	{1519999980926514,	75,	1,	9,	10},
++	{1528089880943298,	77,	1,	5,	17},
++	{1531914949417114,	78,	1,	0,	103},
++	{1538461565971375,	76,	1,	9,	10},
++	{1545454502105713,	78,	1,	5,	17},
++	{1551020383834839,	75,	1,	13,	7},
++	{1555555582046509,	76,	1,	10,	9},
++	{1563218355178833,	78,	1,	0,	101},
++	{1568181872367859,	76,	1,	13,	7},
++	{1573033690452576,	77,	1,	10,	9},
++	{1577319622039795,	78,	1,	9,	10},
++	{1581395387649536,	75,	1,	15,	6},
++	{1587628841400146,	76,	1,	0,	97},
++	{1593750000000000,	78,	1,	10,	9},
++	{1600000023841858,	75,	1,	4,	19},
++	{1604166626930237,	76,	1,	15,	6},
++	{1610526323318481,	78,	1,	13,	7},
++	{1614583373069763,	75,	1,	1,	47},
++	{1619047641754150,	76,	1,	4,	19},
++	{1623529434204102,	77,	1,	15,	6},
++	{1627659559249878,	78,	1,	0,	97},
++	{1634408593177795,	76,	1,	1,	47},
++	{1638554215431213,	77,	1,	4,	19},
++	{1645161271095276,	78,	1,	15,	6},
++	{1652173876762390,	76,	1,	2,	31},
++	{1658536553382874,	77,	1,	1,	47},
++	{1663043498992920,	78,	1,	4,	19},
++	{1674418568611145,	77,	1,	2,	31},
++	{1679012298583984,	78,	1,	1,	47},
++	{1683544278144836,	74,	1,	0,	89},
++	{1688888907432556,	76,	1,	12,	7},
++	{1694117665290833,	77,	1,	3,	23},
++	{1700000047683716,	78,	1,	2,	31},
++	{1705128192901611,	75,	1,	0,	89},
++	{1709677457809448,	76,	1,	14,	6},
++	{1714285731315613,	78,	1,	3,	23},
++	{1721518993377686,	74,	1,	2,	29},
++	{1727272748947144,	76,	1,	0,	89},
++	{1733333349227905,	78,	1,	12,	7},
++	{1738636374473572,	73,	1,	4,	17},
++	{1743589758872986,	75,	1,	2,	29},
++	{1750000000000000,	77,	1,	0,	89},
++	{1758620738983154,	78,	1,	14,	6},
++	{1766233801841736,	76,	1,	2,	29},
++	{1773333311080933,	78,	1,	0,	89},
++	{1779069781303406,	73,	1,	0,	83},
++	{1783783793449402,	75,	1,	4,	17},
++	{1789473652839661,	77,	1,	2,	29},
++	{1794871807098389,	78,	1,	10,	8},
++	{1799999952316284,	72,	1,	8,	9},
++	{1808219194412231,	76,	1,	4,	17},
++	{1813333392143250,	78,	1,	2,	29},
++	{1821428537368774,	72,	1,	15,	5},
++	{1831325292587280,	77,	1,	4,	17},
++	{1837837815284729,	78,	1,	1,	43},
++	{1843373537063599,	71,	1,	12,	6},
++	{1848837256431580,	74,	1,	8,	9},
++	{1853658556938171,	77,	1,	13,	6},
++	{1863013744354248,	78,	1,	4,	17},
++	{1870129823684692,	73,	1,	0,	79},
++	{1876543164253235,	78,	1,	13,	6},
++	{1883116841316223,	66,	1,	0,	71},
++	{1888888835906982,	70,	1,	14,	5},
++	{1894736886024475,	74,	1,	0,	79},
++	{1899999976158142,	78,	1,	0,	83},
++	{1909090876579285,	65,	1,	2,	23},
++	{1915493011474609,	71,	1,	14,	5},
++	{1922077894210815,	78,	1,	1,	41},
++	{1927536249160767,	46,	2,	0,	73},
++	{1936708807945251,	65,	1,	3,	17},
++	{1942857146263123,	73,	1,	3,	19},
++	{1948717951774597,	78,	1,	8,	9},
++	{1955882310867310,	48,	2,	14,	5},
++	{1961538434028625,	52,	2,	8,	9},
++	{1971014499664307,	78,	1,	15,	5},
++	{1987012982368469,	52,	2,	15,	5},
++	{2000000000000000,	78,	1,	0,	79},
++	{2013157844543457,	52,	2,	0,	79},
++	{2029850721359253,	78,	1,	12,	6},
++	{2039999961853027,	52,	2,	12,	6},
++	{2046153783798218,	44,	2,	10,	6},
++	{2054054021835327,	78,	1,	10,	7},
++	{2060606002807617,	68,	1,	0,	67},
++	{2067567586898804,	50,	2,	1,	37},
++	{2078125000000000,	78,	1,	3,	19},
++	{2086956501007080,	74,	1,	11,	6},
++	{2092307806015015,	67,	1,	12,	5},
++	{2099999904632568,	48,	2,	13,	5},
++	{2111111164093018,	78,	1,	14,	5},
++	{2117647171020508,	71,	1,	3,	17},
++	{2125000000000000,	68,	1,	12,	5},
++	{2130434751510620,	78,	1,	1,	37},
++	{2140845060348511,	77,	1,	0,	73},
++	{2149253845214844,	72,	1,	3,	17},
++	{2158730268478394,	68,	1,	15,	4},
++	{2164179086685181,	78,	1,	0,	73},
++	{2171428680419922,	75,	1,	13,	5},
++	{2177419424057007,	72,	1,	0,	67},
++	{2185714244842529,	70,	1,	12,	5},
++	{2193548440933228,	78,	1,	11,	6},
++	{2202898502349854,	76,	1,	13,	5},
++	{2208955287933350,	73,	1,	0,	67},
++	{2217391252517700,	71,	1,	12,	5},
++	{2229508161544800,	78,	1,	0,	71},
++	{2235294103622437,	75,	1,	3,	17},
++	{2242424249649048,	73,	1,	10,	6},
++	{2250000000000000,	71,	1,	15,	4},
++	{2258064508438110,	78,	1,	13,	5},
++	{2266666650772095,	76,	1,	3,	17},
++	{2275861978530884,	74,	1,	10,	6},
++	{2283581972122192,	71,	1,	8,	7},
++	{2293103456497192,	78,	1,	2,	23},
++	{2305084705352783,	75,	1,	10,	6},
++	{2311475515365601,	73,	1,	15,	4},
++	{2318181753158569,	78,	1,	3,	17},
++	{2333333253860474,	77,	1,	0,	67},
++	{2344827651977539,	74,	1,	15,	4},
++	{2353846073150635,	78,	1,	0,	67},
++	{2360655784606934,	77,	1,	10,	6},
++	{2368421077728271,	76,	1,	12,	5},
++	{2375000000000000,	75,	1,	15,	4},
++	{2385964870452881,	74,	1,	8,	7},
++	{2392857074737549,	78,	1,	10,	6},
++	{2400000095367432,	77,	1,	12,	5},
++	{2409836053848267,	76,	1,	15,	4},
++	{2418181896209717,	74,	1,	1,	31},
++	{2428571462631226,	78,	1,	12,	5},
++	{2440677881240845,	77,	1,	15,	4},
++	{2451612949371338,	75,	1,	1,	31},
++	{2462962865829468,	78,	1,	15,	4},
++	{2472727298736572,	77,	1,	8,	7},
++	{2482758522033691,	76,	1,	1,	31},
++	{2491803169250488,	75,	1,	0,	61},
++	{2500000000000000,	74,	1,	14,	4},
++	{2508196830749512,	78,	1,	8,	7},
++	{2518518447875977,	77,	1,	1,	31},
++	{2526315689086914,	71,	1,	2,	19},
++	{2533333301544189,	75,	1,	14,	4},
++	{2542372941970825,	78,	1,	1,	31},
++	{2549999952316284,	73,	1,	1,	29},
++	{2557692289352417,	77,	1,	0,	61},
++	{2566037654876709,	76,	1,	14,	4},
++	{2576271295547485,	75,	1,	0,	59},
++	{2586206912994385,	78,	1,	0,	61},
++	{2593220233917236,	73,	1,	2,	19},
++	{2599999904632568,	77,	1,	14,	4},
++	{2607843160629272,	76,	1,	0,	59},
++	{2615384578704834,	75,	1,	1,	29},
++	{2625000000000000,	70,	1,	8,	6},
++	{2637931108474731,	78,	1,	14,	4},
++	{2647058725357056,	52,	2,	14,	4},
++	{2660000085830688,	76,	1,	1,	29},
++	{2666666746139526,	75,	1,	2,	19},
++	{2684210538864136,	78,	1,	0,	59},
++	{2692307710647583,	69,	1,	12,	4},
++	{2701754331588745,	76,	1,	2,	19},
++	{2711538553237915,	75,	1,	13,	4},
++	{2720000028610229,	78,	1,	1,	29},
++	{2732142925262451,	77,	1,	2,	19},
++	{2745098114013672,	76,	1,	13,	4},
++	{2755102157592773,	72,	1,	0,	53},
++	{2763636350631714,	75,	1,	10,	5},
++	{2775510311126709,	78,	1,	2,	19},
++	{2785714387893677,	77,	1,	13,	4},
++	{2799999952316284,	76,	1,	10,	5},
++	{2807692289352417,	72,	1,	12,	4},
++	{2814814805984497,	78,	1,	13,	4},
++	{2823529481887817,	74,	1,	0,	53},
++	{2833333253860474,	77,	1,	10,	5},
++	{2843137264251709,	73,	1,	12,	4},
++	{2857142925262451,	76,	1,	8,	6},
++	{2867924451828003,	78,	1,	10,	5},
++	{2880000114440918,	74,	1,	12,	4},
++	{2893616914749146,	77,	1,	8,	6},
++	{2905660390853882,	76,	1,	0,	53},
++	{2913043498992920,	72,	1,	9,	5},
++	{2923076868057251,	78,	1,	8,	6},
++	{2933333396911621,	71,	1,	6,	7},
++	{2942307710647583,	77,	1,	0,	53},
++	{2956521749496460,	76,	1,	12,	4},
++	{2980392217636108,	78,	1,	0,	53},
++	{3000000000000000,	77,	1,	12,	4},
++	{3022222280502319,	76,	1,	2,	17},
++	{3039999961853027,	78,	1,	12,	4},
++	{3059999942779541,	77,	1,	2,	17},
++	{3069767475128174,	65,	1,	0,	43},
++	{3079999923706055,	76,	1,	9,	5},
++	{3090909004211426,	78,	1,	2,	17},
++	{3102040767669678,	75,	1,	6,	7},
++	{3111111164093018,	69,	1,	14,	3},
++	{3122448921203613,	77,	1,	9,	5},
++	{3130434751510620,	71,	1,	1,	23},
++	{3142857074737549,	76,	1,	6,	7},
++	{3152173995971680,	78,	1,	9,	5},
++	{3162790775299072,	75,	1,	15,	3},
++	{3173913002014160,	72,	1,	1,	23},
++	{3187500000000000,	77,	1,	6,	7},
++	{3200000047683716,	71,	1,	14,	3},
++	{3208333253860474,	76,	1,	15,	3},
++	{3219512224197388,	78,	1,	6,	7},
++	{3229166746139526,	75,	1,	0,	47},
++	{3238095283508301,	72,	1,	14,	3},
++	{3255319118499756,	77,	1,	15,	3},
++	{3272727251052856,	76,	1,	0,	47},
++	{3285714387893677,	78,	1,	15,	3},
++	{3295454502105713,	70,	1,	0,	43},
++	{3304347753524780,	75,	1,	1,	23},
++	{3317073106765747,	77,	1,	0,	47},
++	{3326086997985840,	74,	1,	14,	3},
++	{3348837137222290,	76,	1,	1,	23},
++	{3365853548049927,	78,	1,	0,	47},
++	{3377777814865112,	75,	1,	14,	3},
++	{3391304254531860,	77,	1,	1,	23},
++	{3400000095367432,	67,	1,	9,	4},
++	{3410256385803223,	74,	1,	10,	4},
++	{3428571462631226,	78,	1,	1,	23},
++	{3444444417953491,	73,	1,	0,	43},
++	{3454545497894287,	75,	1,	10,	4},
++	{3466666698455811,	77,	1,	14,	3},
++	{3477272748947144,	72,	1,	13,	3},
++	{3487179517745972,	74,	1,	0,	43},
++	{3500000000000000,	76,	1,	10,	4},
++	{3512195110321045,	78,	1,	14,	3},
++	{3522727251052856,	73,	1,	13,	3},
++	{3534883737564087,	75,	1,	0,	43},
++	{3545454502105713,	77,	1,	10,	4},
++	{3558139562606812,	72,	1,	0,	41},
++	{3567567586898804,	74,	1,	13,	3},
++	{3578947305679321,	76,	1,	0,	43},
++	{3589743614196777,	78,	1,	10,	4},
++	{3599999904632568,	71,	1,	9,	4},
++	{3609755992889404,	73,	1,	0,	41},
++	{3619047641754150,	77,	1,	0,	43},
++	{3631578922271729,	68,	1,	1,	19},
++	{3642857074737549,	72,	1,	9,	4},
++	{3658536672592163,	76,	1,	13,	3},
++	{3675675630569458,	78,	1,	0,	43},
++	{3692307710647583,	73,	1,	9,	4},
++	{3707317113876343,	77,	1,	13,	3},
++	{3717948675155640,	66,	1,	11,	3},
++	{3731707334518433,	70,	1,	1,	19},
++	{3743589639663696,	74,	1,	9,	4},
++	{3756097555160522,	78,	1,	13,	3},
++	{3777777671813965,	69,	1,	0,	37},
++	{3789473772048950,	73,	1,	12,	3},
++	{3799999952316284,	77,	1,	0,	41},
++	{3810810804367065,	46,	2,	0,	37},
++	{3825000047683716,	68,	1,	11,	3},
++	{3837837934494019,	74,	1,	12,	3},
++	{3849999904632568,	78,	1,	0,	41},
++	{3868421077728271,	52,	2,	0,	41},
++	{3885714292526245,	73,	1,	1,	19},
++	{3897435903549194,	77,	1,	9,	4},
++	{3911764621734619,	46,	2,	11,	3},
++	{3923076868057251,	50,	2,	12,	3},
++	{3948717832565308,	78,	1,	9,	4},
++	{3972972869873047,	52,	2,	9,	4},
++	{4000000000000000,	77,	1,	12,	3},
++	{4026315689086914,	50,	2,	1,	19},
++	{4052631378173828,	78,	1,	12,	3},
++	{4083333492279053,	52,	2,	12,	3},
++	{4108108043670654,	77,	1,	1,	19},
++	{4121212005615234,	67,	1,	10,	3},
++	{4135135173797607,	50,	2,	0,	37},
++	{4156250000000000,	78,	1,	1,	19},
++	{4166666507720947,	74,	1,	11,	3},
++	{4181818008422852,	68,	1,	10,	3},
++	{4199999809265137,	48,	2,	6,	5},
++	{4222222328186035,	77,	1,	0,	37},
++	{4235294342041016,	71,	1,	1,	17},
++	{4250000000000000,	67,	1,	15,	2},
++	{4264705657958984,	78,	1,	0,	37},
++	{4277777671813965,	76,	1,	11,	3},
++	{4290322780609131,	72,	1,	1,	17},
++	{4312500000000000,	70,	1,	10,	3},
++	{4323529243469238,	77,	1,	11,	3},
++	{4342857360839844,	75,	1,	6,	5},
++	{4354838848114014,	71,	1,	10,	3},
++	{4371428489685059,	69,	1,	15,	2},
++	{4387096881866455,	78,	1,	11,	3},
++	{4400000095367432,	76,	1,	6,	5},
++	{4411764621734619,	74,	1,	1,	17},
++	{4433333396911621,	72,	1,	10,	3},
++	{4454545497894287,	77,	1,	6,	5},
++	{4470588207244873,	75,	1,	1,	17},
++	{4484848499298096,	73,	1,	10,	3},
++	{4500000000000000,	71,	1,	15,	2},
++	{4516129016876221,	78,	1,	6,	5},
++	{4533333301544189,	76,	1,	1,	17},
++	{4551723957061768,	74,	1,	10,	3},
++	{4586206912994385,	77,	1,	1,	17},
++	{4606060504913330,	75,	1,	10,	3},
++	{4620689868927002,	73,	1,	15,	2},
++	{4636363506317139,	78,	1,	1,	17},
++	{4666666507720947,	76,	1,	10,	3},
++	{4689655303955078,	74,	1,	15,	2},
++	{4714285850524902,	72,	1,	0,	31},
++	{4727272510528564,	77,	1,	10,	3},
++	{4750000000000000,	75,	1,	15,	2},
++	{4781250000000000,	78,	1,	10,	3},
++	{4800000190734863,	71,	1,	14,	2},
++	{4812500000000000,	76,	1,	15,	2},
++	{4827586174011230,	74,	1,	0,	31},
++	{4843750000000000,	30,	4,	15,	2},
++	{4857142925262451,	72,	1,	14,	2},
++	{4875000000000000,	77,	1,	15,	2},
++	{4888888835906982,	70,	1,	0,	29},
++	{4903225898742676,	75,	1,	0,	31},
++	{4935483932495117,	78,	1,	15,	2},
++	{4965517044067383,	76,	1,	0,	31},
++	{5000000000000000,	74,	1,	14,	2},
++	{5037036895751953,	77,	1,	0,	31},
++	{5066666603088379,	75,	1,	14,	2},
++	{5099999904632568,	78,	1,	0,	31},
++	{5115384578704834,	18,	6,	12,	2},
++	{5129032135009766,	76,	1,	14,	2},
++	{5142857074737549,	71,	1,	13,	2},
++	{5166666507720947,	74,	1,	0,	29},
++	{5185184955596924,	69,	1,	8,	3},
++	{5199999809265137,	77,	1,	14,	2},
++	{5214285850524902,	72,	1,	13,	2},
++	{5230769157409668,	75,	1,	0,	29},
++	{5250000000000000,	70,	1,	8,	3},
++	{5275862216949463,	78,	1,	14,	2},
++	{5300000190734863,	76,	1,	0,	29},
++	{5320000171661377,	45,	2,	12,	2},
++	{5333333492279053,	71,	1,	8,	3},
++	{5357142925262451,	74,	1,	13,	2},
++	{5384615421295166,	77,	1,	0,	29},
++	{5400000095367432,	72,	1,	8,	3},
++	{5423077106475830,	75,	1,	13,	2},
++	{5440000057220459,	78,	1,	0,	29},
++	{5464285850524902,	70,	1,	12,	2},
++	{5481481552124023,	73,	1,	8,	3},
++	{5500000000000000,	76,	1,	13,	2},
++	{5519999980926514,	68,	1,	4,	5},
++	{5538461685180664,	71,	1,	12,	2},
++	{5555555343627930,	74,	1,	8,	3},
++	{5571428775787354,	77,	1,	13,	2},
++	{5599999904632568,	69,	1,	4,	5},
++	{5615384578704834,	72,	1,	12,	2},
++	{5629629611968994,	78,	1,	13,	2},
++	{5666666507720947,	70,	1,	4,	5},
++	{5703703880310059,	76,	1,	8,	3},
++	{5739130496978760,	68,	1,	11,	2},
++	{5760000228881836,	74,	1,	12,	2},
++	{5782608509063721,	77,	1,	8,	3},
++	{5800000190734863,	28,	4,	4,	5},
++	{5826086997985840,	72,	1,	4,	5},
++	{5846153736114502,	78,	1,	8,	3},
++	{5869565010070801,	48,	2,	4,	5},
++	{5884615421295166,	52,	2,	8,	3},
++	{5913043498992920,	76,	1,	12,	2},
++	{5961538314819336,	30,	4,	12,	2},
++	{6000000000000000,	77,	1,	12,	2},
++	{6045454502105713,	28,	4,	11,	2},
++	{6079999923706055,	78,	1,	12,	2},
++	{6119999885559082,	52,	2,	12,	2},
++	{6136363506317139,	44,	2,	10,	2},
++	{6159999847412109,	76,	1,	4,	5},
++	{6181818008422852,	67,	1,	10,	2},
++	{6199999809265137,	30,	4,	4,	5},
++	{6239999771118164,	77,	1,	4,	5},
++	{6260869503021240,	71,	1,	0,	23},
++	{6285714149475098,	65,	1,	6,	3},
++	{6304347991943359,	78,	1,	4,	5},
++	{6333333492279053,	75,	1,	11,	2},
++	{6375000000000000,	69,	1,	10,	2},
++	{6391304492950439,	48,	2,	0,	23},
++	{6416666507720947,	76,	1,	11,	2},
++	{6434782505035400,	73,	1,	0,	23},
++	{6458333492279053,	70,	1,	10,	2},
++	{6476190567016602,	67,	1,	6,	3},
++	{6500000000000000,	77,	1,	11,	2},
++	{6521739006042480,	74,	1,	0,	23},
++	{6545454502105713,	71,	1,	10,	2},
++	{6571428775787354,	78,	1,	11,	2},
++	{6590909004211426,	65,	1,	9,	2},
++	{6608695507049561,	75,	1,	0,	23},
++	{6652173995971680,	72,	1,	10,	2},
++	{6681818008422852,	76,	1,	0,	23},
++	{6699999809265137,	66,	1,	9,	2},
++	{6727272510528564,	73,	1,	10,	2},
++	{6750000000000000,	70,	1,	6,	3},
++	{6782608509063721,	77,	1,	0,	23},
++	{6800000190734863,	67,	1,	9,	2},
++	{6818181991577148,	74,	1,	10,	2},
++	{6857142925262451,	78,	1,	0,	23},
++	{6909090995788574,	75,	1,	10,	2},
++	{6954545497894287,	72,	1,	6,	3},
++	{7000000000000000,	76,	1,	10,	2},
++	{7045454502105713,	73,	1,	6,	3},
++	{7090909004211426,	77,	1,	10,	2},
++	{7157894611358643,	74,	1,	6,	3},
++	{7181818008422852,	78,	1,	10,	2},
++	{7199999809265137,	71,	1,	9,	2},
++	{7238095283508301,	75,	1,	6,	3},
++	{7263157844543457,	68,	1,	0,	19},
++	{7285714149475098,	72,	1,	9,	2},
++	{7349999904632568,	76,	1,	6,	3},
++	{7368421077728271,	69,	1,	0,	19},
++	{7388888835906982,	73,	1,	9,	2},
++	{7428571224212646,	77,	1,	6,	3},
++	{7473684310913086,	70,	1,	0,	19},
++	{7500000000000000,	74,	1,	9,	2},
++	{7523809432983398,	78,	1,	6,	3},
++	{7555555343627930,	67,	1,	8,	2},
++	{7578947544097900,	71,	1,	0,	19},
++	{7599999904632568,	75,	1,	9,	2},
++	{7650000095367432,	68,	1,	8,	2},
++	{7699999809265137,	76,	1,	9,	2},
++	{7736842155456543,	48,	2,	0,	19},
++	{7777777671813965,	73,	1,	0,	19},
++	{7800000190734863,	77,	1,	9,	2},
++	{7823529243469238,	46,	2,	8,	2},
++	{7894736766815186,	78,	1,	9,	2},
++	{7941176414489746,	52,	2,	9,	2},
++	{8000000000000000,	75,	1,	0,	19},
++	{8052631378173828,	50,	2,	0,	19},
++	{8105262756347656,	76,	1,	0,	19},
++	{8166666984558105,	48,	2,	8,	2},
++	{8210526466369629,	77,	1,	0,	19},
++	{8235294342041016,	69,	1,	0,	17},
++	{8312500000000000,	78,	1,	0,	19},
++	{8333333015441895,	74,	1,	8,	2},
++	{8368420600891113,	66,	1,	15,	1},
++	{8444444656372070,	75,	1,	8,	2},
++	{8470588684082031,	71,	1,	0,	17},
++	{8500000000000000,	67,	1,	15,	1},
++	{8529411315917969,	28,	4,	0,	17},
++	{8555555343627930,	76,	1,	8,	2},
++	{8588234901428223,	72,	1,	0,	17},
++	{8625000000000000,	68,	1,	15,	1},
++	{8647058486938477,	77,	1,	8,	2},
++	{8705882072448730,	73,	1,	0,	17},
++	{8750000000000000,	69,	1,	15,	1},
++	{8777777671813965,	78,	1,	8,	2},
++	{8800000190734863,	65,	1,	14,	1},
++	{8823529243469238,	74,	1,	0,	17},
++	{8866666793823242,	70,	1,	15,	1},
++	{8941176414489746,	75,	1,	0,	17},
++	{9000000000000000,	71,	1,	15,	1},
++	{9066666603088379,	76,	1,	0,	17},
++	{9117647171020508,	72,	1,	15,	1},
++	{9187500000000000,	77,	1,	0,	17},
++	{9250000000000000,	73,	1,	15,	1},
++	{9294117927551270,	78,	1,	0,	17},
++	{9333333015441895,	69,	1,	14,	1},
++	{9375000000000000,	74,	1,	15,	1},
++	{9399999618530273,	46,	2,	14,	1},
++	{9428571701049805,	65,	1,	13,	1},
++	{9466666221618652,	70,	1,	14,	1},
++	{9500000000000000,	75,	1,	15,	1},
++	{9562500000000000,	66,	1,	13,	1},
++	{9600000381469727,	71,	1,	14,	1},
++	{9625000000000000,	76,	1,	15,	1},
++	{9666666984558105,	30,	4,	15,	1},
++	{9714285850524902,	72,	1,	14,	1},
++	{9750000000000000,	77,	1,	15,	1},
++	{9800000190734863,	48,	2,	14,	1},
++	{9857142448425293,	78,	1,	15,	1},
++	{9937500000000000,	52,	2,	15,	1},
++	{10000000000000000,	74,	1,	14,	1},
++	{10071428298950195,	46,	2,	13,	1},
++	{10133333206176758,	75,	1,	14,	1},
++	{10199999809265137,	50,	2,	14,	1},
++	{10230769157409668,	18,	6,	12,	1},
++	{10285714149475098,	76,	1,	14,	1},
++	{10357142448425293,	30,	4,	14,	1},
++	{10399999618530273,	77,	1,	14,	1},
++	{10428571701049805,	72,	1,	13,	1},
++	{10461538314819336,	67,	1,	12,	1},
++	{10500000000000000,	48,	2,	13,	1},
++	{10533333778381348,	78,	1,	14,	1},
++	{10571428298950195,	73,	1,	13,	1},
++	{10615385055541992,	68,	1,	12,	1},
++	{10714285850524902,	74,	1,	13,	1},
++	{10769230842590332,	69,	1,	12,	1},
++	{10857142448425293,	75,	1,	13,	1},
++	{10928571701049805,	70,	1,	12,	1},
++	{11000000000000000,	76,	1,	13,	1},
++	{11076923370361328,	71,	1,	12,	1},
++	{11142857551574707,	77,	1,	13,	1},
++	{11250000000000000,	72,	1,	12,	1},
++	{11285714149475098,	78,	1,	13,	1},
++	{11333333015441895,	67,	1,	11,	1},
++	{11384614944458008,	73,	1,	12,	1},
++	{11500000000000000,	68,	1,	11,	1},
++	{11538461685180664,	74,	1,	12,	1},
++	{11692307472229004,	75,	1,	12,	1},
++	{11769230842590332,	50,	2,	12,	1},
++	{11846154212951660,	76,	1,	12,	1},
++	{11923076629638672,	30,	4,	12,	1},
++	{12000000000000000,	77,	1,	12,	1},
++	{12090909004211426,	28,	4,	11,	1},
++	{12181818008422852,	78,	1,	12,	1},
++	{12250000000000000,	52,	2,	12,	1},
++	{12363636016845703,	73,	1,	11,	1},
++	{12500000000000000,	74,	1,	11,	1},
++	{12545454978942871,	68,	1,	10,	1},
++	{12666666984558105,	75,	1,	11,	1},
++	{12750000000000000,	69,	1,	10,	1},
++	{12833333015441895,	76,	1,	11,	1},
++	{12916666984558105,	70,	1,	10,	1},
++	{13000000000000000,	77,	1,	11,	1},
++	{13090909004211426,	71,	1,	10,	1},
++	{13166666984558105,	78,	1,	11,	1},
++	{13199999809265137,	65,	1,	9,	1},
++	{13250000000000000,	72,	1,	10,	1},
++	{13300000190734863,	18,	6,	9,	1},
++	{13363636016845703,	48,	2,	10,	1},
++	{13399999618530273,	66,	1,	9,	1},
++	{13454545021057129,	73,	1,	10,	1},
++	{13500000000000000,	44,	2,	9,	1},
++	{13600000381469727,	67,	1,	9,	1},
++	{13636363983154297,	74,	1,	10,	1},
++	{13818181991577148,	75,	1,	10,	1},
++	{13909090995788574,	50,	2,	10,	1},
++	{14000000000000000,	76,	1,	10,	1},
++	{14090909004211426,	46,	2,	9,	1},
++	{14181818008422852,	77,	1,	10,	1},
++	{14363636016845703,	78,	1,	10,	1},
++	{14399999618530273,	71,	1,	9,	1},
++	{14454545021057129,	52,	2,	10,	1},
++	{14500000000000000,	28,	4,	9,	1},
++	{14600000381469727,	72,	1,	9,	1},
++	{14699999809265137,	65,	1,	8,	1},
++	{14777777671813965,	73,	1,	9,	1},
++	{14888889312744141,	66,	1,	8,	1},
++	{15000000000000000,	74,	1,	9,	1},
++	{15111110687255859,	67,	1,	8,	1},
++	{15199999809265137,	75,	1,	9,	1},
++	{15300000190734863,	68,	1,	8,	1},
++	{15399999618530273,	76,	1,	9,	1},
++	{15500000000000000,	30,	4,	9,	1},
++	{15555555343627930,	69,	1,	8,	1},
++	{15600000381469727,	77,	1,	9,	1},
++	{15666666984558105,	46,	2,	8,	1},
++	{15777777671813965,	78,	1,	9,	1},
++	{15899999618530273,	52,	2,	9,	1},
++	{16000000000000000,	71,	1,	8,	1},
++	{16111110687255859,	28,	4,	8,	1},
++	{16222221374511719,	72,	1,	8,	1},
++	{16333333969116211,	48,	2,	8,	1},
++	{16444444656372070,	73,	1,	8,	1},
++	{16500000000000000,	65,	1,	7,	1},
++	{16625000000000000,	18,	6,	7,	1},
++	{16666666030883789,	74,	1,	8,	1},
++	{16750000000000000,	66,	1,	7,	1},
++	{16888889312744141,	75,	1,	8,	1},
++	{17000000000000000,	67,	1,	7,	1},
++	{17111110687255859,	76,	1,	8,	1},
++	{17250000000000000,	68,	1,	7,	1},
++	{17333333969116211,	77,	1,	8,	1},
++	{17500000000000000,	69,	1,	7,	1},
++	{17555555343627930,	78,	1,	8,	1},
++	{17625000000000000,	52,	2,	8,	1},
++	{17750000000000000,	70,	1,	7,	1},
++	{18000000000000000,	71,	1,	7,	1},
++	{18125000000000000,	28,	4,	7,	1},
++	{18250000000000000,	72,	1,	7,	1},
++	{18375000000000000,	48,	2,	7,	1},
++	{18500000000000000,	73,	1,	7,	1},
++	{18750000000000000,	74,	1,	7,	1},
++	{18857143402099609,	65,	1,	6,	1},
++	{19000000000000000,	75,	1,	7,	1},
++	{19125000000000000,	66,	1,	6,	1},
++	{19250000000000000,	76,	1,	7,	1},
++	{19375000000000000,	30,	4,	7,	1},
++	{19428571701049805,	67,	1,	6,	1},
++	{19500000000000000,	77,	1,	7,	1},
++	{19714284896850586,	78,	1,	7,	1},
++	{19875000000000000,	52,	2,	7,	1},
++	{20000000000000000,	69,	1,	6,	1},
++	{20142856597900391,	46,	2,	6,	1},
++	{20285715103149414,	70,	1,	6,	1},
++	{20571428298950195,	71,	1,	6,	1},
++	{20714284896850586,	28,	4,	6,	1},
++	{20857143402099609,	72,	1,	6,	1},
++	{21000000000000000,	48,	2,	6,	1},
++	{21142856597900391,	73,	1,	6,	1},
++	{21428571701049805,	74,	1,	6,	1},
++	{21714284896850586,	75,	1,	6,	1},
++	{21857143402099609,	50,	2,	6,	1},
++	{22000000000000000,	76,	1,	6,	1},
++	{22166666030883789,	30,	4,	6,	1},
++	{22285715103149414,	77,	1,	6,	1},
++	{22500000000000000,	44,	2,	5,	1},
++	{22571428298950195,	78,	1,	6,	1},
++	{22666666030883789,	67,	1,	5,	1},
++	{23000000000000000,	68,	1,	5,	1},
++	{23333333969116211,	69,	1,	5,	1},
++	{23500000000000000,	46,	2,	5,	1},
++	{23666666030883789,	70,	1,	5,	1},
++	{24000000000000000,	71,	1,	5,	1},
++	{24166666030883789,	28,	4,	5,	1},
++	{24333333969116211,	72,	1,	5,	1},
++	{24500000000000000,	48,	2,	5,	1},
++	{24666666030883789,	73,	1,	5,	1},
++	{25000000000000000,	74,	1,	5,	1},
++	{25333333969116211,	75,	1,	5,	1},
++	{25500000000000000,	50,	2,	5,	1},
++	{25666666030883789,	76,	1,	5,	1},
++	{25833333969116211,	30,	4,	5,	1},
++	{26000000000000000,	77,	1,	5,	1},
++	{26333333969116211,	78,	1,	5,	1},
++	{26399999618530273,	65,	1,	4,	1},
++	{26500000000000000,	52,	2,	5,	1},
++	{26600000381469727,	18,	6,	4,	1},
++	{26799999237060547,	66,	1,	4,	1},
++	{27000000000000000,	44,	2,	4,	1},
++	{27200000762939453,	67,	1,	4,	1},
++	{27600000381469727,	68,	1,	4,	1},
++	{28000000000000000,	69,	1,	4,	1},
++	{28200000762939453,	46,	2,	4,	1},
++	{28399999618530273,	70,	1,	4,	1},
++	{28799999237060547,	71,	1,	4,	1},
++	{29000000000000000,	28,	4,	4,	1},
++	{29200000762939453,	72,	1,	4,	1},
++	{29399999618530273,	48,	2,	4,	1},
++	{29600000381469727,	73,	1,	4,	1},
++	{30000000000000000,	74,	1,	4,	1},
++	{30399999618530273,	75,	1,	4,	1},
++	{30600000381469727,	50,	2,	4,	1},
++	{30799999237060547,	76,	1,	4,	1},
++	{31000000000000000,	30,	4,	4,	1},
++	{31200000762939453,	77,	1,	4,	1},
++	{31600000381469727,	78,	1,	4,	1},
++	{31799999237060547,	52,	2,	4,	1},
++	{33000000000000000,	65,	1,	3,	1},
++	{33250000000000000,	18,	6,	3,	1},
++	{33500000000000000,	66,	1,	3,	1},
++	{33750000000000000,	44,	2,	3,	1},
++	{34000000000000000,	67,	1,	3,	1},
++	{34500000000000000,	68,	1,	3,	1},
++	{35000000000000000,	69,	1,	3,	1},
++	{35250000000000000,	46,	2,	3,	1},
++	{35500000000000000,	70,	1,	3,	1},
++	{36000000000000000,	71,	1,	3,	1},
++	{36250000000000000,	28,	4,	3,	1},
++	{36500000000000000,	72,	1,	3,	1},
++	{36750000000000000,	48,	2,	3,	1},
++	{37000000000000000,	73,	1,	3,	1},
++	{37500000000000000,	74,	1,	3,	1},
++	{38000000000000000,	75,	1,	3,	1},
++	{38250000000000000,	50,	2,	3,	1},
++	{38500000000000000,	76,	1,	3,	1},
++	{38750000000000000,	30,	4,	3,	1},
++	{39000000000000000,	77,	1,	3,	1},
++	{39500000000000000,	78,	1,	3,	1},
++	{39750000000000000,	52,	2,	3,	1},
++	{44000000000000000,	65,	1,	2,	1},
++	{44333332061767578,	18,	6,	2,	1},
++	{44666667938232422,	66,	1,	2,	1},
++	{45000000000000000,	44,	2,	2,	1},
++	{45333332061767578,	67,	1,	2,	1},
++	{46000000000000000,	68,	1,	2,	1},
++	{46666667938232422,	69,	1,	2,	1},
++	{47000000000000000,	46,	2,	2,	1},
++	{47333332061767578,	70,	1,	2,	1},
++	{48000000000000000,	71,	1,	2,	1},
++	{48333332061767578,	28,	4,	2,	1},
++	{48666667938232422,	72,	1,	2,	1},
++	{49000000000000000,	48,	2,	2,	1},
++	{49333332061767578,	73,	1,	2,	1},
++	{50000000000000000,	74,	1,	2,	1},
++	{50666667938232422,	75,	1,	2,	1},
++	{51000000000000000,	50,	2,	2,	1},
++	{51333332061767578,	76,	1,	2,	1},
++	{51666667938232422,	30,	4,	2,	1},
++	{52000000000000000,	77,	1,	2,	1},
++	{52666667938232422,	78,	1,	2,	1},
++	{53000000000000000,	52,	2,	2,	1},
++};
++EXPORT_SYMBOL(ambarella_pll_vout2_table);
++
++
+diff --git a/arch/arm/mach-ambarella/fio.c b/arch/arm/mach-ambarella/fio.c
+new file mode 100644
+index 00000000..aa1071df
+--- /dev/null
++++ b/arch/arm/mach-ambarella/fio.c
+@@ -0,0 +1,303 @@
++/*
++ * arch/arm/plat-ambarella/generic/fio.c
++ *
++ * History:
++ *	2008/03/05 - [Chien-Yang Chen] created file
++ *	2008/01/09 - [Anthony Ginger] Port to 2.6.28.
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <asm/setup.h>
++#include <mach/hardware.h>
++#include <asm/cacheflush.h>
++#include <plat/fio.h>
++#include <plat/sd.h>
++#include <plat/nand.h>
++#include <plat/rct.h>
++
++static void *fio_4k_vaddr = NULL;
++
++#if (FIO_INDEPENDENT_SD == 0)
++
++static DECLARE_WAIT_QUEUE_HEAD(fio_wait);
++static DEFINE_SPINLOCK(fio_lock);
++static DEFINE_SPINLOCK(fio_sd0_int_lock);
++
++static u32 fio_owner = SELECT_FIO_FREE;
++static u32 fio_sd_owner_cnt = 0;
++#if (CHIP_REV == A5S)
++static u32 fio_default_owner = SELECT_FIO_SDIO;
++#else
++static u32 fio_default_owner = SELECT_FIO_SD;
++#endif
++static u32 fio_sd_int = 0;
++static u32 fio_sdio_int = 0;
++
++
++static int __init fio_default_owner_init(char *p)
++{
++	fio_default_owner = simple_strtoul(p, NULL, 0);
++	return 0;
++}
++early_param("fio_default_owner", fio_default_owner_init);
++
++void __fio_select_lock(int module)
++{
++	u32					fio_ctr;
++	u32					fio_dmactr;
++#if (CHIP_REV == A5S)
++	unsigned long				flags;
++#endif
++
++	if (module == SELECT_FIO_FREE)
++		return;
++
++	fio_ctr = amba_readl(FIO_CTR_REG);
++	fio_dmactr = amba_readl(FIO_DMACTR_REG);
++
++	switch (module) {
++	case SELECT_FIO_FL:
++		fio_ctr &= ~FIO_CTR_XD;
++		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_FL;
++		break;
++
++	case SELECT_FIO_XD:
++		fio_ctr |= FIO_CTR_XD;
++		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_XD;
++		break;
++
++	case SELECT_FIO_CF:
++		fio_ctr &= ~FIO_CTR_XD;
++		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_CF;
++		break;
++
++	case SELECT_FIO_SD:
++		fio_ctr &= ~FIO_CTR_XD;
++		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
++		break;
++
++	case SELECT_FIO_SDIO:
++		fio_ctr |= FIO_CTR_XD;
++		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
++		break;
++
++	default:
++		break;
++	}
++
++#if (CHIP_REV == A5S)
++	spin_lock_irqsave(&fio_sd0_int_lock, flags);
++	amba_clrbitsl(SD0_REG(SD_NISEN_OFFSET), SD_NISEN_CARD);
++	spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
++#endif
++	amba_writel(FIO_CTR_REG, fio_ctr);
++	amba_writel(FIO_DMACTR_REG, fio_dmactr);
++#if (CHIP_REV == A5S)
++	if (module == SELECT_FIO_SD) {
++		spin_lock_irqsave(&fio_sd0_int_lock, flags);
++		amba_writel(SD0_REG(SD_NISEN_OFFSET), fio_sd_int);
++		amba_writel(SD0_REG(SD_NIXEN_OFFSET), fio_sd_int);
++		spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
++	} else if (module == SELECT_FIO_SDIO) {
++		spin_lock_irqsave(&fio_sd0_int_lock, flags);
++		amba_writel(SD0_REG(SD_NISEN_OFFSET), fio_sdio_int);
++		amba_writel(SD0_REG(SD_NIXEN_OFFSET), fio_sdio_int);
++		spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
++	}
++#endif
++}
++
++static bool fio_check_free(u32 module)
++{
++	unsigned long flags;
++	bool is_free = false;
++
++	spin_lock_irqsave(&fio_lock, flags);
++
++	if (fio_owner == SELECT_FIO_FREE) {
++		is_free = true;
++		fio_owner = module;
++	} else if (fio_owner == module) {
++		is_free = true;
++		if (fio_owner != SELECT_FIO_SD)
++			pr_warning("%s: module[%d] reentry!\n", __func__, module);
++	}
++
++	if (is_free && module == SELECT_FIO_SD)
++		fio_sd_owner_cnt++;
++
++	spin_unlock_irqrestore(&fio_lock, flags);
++
++	return is_free;
++}
++
++
++void fio_select_lock(int module)
++{
++	wait_event(fio_wait, fio_check_free(module));
++	__fio_select_lock(module);
++}
++EXPORT_SYMBOL(fio_select_lock);
++
++void fio_unlock(int module)
++{
++	unsigned long flags;
++
++	BUG_ON(fio_owner != module);
++
++	spin_lock_irqsave(&fio_lock, flags);
++
++	if (module != SELECT_FIO_SD || --fio_sd_owner_cnt == 0)
++		fio_owner = SELECT_FIO_FREE;
++
++	if (fio_owner == SELECT_FIO_FREE) {
++		if (fio_default_owner != module)
++			__fio_select_lock(fio_default_owner);
++		wake_up(&fio_wait);
++	}
++
++	spin_unlock_irqrestore(&fio_lock, flags);
++}
++EXPORT_SYMBOL(fio_unlock);
++
++static int fio_amb_sd0_is_enable(void)
++{
++	u32 fio_ctr;
++	u32 fio_dmactr;
++
++	fio_ctr = amba_readl(FIO_CTR_REG);
++	fio_dmactr = amba_readl(FIO_DMACTR_REG);
++
++	return (((fio_ctr & FIO_CTR_XD) == 0) &&
++		((fio_dmactr & FIO_DMACTR_SD) == FIO_DMACTR_SD));
++}
++
++void fio_amb_sd0_set_int(u32 mask, u32 on)
++{
++	unsigned long				flags;
++	u32					int_flag;
++
++	spin_lock_irqsave(&fio_sd0_int_lock, flags);
++	int_flag = amba_readl(SD0_REG(SD_NISEN_OFFSET));
++	if (on)
++		int_flag |= mask;
++	else
++		int_flag &= ~mask;
++	fio_sd_int = int_flag;
++	if (fio_amb_sd0_is_enable()) {
++		amba_writel(SD0_REG(SD_NISEN_OFFSET), int_flag);
++		amba_writel(SD0_REG(SD_NIXEN_OFFSET), int_flag);
++	}
++	spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
++}
++EXPORT_SYMBOL(fio_amb_sd0_set_int);
++
++static int fio_amb_sdio0_is_enable(void)
++{
++	u32 fio_ctr;
++	u32 fio_dmactr;
++
++	fio_ctr = amba_readl(FIO_CTR_REG);
++	fio_dmactr = amba_readl(FIO_DMACTR_REG);
++
++	return (((fio_ctr & FIO_CTR_XD) == FIO_CTR_XD) &&
++		((fio_dmactr & FIO_DMACTR_SD) == FIO_DMACTR_SD));
++}
++
++void fio_amb_sdio0_set_int(u32 mask, u32 on)
++{
++	unsigned long				flags;
++	u32					int_flag;
++
++	spin_lock_irqsave(&fio_sd0_int_lock, flags);
++	int_flag = amba_readl(SD0_REG(SD_NISEN_OFFSET));
++	if (on)
++		int_flag |= mask;
++	else
++		int_flag &= ~mask;
++	fio_sdio_int = int_flag;
++	if (fio_amb_sdio0_is_enable()) {
++		amba_writel(SD0_REG(SD_NISEN_OFFSET), int_flag);
++		amba_writel(SD0_REG(SD_NIXEN_OFFSET), int_flag);
++	}
++	spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
++}
++EXPORT_SYMBOL(fio_amb_sdio0_set_int);
++#endif
++
++void ambarella_fio_prepare(void)
++{
++	fio_4k_vaddr = __arm_ioremap_exec(FIO_4K_PHYS_BASE, 0x1000, false);
++	if (!fio_4k_vaddr)
++		pr_warning("__arm_ioremap_exec for FIFO failed!\n");
++}
++
++void *ambarella_fio_push(void *func, u32 size)
++{
++	BUG_ON(!fio_4k_vaddr || (size > 0x1000));
++
++	amba_writel(FIO_CTR_REG, (amba_readl(FIO_CTR_REG) | FIO_CTR_RR));
++	memcpy(fio_4k_vaddr, func, size);
++
++	flush_icache_range((unsigned long)(fio_4k_vaddr),
++			(unsigned long)(fio_4k_vaddr) + (size));
++
++	return fio_4k_vaddr;
++}
++EXPORT_SYMBOL(ambarella_fio_push);
++
++void ambarella_fio_rct_reset(void)
++{
++	amba_rct_writel(FIO_RESET_REG, FIO_RESET_FIO_RST);
++	mdelay(1);
++	amba_rct_writel(FIO_RESET_REG, 0x0);
++	mdelay(1);
++}
++EXPORT_SYMBOL(ambarella_fio_rct_reset);
++
++/* ==========================================================================*/
++int __init ambarella_init_fio(void)
++{
++	/* ioremap for self refresh */
++	ambarella_fio_prepare();
++#if defined(CONFIG_AMBARELLA_RAW_BOOT)
++	amba_rct_writel(FIO_RESET_REG, (FIO_RESET_FIO_RST | FIO_RESET_CF_RST |
++		FIO_RESET_XD_RST | FIO_RESET_FLASH_RST));
++	mdelay(100);
++	amba_rct_writel(FIO_RESET_REG, 0);
++	mdelay(100);
++	amba_clrbitsl(FIO_CTR_REG, FIO_CTR_RR);
++
++	amba_setbitsl(NAND_CTR_REG, 0);
++	amba_writel(NAND_CMD_REG, 0xff);
++	mdelay(100);
++	amba_writel(NAND_INT_REG, 0x0);
++	amba_writel(NAND_CMD_REG, 0x90);
++	mdelay(100);
++	amba_writel(NAND_INT_REG, 0x0);
++#endif
++	return 0;
++}
++
+diff --git a/arch/arm/mach-ambarella/hibernate.c b/arch/arm/mach-ambarella/hibernate.c
+new file mode 100644
+index 00000000..94b0a9c5
+--- /dev/null
++++ b/arch/arm/mach-ambarella/hibernate.c
+@@ -0,0 +1,357 @@
++
++/*
++ * Hibernation support specific for ARM
++ *
++ * Derived from work on ARM hibernation support by:
++ *
++ * Ubuntu project, hibernation support for mach-dove
++ * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu)
++ * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.)
++ *  https://lkml.org/lkml/2010/6/18/4
++ *  https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html
++ *  https://patchwork.kernel.org/patch/96442/
++ *
++ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
++ *
++ * Copyright (C) 2015 Ambarella, Shanghai(Jorney Tu)
++ *
++ * License terms: GNU General Public License (GPL) version 2
++ */
++
++#include <linux/mm.h>
++#include <linux/suspend.h>
++#include <asm/system_misc.h>
++#include <asm/idmap.h>
++#include <asm/suspend.h>
++#include <asm/memory.h>
++#include <asm/sections.h>
++#include <linux/mtd/mtd.h>
++#include <linux/vmalloc.h>
++
++#define HIBERNATE_MTD_NAME  "swp"
++
++static int mtd_page_offset = 0;
++
++extern const void __nosave_begin, __nosave_end;
++
++static const unsigned int crc32_tab[] = {
++	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
++	0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
++	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
++	0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
++	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
++	0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
++	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
++	0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
++	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
++	0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
++	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
++	0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
++	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
++	0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
++	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
++	0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
++	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
++	0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
++	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
++	0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
++	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
++	0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
++	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
++	0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
++	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
++	0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
++	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
++	0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
++	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
++	0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
++	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
++	0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
++	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
++	0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
++	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
++	0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
++	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
++	0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
++	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
++	0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
++	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
++	0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
++	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
++};
++
++static unsigned int __crc32(unsigned int crc, const void *buf, unsigned int size)
++{
++	const unsigned char *p;
++	unsigned int __crc = crc;
++
++	p = buf;
++
++	while (size > 0) {
++		__crc = crc32_tab[(__crc ^ *p++) & 0xff] ^ (__crc >> 8);
++		size--;
++	}
++
++	return __crc ^ ~0U;
++}
++
++
++int pfn_is_nosave(unsigned long pfn)
++{
++	return 0;
++}
++
++void notrace save_processor_state(void)
++{
++	WARN_ON(num_online_cpus() != 1);
++	local_fiq_disable();
++}
++
++void notrace restore_processor_state(void)
++{
++	local_fiq_enable();
++}
++
++/*
++ * Snapshot kernel memory and reset the system.
++ *
++ * swsusp_save() is executed in the suspend finisher so that the CPU
++ * context pointer and memory are part of the saved image, which is
++ * required by the resume kernel image to restart execution from
++ * swsusp_arch_suspend().
++ *
++ * soft_restart is not technically needed, but is used to get success
++ * returned from cpu_suspend.
++ *
++ * When soft reboot completes, the hibernation snapshot is written out.
++ */
++static int notrace arch_save_image(unsigned long unused)
++{
++	int ret;
++
++	ret = swsusp_save();
++	if (ret == 0)
++		soft_restart(virt_to_phys(cpu_resume));
++	return ret;
++}
++
++/*
++ * Save the current CPU state before suspend / poweroff.
++ */
++int notrace swsusp_arch_suspend(void)
++{
++	return cpu_suspend(0, arch_save_image);
++}
++
++/*
++ * Restore page contents for physical pages that were in use during loading
++ * hibernation image.  Switch to idmap_pgd so the physical page tables
++ * are overwritten with the same contents.
++ */
++static void notrace arch_restore_image(void *unused)
++{
++	struct pbe *pbe;
++
++	cpu_switch_mm(idmap_pgd, &init_mm);
++	for (pbe = restore_pblist; pbe; pbe = pbe->next)
++		copy_page(pbe->orig_address, pbe->address);
++
++	soft_restart(virt_to_phys(cpu_resume));
++}
++
++static u64 resume_stack[PAGE_SIZE / 2 / sizeof(u64)] __nosavedata;
++
++/*
++ * Resume from the hibernation image.
++ * Due to the kernel heap / data restore, stack contents change underneath
++ * and that would make function calls impossible; switch to a temporary
++ * stack within the nosave region to avoid that problem.
++ */
++int swsusp_arch_resume(void)
++{
++	extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
++	call_with_stack(arch_restore_image, 0,
++		resume_stack + ARRAY_SIZE(resume_stack));
++	return 0;
++}
++
++struct mtd_info *mtd_probe_dev(void)
++{
++	struct mtd_info *info = NULL;
++	info = get_mtd_device_nm(HIBERNATE_MTD_NAME);
++
++	if(IS_ERR(info)){
++		printk("SWP: mtd dev no found!\n");
++		return NULL;
++	}else{
++		/* Makesure the swp partition has 32M at least */
++		if(info->size < 0x2000000){
++			printk("ERR: swp partition size is less than 32M\n");
++			return NULL;
++		}
++
++		printk("MTD name: %s\n",	info->name);
++		printk("MTD size: 0x%llx\n",	info->size);
++		printk("MTD blocksize: 0x%x\n", info->erasesize);
++		printk("MTD pagesize: 0x%x\n",	info->writesize);
++	}
++	return info;
++}
++
++
++int hibernate_mtd_check(struct mtd_info *mtd, int ofs)
++{
++
++	int loff = ofs;
++	int block = 0;
++
++	while (mtd_block_isbad(mtd, loff) > 0){
++
++		if(loff > mtd->size){
++			printk("SWP: overflow mtd device ...\n");
++			loff = 0;
++			break;
++		}
++
++		printk("SWP: offset %d is a bad block\n" ,loff);
++
++		block = loff / mtd->erasesize;
++		loff = (block + 1) * mtd->erasesize;
++	}
++	return loff / PAGE_SIZE;
++}
++
++
++int hibernate_write_page(struct mtd_info *mtd, void *buf)
++{
++
++	int ret, retlen;
++	int offset = 0;
++
++	/* Default: The 1st 4k(one PAGE_SIZE) is empty in "swp" mtd partition */
++	mtd_page_offset++;
++
++#if 1 /* bad block checking is needed ? */
++	offset = hibernate_mtd_check(mtd, mtd_page_offset * PAGE_SIZE);
++#else
++	offset = mtd_page_offset;
++#endif
++
++	if(offset == 0)
++		return -EINVAL;
++
++	ret = mtd_write(mtd, PAGE_SIZE * offset, PAGE_SIZE, &retlen, buf);
++	if(ret < 0){
++		printk("SWP: MTD write failed!\n");
++		return -EFAULT;
++	}
++
++	mtd_page_offset = offset;
++	return 0;
++}
++
++int hibernate_save_image(struct mtd_info *mtd, struct snapshot_handle *snapshot,
++		struct swsusp_info *header)
++{
++
++	int ret;
++	int nr_pages = 0;
++	unsigned int crc = 0;
++
++	while (1) {
++		ret = snapshot_read_next(snapshot);
++		if (ret <= 0)
++			break;
++
++		ret = hibernate_write_page(mtd, data_of(*snapshot));
++		if (ret) {
++			printk("hibernate_write_page error.\n");
++			return ret;
++		}
++
++		nr_pages++;
++
++		if (nr_pages > nr_meta_pages)
++			crc = __crc32(crc, data_of(*snapshot), PAGE_SIZE);
++	}
++
++	if(!ret)
++		printk("LINUX:	%d pages, crc = %08x.\n", nr_pages - nr_meta_pages, crc);
++
++	if(!nr_pages)
++		ret = -EINVAL;
++
++	header->crc32 = crc;
++	header->lzo_enable = 0;
++
++	/* save the header */
++	mtd_page_offset = 0;
++	hibernate_write_page(mtd, header);
++
++	return ret;
++}
++
++int hibernate_mtd_write(struct mtd_info *mtd)
++{
++
++	int error = 0;
++	struct swsusp_info *header, *copy;
++	struct snapshot_handle snapshot;
++
++	copy = vmalloc(sizeof(struct swsusp_info));
++	if (!copy)
++		return -ENOMEM;
++
++	memset(&snapshot, 0, sizeof(struct snapshot_handle));
++
++	if(nr_meta_pages <= 0)
++		return -EFAULT;
++
++	error = snapshot_read_next(&snapshot);
++	if (error < PAGE_SIZE) {
++		if (error >= 0)
++			error = -EFAULT;
++		goto out_finish;
++	}
++	
++	header = (struct swsusp_info *)data_of(snapshot);
++	memcpy(copy, header, sizeof(struct swsusp_info));
++
++	/*
++	 * Skip saving the header. the header is copied and
++	 * will be save after the CRC of the kernel snapshot
++	 * has been generated. The mtd_page_offset should be
++	 * set at meta data offset.
++	 *
++	 * */
++	mtd_page_offset ++;
++
++	/* TODO: SWP partition space size check */
++	if (header->pages * 0x1000 > mtd->size){
++		printk("ERR: swp partition[0x%llx] has not enough space for the \
++				kernel snapshot[0x%lx]\n", mtd->size, header->pages * 0x1000);
++			return -ENOMEM;
++	}
++
++	error = hibernate_save_image(mtd, &snapshot, copy);
++
++out_finish:
++	vfree(copy);
++	return error;
++
++}
++
++int swsusp_write_mtd(int flags)
++{
++
++	struct mtd_info *info = NULL;
++
++	mtd_page_offset = 0;
++
++	info = mtd_probe_dev();
++	if(!info)
++		return -EFAULT;
++
++	return hibernate_mtd_write(info);
++}
++
+diff --git a/arch/arm/mach-ambarella/include/mach/common.h b/arch/arm/mach-ambarella/include/mach/common.h
+new file mode 100644
+index 00000000..c0cb7343
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/common.h
+@@ -0,0 +1,19 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/common.h
++ *
++ * History:
++ *	2012/11/12 - Ken He <jianhe@ambarella.com> created file
++ *
++ * Coryright (c) 2012, Ambarella, Inc.
++ * http://www.ambarella.com
++ *
++ * 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.
++*/
++#ifndef __MACH_COMMON_H
++#define __MACH_COMMON_H
++
++extern struct smp_operations ambarella_smp_ops;
++
++#endif
+diff --git a/arch/arm/mach-ambarella/include/mach/debug-macro.S b/arch/arm/mach-ambarella/include/mach/debug-macro.S
+new file mode 100644
+index 00000000..672ed554
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/debug-macro.S
+@@ -0,0 +1,71 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/debug-macro.S
++ *
++ * History:
++ *	2006/12/27 - [Charles Chiou] created file
++ *	2010/03/29 - [Cao Rongrong] port to BOSS
++ *	2010/11/04 - [Cao Rongrong] port to Linux-2.6.36+
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <mach/hardware.h>
++#include <plat/uart.h>
++
++#define AMBA_UART_BASE_P		(APB_PHYS_BASE + UART_OFFSET)
++#define AMBA_UART_BASE_V		(APB_BASE + UART_OFFSET)
++
++#if defined(CONFIG_AMBARELLA_DEBUG_LL_UART0)
++	.macro	addruart, rp, rv, tmp
++	ldr	\rp, =AMBA_UART_BASE_P
++	ldr	\rv, =AMBA_UART_BASE_V
++	.endm
++
++	.macro	senduart, rd, rx
++	str	\rd, [\rx, #UART_TH_OFFSET]
++	.endm
++
++	.macro	waituart, rd, rx
++1001:
++	ldr	\rd, [\rx, #UART_LS_OFFSET]
++	tst	\rd, #UART_LS_TEMT
++	beq	1001b
++	.endm
++
++	.macro	busyuart, rd, rx
++1002:
++	ldr	\rd, [\rx, #UART_LS_OFFSET]
++	tst	\rd, #UART_LS_TEMT
++	beq	1002b
++	.endm
++#elif defined(CONFIG_DEBUG_LL_UART_NONE)
++	.macro	addruart, rp, rv, tmp
++	ldr	\rp, =AMBA_UART_BASE_P
++	ldr	\rv, =AMBA_UART_BASE_V
++	.endm
++
++	.macro	senduart,rd,rx
++	.endm
++
++	.macro	waituart,rd,rx
++	.endm
++
++	.macro	busyuart,rd,rx
++	.endm
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/gpio.h b/arch/arm/mach-ambarella/include/mach/gpio.h
+new file mode 100644
+index 00000000..5764299a
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/gpio.h
+@@ -0,0 +1,42 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/gpio.h
++ *
++ * History:
++ *	2006/12/27 - [Charles Chiou] created file
++ *	2009/01/12 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_GPIO_H
++#define __ASM_ARCH_GPIO_H
++
++/* ==========================================================================*/
++#include <mach/hardware.h>
++#include <plat/gpio.h>
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/hardware.h b/arch/arm/mach-ambarella/include/mach/hardware.h
+new file mode 100644
+index 00000000..595bb79a
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/hardware.h
+@@ -0,0 +1,54 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/hardware.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++/* ==========================================================================*/
++#include <plat/chip.h>
++#include <mach/memory.h>
++
++#include <plat/gpio.h>
++#include <plat/irq.h>
++#include <plat/pm.h>
++#include <plat/hwlock.h>
++#if defined(CONFIG_PLAT_AMBARELLA_CORTEX)
++#include <plat/cortex.h>
++#endif
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++extern u64 ambarella_dmamask;
++
++/* ==========================================================================*/
++extern int ambarella_create_proc_dir(void);
++extern struct proc_dir_entry *get_ambarella_proc_dir(void);
++
++extern u32 ambarella_get_poc(void);
++
++#endif
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/init.h b/arch/arm/mach-ambarella/include/mach/init.h
+new file mode 100644
+index 00000000..500714ef
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/init.h
+@@ -0,0 +1,103 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/init.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_INIT_H
++#define __ASM_ARCH_INIT_H
++
++/* ==========================================================================*/
++#include <plat/gpio.h>
++#include <plat/adc.h>
++#include <plat/audio.h>
++#include <plat/crypto.h>
++#include <plat/dma.h>
++#include <plat/eth.h>
++#include <plat/event.h>
++#include <plat/fio.h>
++#include <plat/idc.h>
++#include <plat/ir.h>
++#include <plat/irq.h>
++#include <plat/nand.h>
++#include <plat/clk.h>
++#include <plat/pm.h>
++#include <plat/pwm.h>
++#include <plat/rtc.h>
++#include <plat/sd.h>
++#include <plat/spi.h>
++#include <plat/timer.h>
++#include <plat/uart.h>
++#include <plat/udc.h>
++#include <plat/ahci.h>
++#include <plat/wdt.h>
++#include <plat/pinctrl.h>
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#define AMBARELLA_BOARD_TYPE_AUTO		(0)
++#define AMBARELLA_BOARD_TYPE_BUB		(1)
++#define AMBARELLA_BOARD_TYPE_EVK		(2)
++#define AMBARELLA_BOARD_TYPE_IPCAM		(3)
++#define AMBARELLA_BOARD_TYPE_VENDOR		(4)
++#define AMBARELLA_BOARD_TYPE_ATB		(5)
++
++#define AMBARELLA_BOARD_VERSION(c,t,r)		(((c) << 16) + ((t) << 12) + (r))
++#define AMBARELLA_BOARD_CHIP(v)			(((v) >> 16) & 0xFFFF)
++#define AMBARELLA_BOARD_TYPE(v)			(((v) >> 12) & 0xF)
++#define AMBARELLA_BOARD_REV(v)			(((v) >> 0) & 0xFFF)
++
++/* ==========================================================================*/
++extern void ambarella_init_early(void);
++extern void ambarella_init_machine(void);
++extern void ambarella_map_io(void);
++extern void ambarella_restart_machine(char mode, const char *cmd);
++
++/* ==========================================================================*/
++extern int ambarella_init_fb(void);
++
++/* ==========================================================================*/
++extern u32 ambarella_phys_to_virt(u32 paddr);
++extern u32 ambarella_virt_to_phys(u32 vaddr);
++
++extern u32 get_ambarella_iavmem_phys(void);
++extern u32 get_ambarella_iavmem_size(void);
++
++extern u32 get_ambarella_fbmem_phys(void);
++extern u32 get_ambarella_fbmem_size(void);
++
++extern u32 get_ambarella_ppm_phys(void);
++extern u32 get_ambarella_ppm_virt(void);
++extern u32 get_ambarella_ppm_size(void);
++
++extern u32 get_ambarella_ahb_phys(void);
++extern u32 get_ambarella_ahb_virt(void);
++extern u32 get_ambarella_ahb_size(void);
++
++extern u32 get_ambarella_apb_phys(void);
++extern u32 get_ambarella_apb_virt(void);
++extern u32 get_ambarella_apb_size(void);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/io.h b/arch/arm/mach-ambarella/include/mach/io.h
+new file mode 100644
+index 00000000..1cf73546
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/io.h
+@@ -0,0 +1,231 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/io.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_IO_H
++#define __ASM_ARCH_IO_H
++
++/* ==========================================================================*/
++#include <mach/hardware.h>
++
++/* ==========================================================================*/
++#define IO_SPACE_LIMIT		0xffffffff
++
++#define __io(a)			((void __iomem *)(a))
++#define __mem_pci(a)		(a)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++#define AMBARELLA_REG_LOCK()	AMBARELLA_GLOBAL_HW_LOCK()
++#define AMBARELLA_REG_UNLOCK()	AMBARELLA_GLOBAL_HW_UNLOCK()
++#else
++#define AMBARELLA_REG_LOCK()
++#define AMBARELLA_REG_UNLOCK()
++#endif
++
++#define amba_readb(v)		__raw_readb(v)
++#define amba_readw(v)		__raw_readw(v)
++#define amba_writeb(v,d)	__raw_writeb(d,v)
++#define amba_writew(v,d)	__raw_writew(d,v)
++
++static inline u32 __amba_readl(volatile void __iomem *address)
++{
++	u32 tmpval;
++
++	AMBARELLA_REG_LOCK();
++	tmpval = __raw_readl(address);
++	AMBARELLA_REG_UNLOCK();
++
++	return tmpval;
++}
++
++static inline void __amba_writel(volatile void __iomem *address, u32 value)
++{
++	AMBARELLA_REG_LOCK();
++	__raw_writel(value, address);
++	AMBARELLA_REG_UNLOCK();
++}
++
++static inline void __amba_writel_en(volatile void __iomem *address, u32 value)
++{
++	AMBARELLA_REG_LOCK();
++	__raw_writel(value, address);
++	__raw_writel((value | 0x1), address);
++	__raw_writel(value, address);
++	AMBARELLA_REG_UNLOCK();
++}
++
++#define amba_readl(v)		__amba_readl((volatile void __iomem *)v)
++#define amba_writel(v,d)	__amba_writel((volatile void __iomem *)v, d)
++
++static inline void __amba_read2w(volatile void __iomem *address,
++	u16 *value1, u16 *value2)
++{
++	volatile void __iomem *base;
++	u32 tmpreg;
++
++	BUG_ON((u32)address & 0x03);
++
++	base = (volatile void __iomem *)((u32)address & 0xFFFFFFFC);
++	tmpreg = amba_readl(base);
++	*value1 = (u16)tmpreg;
++	*value2 = (u16)(tmpreg >> 16);
++}
++
++static inline void __amba_write2w(volatile void __iomem *address,
++	u16 value1, u16 value2)
++{
++	volatile void __iomem *base;
++	u32 tmpreg;
++
++	BUG_ON((u32)address & 0x03);
++
++	base = (volatile void __iomem *)((u32)address & 0xFFFFFFFC);
++	tmpreg = value2;
++	tmpreg <<= 16;
++	tmpreg |= value1;
++	amba_writel(base, tmpreg);
++}
++
++#define amba_read2w(v,pd1,pd2)	__amba_read2w(v,pd1,pd2)
++#define amba_write2w(v,d1,d2)	__amba_write2w(v,d1,d2)
++
++#define amba_setbitsb(v, mask)	amba_writeb((v),(amba_readb(v) | (mask)))
++#define amba_setbitsw(v, mask)	amba_writew((v),(amba_readw(v) | (mask)))
++#define amba_setbitsl(v, mask)	amba_writel((v),(amba_readl(v) | (mask)))
++
++#define amba_clrbitsb(v, mask)	amba_writeb((v),(amba_readb(v) & ~(mask)))
++#define amba_clrbitsw(v, mask)	amba_writew((v),(amba_readw(v) & ~(mask)))
++#define amba_clrbitsl(v, mask)	amba_writel((v),(amba_readl(v) & ~(mask)))
++
++#define amba_tstbitsb(v, mask)	(amba_readb(v) & (mask))
++#define amba_tstbitsw(v, mask)	(amba_readw(v) & (mask))
++#define amba_tstbitsl(v, mask)	(amba_readl(v) & (mask))
++
++static inline void amba_change_bit(
++	volatile void __iomem *vaddress,
++	unsigned int bit)
++{
++	u32 mask = 1UL << (bit & 31);
++	u32 data;
++
++	data = amba_readl(vaddress);
++	data ^= mask;
++	amba_writel(vaddress, data);
++}
++static inline int amba_test_and_set_bit(
++	volatile void __iomem *vaddress,
++	unsigned int bit)
++{
++	u32 mask = 1UL << (bit & 31);
++	u32 data;
++	u32 tmp;
++
++	data = amba_readl(vaddress);
++	tmp = data | mask;
++	amba_writel(vaddress, tmp);
++
++	return data & mask;
++}
++static inline int amba_test_and_clear_bit(
++	volatile void __iomem *vaddress,
++	unsigned int bit)
++{
++	u32 mask = 1UL << (bit & 31);
++	u32 data;
++	u32 tmp;
++
++	data = amba_readl(vaddress);
++	tmp = data & ~mask;
++	amba_writel(vaddress, tmp);
++
++	return data & mask;
++}
++static inline int amba_test_and_change_bit(
++	volatile void __iomem *vaddress,
++	unsigned int bit)
++{
++	u32 mask = 1UL << (bit & 31);
++	u32 data;
++	u32 tmp;
++
++	data = amba_readl(vaddress);
++	tmp = data ^ mask;
++	amba_writel(vaddress, tmp);
++
++	return data & mask;
++}
++static inline int amba_test_and_set_mask(
++	volatile void __iomem *vaddress,
++	unsigned int mask)
++{
++	u32 data;
++	u32 tmp;
++
++	data = amba_readl(vaddress);
++	tmp = data | mask;
++	amba_writel(vaddress, tmp);
++
++	return data & mask;
++}
++static inline int amba_test_and_clear_mask(
++	volatile void __iomem *vaddress,
++	unsigned int mask)
++{
++	u32 data;
++	u32 tmp;
++
++	data = amba_readl(vaddress);
++	tmp = data & ~mask;
++	amba_writel(vaddress, tmp);
++
++	return data & mask;
++}
++
++/* ==========================================================================*/
++static inline u32 __amba_rct_readl(volatile void __iomem *address)
++{
++	volatile u32 tmpval;
++
++	AMBARELLA_REG_LOCK();
++	tmpval = __raw_readl(address);
++#if (CHIP_REV == A8)
++	tmpval = __raw_readl(address);
++#endif	/* CHIP_REV */
++	AMBARELLA_REG_UNLOCK();
++
++	return tmpval;
++}
++
++#define amba_rct_readl(v)		__amba_rct_readl((volatile void __iomem *)v)
++#define amba_rct_writel(v,d)		__amba_writel((volatile void __iomem *)v, d)
++#define amba_rct_writel_en(v,d)		__amba_writel_en((volatile void __iomem *)v, d)
++#define amba_rct_setbitsl(v, mask)	amba_rct_writel((v),(amba_rct_readl(v) | (mask)))
++#define amba_rct_clrbitsl(v, mask)	amba_rct_writel((v),(amba_rct_readl(v) & ~(mask)))
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/irqs.h b/arch/arm/mach-ambarella/include/mach/irqs.h
+new file mode 100644
+index 00000000..f233b117
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/irqs.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/irqs.h
++ *
++ * History:
++ *	2007/01/27 - [Charles Chiou] created file
++ *	2008/02/19 - [Allen Wang] changed to use capabilities and chip ID
++ *	2008/05/13 - [Allen Wang] added capabilities of A2S and A2M silicons
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_IRQS_H
++#define __ASM_ARCH_IRQS_H
++
++/* ==========================================================================*/
++#include <mach/hardware.h>
++#include <plat/irq.h>
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#define IRQ_LOCALTIMER		29
++/* ==========================================================================*/
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/memory.h b/arch/arm/mach-ambarella/include/mach/memory.h
+new file mode 100644
+index 00000000..9b7246da
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/memory.h
+@@ -0,0 +1,206 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/memory.h
++ *
++ * History:
++ *	2006/12/27 - [Charles Chiou] created file
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++/*
++ * MAP Sample	Phisical		Virtual			Size
++ * --------------------------------------------------------------------------
++ * AHB(IO)	AHB_PHYS_BASE		AHB_BASE		AHB_SIZE
++ * APB(IO)	APB_PHYS_BASE		APB_BASE		APB_BASE
++ * MISC(IO)	MISC_PHYS_BASE		MISC_BASE		MISC_SIZE
++ * PPM		DEFAULT_MEM_START	AHB_BASE - Size		CONFIG_AMBARELLA_PPM_SIZE
++ * Linux MEM	PHYS_OFFSET		CONFIG_VMSPLIT_xG	Linux MEM Size
++ */
++
++/* ==========================================================================*/
++#if defined(CONFIG_PLAT_AMBARELLA_MEM_START_LOW)
++#define DEFAULT_MEM_START		(0x00000000)
++#else
++#define DEFAULT_MEM_START		(0xc0000000)
++#endif
++#ifndef CONFIG_ARM_PATCH_PHYS_VIRT
++#define PHYS_OFFSET			(DEFAULT_MEM_START + CONFIG_AMBARELLA_PPM_SIZE)
++#endif
++
++/* ==========================================================================*/
++/* Physical Address and Size */
++#if defined(CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH)
++#define AHB_PHYS_BASE			(0xe0000000)
++#define APB_PHYS_BASE			(0xe8000000)
++#else
++#define AHB_PHYS_BASE			(0x60000000)
++#define APB_PHYS_BASE			(0x70000000)
++#endif
++#define AHB_SIZE			(0x01000000)
++#define APB_SIZE			(0x01000000)
++
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
++#define AXI_PHYS_BASE			(0xf0000000)
++#define AXI_SIZE			(0x00030000)
++#endif
++
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
++#define DRAMC_PHYS_BASE			(0xdffe0000)
++#define DRAMC_SIZE			(0x00020000)
++#endif
++
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
++#define AHB64_PHYS_BASE			(0x80000000)
++#define AHB64_SIZE			(0x00020000)
++#endif
++
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
++#define DBGBUS_PHYS_BASE		(0xec000000)
++#define DBGBUS_SIZE			(0x00200000)
++#define DBGFMEM_PHYS_BASE		(0xee000000)
++#define DBGFMEM_SIZE			(0x01000000)
++#endif
++
++/* Virtual Address */
++#if defined(CONFIG_VMSPLIT_3G)
++#define AHB_BASE			(0xf0000000)
++#define APB_BASE			(0xf1000000)
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
++#define AXI_BASE			(0xf2000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
++#define DRAMC_BASE			(0xf2040000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
++#define AHB64_BASE			(0xf20c0000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
++#define DBGBUS_BASE			(0xf2200000)
++#define DBGFMEM_BASE		(0xf3000000)
++#endif
++
++#elif defined(CONFIG_VMSPLIT_2G)
++#define AHB_BASE			(0xe0000000)
++#define APB_BASE			(0xe8000000)
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
++#define AXI_BASE			(0xf0000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
++#define DRAMC_BASE			(0xef000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
++#define AHB64_BASE			(0xed000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
++#define DBGBUS_BASE			(0xec000000)
++#define DBGFMEM_BASE		(0xee000000)
++#endif
++
++#else /* CONFIG_VMSPLIT_1G */
++#define AHB_BASE			(0xe0000000)
++#define APB_BASE			(0xe8000000)
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
++#define AXI_BASE			(0xf0000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
++#define DRAMC_BASE			(0xef000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
++#define AHB64_BASE			(0xed000000)
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
++#define DBGBUS_BASE			(0xec000000)
++#define DBGFMEM_BASE		(0xee000000)
++#endif
++#endif	/* CONFIG_VMSPLIT_3G */
++
++/* ==========================================================================*/
++#define DEFAULT_BST_START		(DEFAULT_MEM_START + 0x00000000)
++#define DEFAULT_BST_SIZE		(0x00000000)
++#define AMB_BST_MAGIC			(0xffaa5500)
++#define AMB_BST_INVALID			(0xdeadbeaf)
++#define AMB_BST_START_COUNTER		(0xffffffff)
++
++#define DEFAULT_DEBUG_START		(DEFAULT_MEM_START + 0x000f8000)
++#define DEFAULT_DEBUG_SIZE		(0x00008000)
++
++/* ==========================================================================*/
++/*
++ * Constants used to force the right instruction encodings and shifts
++ * so that all we need to do is modify the 8-bit constant field.
++ */
++#define __PV_BITS_31_24	0x81000000
++
++#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
++#ifndef __ASSEMBLY__
++extern u32 ambarella_phys_to_virt(u32 paddr);
++extern u32 ambarella_virt_to_phys(u32 vaddr);
++extern unsigned long __pv_phys_offset;
++#define PHYS_OFFSET __pv_phys_offset
++
++#define __pv_stub(from,to,instr,type)			\
++	__asm__("@ __pv_stub\n"				\
++	"1:	" instr "	%0, %1, %2\n"		\
++	"	.pushsection .pv_table,\"a\"\n"		\
++	"	.long	1b\n"				\
++	"	.popsection\n"				\
++	: "=r" (to)					\
++	: "r" (from), "I" (type))
++
++static inline unsigned long __amb_raw_virt_to_phys(unsigned long x)
++{
++	unsigned long t;
++	__pv_stub(x, t, "add", __PV_BITS_31_24);
++	return t;
++}
++
++static inline unsigned long __amb_raw_phys_to_virt(unsigned long x)
++{
++	unsigned long t;
++	__pv_stub(x, t, "sub", __PV_BITS_31_24);
++	return t;
++}
++#endif /* __ASSEMBLY__ */
++#else /* CONFIG_ARM_PATCH_PHYS_VIRT */
++#define __amb_raw_virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
++#define __amb_raw_phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
++#endif /* CONFIG_ARM_PATCH_PHYS_VIRT */
++
++#if defined(CONFIG_AMBARELLA_IO_MAP)
++#define __virt_to_phys(x)		(ambarella_virt_to_phys(x))
++#define __phys_to_virt(x)		(ambarella_phys_to_virt(x))
++#else
++#define __virt_to_phys(x)		(__amb_raw_virt_to_phys(x))
++#define __phys_to_virt(x)		(__amb_raw_phys_to_virt(x))
++#endif
++#define __virt_to_bus(x)		__virt_to_phys(x)
++#define __bus_to_virt(x)		__phys_to_virt(x)
++#define __pfn_to_bus(x)			__pfn_to_phys(x)
++#define __bus_to_pfn(x)			__phys_to_pfn(x)
++
++
++/* ==========================================================================*/
++#define MAX_PHYSMEM_BITS		32
++#define SECTION_SIZE_BITS		24
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/mach/timex.h b/arch/arm/mach-ambarella/include/mach/timex.h
+new file mode 100644
+index 00000000..5efe4351
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/timex.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/timex.h
++ *
++ * History:
++ *	2006/12/27 - [Charles Chiou] created file
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_TIMEX_H
++#define __ASM_ARCH_TIMEX_H
++
++#include <plat/chip.h>
++
++#define CLOCK_TICK_RATE				REF_CLK_FREQ
++
++#endif /* __ASM_ARCH_TIMEX_H */
++
+diff --git a/arch/arm/mach-ambarella/include/mach/uncompress.h b/arch/arm/mach-ambarella/include/mach/uncompress.h
+new file mode 100644
+index 00000000..35f8d46b
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/mach/uncompress.h
+@@ -0,0 +1,54 @@
++/*
++ * arch/arm/plat-ambarella/include/mach/uart.h
++ *
++ * History:
++ *	2006/12/27 - [Charles Chiou] created file
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_UNCOMPRESS_H
++#define __ASM_ARCH_UNCOMPRESS_H
++
++/* ==========================================================================*/
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++static inline void putc(int c)
++{
++
++}
++
++static inline void flush(void)
++{
++}
++
++static __inline__ void arch_decomp_setup(void)
++{
++
++}
++
++#define arch_decomp_wdog()
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/adc.h b/arch/arm/mach-ambarella/include/plat/adc.h
+new file mode 100644
+index 00000000..a9d450a9
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/adc.h
+@@ -0,0 +1,375 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/adc.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_ADC_H__
++#define __PLAT_AMBARELLA_ADC_H__
++
++#include <linux/workqueue.h>
++
++/* ==========================================================================*/
++#if (CHIP_REV == A7L)
++#define ADC_NUM_CHANNELS		8
++#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define ADC_NUM_CHANNELS		12
++#elif (CHIP_REV == S3)
++#define ADC_NUM_CHANNELS		5
++#else
++#define ADC_NUM_CHANNELS		4
++#endif
++
++#if (CHIP_REV == A5S)
++#define ADC_SUPPORT_THRESHOLD_INT	0
++#define ADC_SUPPORT_SLOT		0
++#else
++#define ADC_SUPPORT_THRESHOLD_INT	1
++#define ADC_SUPPORT_SLOT		1
++#endif
++
++/* ==========================================================================*/
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define ADC_OFFSET			0x1D000
++#else
++#define ADC_OFFSET			0xD000
++#endif
++#define ADC_BASE			(APB_BASE + ADC_OFFSET)
++#define ADC_REG(x)			(ADC_BASE + (x))
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define ADC_CONTROL_TYPE		0
++#define ADC_CONTROL_OFFSET		0x00
++#define ADC_ENABLE_OFFSET		0x18
++#else
++#define ADC_CONTROL_TYPE		1
++#define ADC_CONTROL_OFFSET		0x04
++#define ADC_ENABLE_OFFSET		ADC_CONTROL_OFFSET
++#endif
++
++#if (CHIP_REV == A5S)
++/* NOTE: ADC channel is re-order for A5S to make life easier */
++#define ADC_DATA0_OFFSET		0x04
++#define ADC_DATA1_OFFSET		0x08
++#define ADC_DATA2_OFFSET		0x0c
++#define ADC_DATA3_OFFSET		0x10
++#else
++#define ADC_DATA0_OFFSET		0x150
++#define ADC_DATA1_OFFSET		0x154
++#define ADC_DATA2_OFFSET		0x158
++#define ADC_DATA3_OFFSET		0x15c
++#endif
++
++#define ADC_COUNTER_OFFSET		0x008
++
++#if (CHIP_REV == A5S)
++#define ADC_CHAN0_INTR_OFFSET		0x44
++#define ADC_CHAN1_INTR_OFFSET		0x48
++#define ADC_CHAN2_INTR_OFFSET		0x4c
++#define ADC_CHAN3_INTR_OFFSET		0x50
++#else
++#define ADC_CHAN0_INTR_OFFSET		0x120
++#define ADC_CHAN1_INTR_OFFSET		0x124
++#define ADC_CHAN2_INTR_OFFSET		0x128
++#define ADC_CHAN3_INTR_OFFSET		0x12c
++#endif
++
++#if (CHIP_REV == A7L)
++#define ADC_DATA4_OFFSET		0x100
++#define ADC_DATA5_OFFSET		0x104
++#define ADC_DATA6_OFFSET		0x108
++#define ADC_DATA7_OFFSET		0x10c
++#define ADC_CHAN4_INTR_OFFSET		0x110
++#define ADC_CHAN5_INTR_OFFSET		0x114
++#define ADC_CHAN6_INTR_OFFSET		0x118
++#define ADC_CHAN7_INTR_OFFSET		0x11c
++#elif (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == S3)
++#define ADC_DATA4_OFFSET		0x160
++#define ADC_DATA5_OFFSET		0x164
++#define ADC_DATA6_OFFSET		0x168
++#define ADC_DATA7_OFFSET		0x16c
++#define ADC_CHAN4_INTR_OFFSET		0x130
++#define ADC_CHAN5_INTR_OFFSET		0x134
++#define ADC_CHAN6_INTR_OFFSET		0x138
++#define ADC_CHAN7_INTR_OFFSET		0x13c
++#else
++#define ADC_DATA4_OFFSET		0x54
++#define ADC_DATA5_OFFSET		0x58
++#define ADC_DATA6_OFFSET		0x5c
++#define ADC_DATA7_OFFSET		0x60
++#define ADC_CHAN4_INTR_OFFSET		0x64
++#define ADC_CHAN5_INTR_OFFSET		0x68
++#define ADC_CHAN6_INTR_OFFSET		0x6c
++#define ADC_CHAN7_INTR_OFFSET		0x70
++#endif
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define ADC_DATA8_OFFSET		0x170
++#define ADC_DATA9_OFFSET		0x174
++#define ADC_DATA10_OFFSET		0x178
++#define ADC_DATA11_OFFSET		0x17c
++#define ADC_CHAN8_INTR_OFFSET		0x140
++#define ADC_CHAN9_INTR_OFFSET		0x144
++#define ADC_CHAN10_INTR_OFFSET		0x148
++#define ADC_CHAN11_INTR_OFFSET		0x14c
++#else
++#define ADC_DATA8_OFFSET		0x60
++#define ADC_DATA9_OFFSET		0x70
++#define ADC_CHAN8_INTR_OFFSET		0x120
++#define ADC_CHAN9_INTR_OFFSET		0x124
++#endif
++
++/* S2, S2L and S3 */
++#define ADC_STATUS_OFFSET		0x000
++#define ADC_SLOT_NUM_OFFSET		0x00c
++#define ADC_SLOT_PERIOD_OFFSET		0x010
++#define ADC_CTRL_INTR_TABLE_OFFSET	0x044
++#define ADC_DATA_INTR_TABLE_OFFSET	0x048
++#define ADC_FIFO_INTR_TABLE_OFFSET	0x04c
++#define ADC_ERR_STATUS_OFFSET		0x050
++
++#define ADC_SLOT_CTRL_0_OFFSET		0x100
++#define ADC_SLOT_CTRL_1_OFFSET		0x104
++#define ADC_SLOT_CTRL_2_OFFSET		0x108
++#define ADC_SLOT_CTRL_3_OFFSET		0x10c
++#define ADC_SLOT_CTRL_4_OFFSET		0x110
++#define ADC_SLOT_CTRL_5_OFFSET		0x114
++#define ADC_SLOT_CTRL_6_OFFSET		0x118
++#define ADC_SLOT_CTRL_7_OFFSET		0x11c
++
++#define ADC_FIFO_CTRL_0_OFFSET		0x180
++#define ADC_FIFO_CTRL_1_OFFSET		0x184
++#define ADC_FIFO_CTRL_2_OFFSET		0x188
++#define ADC_FIFO_CTRL_3_OFFSET		0x18C
++#define ADC_FIFO_CTRL_OFFSET		0x190
++
++#define ADC_FIFO_STATUS_0_OFFSET	0x1a0
++#define ADC_FIFO_STATUS_1_OFFSET	0x1a4
++#define ADC_FIFO_STATUS_2_OFFSET	0x1a8
++#define ADC_FIFO_STATUS_3_OFFSET	0x1ac
++
++#define ADC_EC_ADC_OFFSET		0x1C0
++#define ADC_EC_REFVAL_OFFSET		0x1C4
++#define ADC_EC_RESHAPE_OFFSET		0x1C8
++
++#define ADC_FIFO_DATA0_OFFSET		0x200
++#define ADC_FIFO_DATA1_OFFSET		0x280
++#define ADC_FIFO_DATA2_OFFSET		0x300
++#define ADC_FIFO_DATA3_OFFSET		0x380
++
++/* A7 */
++#define ADC_DATA4_SAMPLE0_OFFSET	0x60
++#define ADC_DATA4_SAMPLE1_OFFSET	0x64
++#define ADC_DATA4_SAMPLE2_OFFSET	0x68
++#define ADC_DATA4_SAMPLE3_OFFSET	0x6c
++#define ADC_DATA5_SAMPLE0_OFFSET	0x70
++#define ADC_DATA5_SAMPLE1_OFFSET	0x74
++#define ADC_DATA5_SAMPLE2_OFFSET	0x78
++#define ADC_DATA5_SAMPLE3_OFFSET	0x5c
++
++#define ADC_CONTROL_REG			ADC_REG(ADC_CONTROL_OFFSET)
++#define ADC_COUNTER_REG			ADC_REG(ADC_COUNTER_OFFSET)
++#define ADC_ENABLE_REG			ADC_REG(ADC_ENABLE_OFFSET)
++
++#define ADC_DATA0_REG			ADC_REG(ADC_DATA0_OFFSET)
++#define ADC_DATA1_REG			ADC_REG(ADC_DATA1_OFFSET)
++#define ADC_DATA2_REG			ADC_REG(ADC_DATA2_OFFSET)
++#define ADC_DATA3_REG			ADC_REG(ADC_DATA3_OFFSET)
++#define ADC_DATA4_REG			ADC_REG(ADC_DATA4_OFFSET)
++#define ADC_DATA5_REG			ADC_REG(ADC_DATA5_OFFSET)
++#define ADC_DATA6_REG			ADC_REG(ADC_DATA6_OFFSET)
++#define ADC_DATA7_REG			ADC_REG(ADC_DATA7_OFFSET)
++#define ADC_DATA8_REG			ADC_REG(ADC_DATA8_OFFSET)
++#define ADC_DATA9_REG			ADC_REG(ADC_DATA9_OFFSET)
++
++#define ADC_CHAN0_INTR_REG		ADC_REG(ADC_CHAN0_INTR_OFFSET)
++#define ADC_CHAN1_INTR_REG		ADC_REG(ADC_CHAN1_INTR_OFFSET)
++#define ADC_CHAN2_INTR_REG		ADC_REG(ADC_CHAN2_INTR_OFFSET)
++#define ADC_CHAN3_INTR_REG		ADC_REG(ADC_CHAN3_INTR_OFFSET)
++#define ADC_CHAN4_INTR_REG		ADC_REG(ADC_CHAN4_INTR_OFFSET)
++#define ADC_CHAN5_INTR_REG		ADC_REG(ADC_CHAN5_INTR_OFFSET)
++#define ADC_CHAN6_INTR_REG		ADC_REG(ADC_CHAN6_INTR_OFFSET)
++#define ADC_CHAN7_INTR_REG		ADC_REG(ADC_CHAN7_INTR_OFFSET)
++#define ADC_CHAN8_INTR_REG		ADC_REG(ADC_CHAN8_INTR_OFFSET)
++#define ADC_CHAN9_INTR_REG		ADC_REG(ADC_CHAN9_INTR_OFFSET)
++
++#define ADC_DATA4_SAMPLE0_REG		ADC_REG(ADC_DATA4_SAMPLE0_OFFSET)
++#define ADC_DATA4_SAMPLE1_REG		ADC_REG(ADC_DATA4_SAMPLE1_OFFSET)
++#define ADC_DATA4_SAMPLE2_REG		ADC_REG(ADC_DATA4_SAMPLE2_OFFSET)
++#define ADC_DATA4_SAMPLE3_REG		ADC_REG(ADC_DATA4_SAMPLE3_OFFSET)
++#define ADC_DATA5_SAMPLE0_REG		ADC_REG(ADC_DATA5_SAMPLE0_OFFSET)
++#define ADC_DATA5_SAMPLE1_REG		ADC_REG(ADC_DATA5_SAMPLE1_OFFSET)
++#define ADC_DATA5_SAMPLE2_REG		ADC_REG(ADC_DATA5_SAMPLE2_OFFSET)
++#define ADC_DATA5_SAMPLE3_REG		ADC_REG(ADC_DATA5_SAMPLE3_OFFSET)
++
++/* valid only for S2/S2E/S2L/S3/S3L */
++#define ADC_STATUS_REG			ADC_REG(ADC_STATUS_OFFSET)
++#define ADC_SLOT_NUM_REG		ADC_REG(ADC_SLOT_NUM_OFFSET)
++#define ADC_SLOT_PERIOD_REG		ADC_REG(ADC_SLOT_PERIOD_OFFSET)
++#define ADC_CTRL_INTR_TABLE_REG		ADC_REG(ADC_CTRL_INTR_TABLE_OFFSET)
++#define ADC_DATA_INTR_TABLE_REG		ADC_REG(ADC_DATA_INTR_TABLE_OFFSET)
++#define ADC_FIFO_INTR_TABLE_REG		ADC_REG(ADC_FIFO_INTR_TABLE_OFFSET)
++#define ADC_ERR_STATUS_REG		ADC_REG(ADC_ERR_STATUS_OFFSET)
++
++#define ADC_SLOT_CTRL_0_REG		ADC_REG(ADC_SLOT_CTRL_0_OFFSET)
++#define ADC_SLOT_CTRL_1_REG		ADC_REG(ADC_SLOT_CTRL_1_OFFSET)
++#define ADC_SLOT_CTRL_2_REG		ADC_REG(ADC_SLOT_CTRL_2_OFFSET)
++#define ADC_SLOT_CTRL_3_REG		ADC_REG(ADC_SLOT_CTRL_3_OFFSET)
++#define ADC_SLOT_CTRL_4_REG		ADC_REG(ADC_SLOT_CTRL_4_OFFSET)
++#define ADC_SLOT_CTRL_5_REG		ADC_REG(ADC_SLOT_CTRL_5_OFFSET)
++#define ADC_SLOT_CTRL_6_REG		ADC_REG(ADC_SLOT_CTRL_6_OFFSET)
++#define ADC_SLOT_CTRL_7_REG		ADC_REG(ADC_SLOT_CTRL_7_OFFSET)
++
++#define ADC_FIFO_CTRL_0_REG		ADC_REG(ADC_FIFO_CTRL_0_OFFSET)
++#define ADC_FIFO_CTRL_1_REG		ADC_REG(ADC_FIFO_CTRL_1_OFFSET)
++#define ADC_FIFO_CTRL_2_REG		ADC_REG(ADC_FIFO_CTRL_2_OFFSET)
++#define ADC_FIFO_CTRL_3_REG		ADC_REG(ADC_FIFO_CTRL_3_OFFSET)
++#define ADC_FIFO_CTRL_REG		ADC_REG(ADC_FIFO_CTRL_OFFSET)
++
++#define ADC_FIFO_STATUS_0_REG		ADC_REG(ADC_FIFO_STATUS_0_OFFSET)
++#define ADC_FIFO_STATUS_1_REG		ADC_REG(ADC_FIFO_STATUS_1_OFFSET)
++#define ADC_FIFO_STATUS_2_REG		ADC_REG(ADC_FIFO_STATUS_2_OFFSET)
++#define ADC_FIFO_STATUS_3_REG		ADC_REG(ADC_FIFO_STATUS_3_OFFSET)
++
++#define ADC_EC_ADC_REG			ADC_REG(ADC_EC_ADC_OFFSET)
++#define ADC_EC_REFVAL_REG		ADC_REG(ADC_EC_REFVAL_OFFSET)
++#define ADC_EC_RESHAPE_REG		ADC_REG(ADC_EC_RESHAPE_OFFSET)
++
++#define ADC_FIFO_DATA0_REG		ADC_REG(ADC_FIFO_DATA0_OFFSET)
++#define ADC_FIFO_DATA1_REG		ADC_REG(ADC_FIFO_DATA1_OFFSET)
++#define ADC_FIFO_DATA2_REG		ADC_REG(ADC_FIFO_DATA2_OFFSET)
++#define ADC_FIFO_DATA3_REG		ADC_REG(ADC_FIFO_DATA3_OFFSET)
++
++#define ADC_DATA10_REG			ADC_REG(ADC_DATA10_OFFSET)
++#define ADC_DATA11_REG			ADC_REG(ADC_DATA11_OFFSET)
++#define ADC_CHAN10_INTR_REG		ADC_REG(ADC_CHAN10_INTR_OFFSET)
++#define ADC_CHAN11_INTR_REG		ADC_REG(ADC_CHAN11_INTR_OFFSET)
++
++#if (CHIP_REV == A7L)
++#error "ADC_DATA_REG/ADC_CHAN_INTR_REG(ch) Not Implemented"
++#else
++#define ADC_DATA_OFFSET(ch)		(ADC_DATA0_OFFSET + (ch) * 4)
++#define ADC_DATA_REG(ch)		ADC_REG(ADC_DATA_OFFSET(ch))
++#define ADC_FIFO_CTRL_X_OFFSET(fifoNo)	(ADC_FIFO_CTRL_0_OFFSET + (fifoNo) * 4)
++#define ADC_FIFO_CTRL_X_REG(fifoNo)	ADC_REG(ADC_FIFO_CTRL_X_OFFSET(fifoNo))
++#define ADC_CHAN_INTR_OFFSET(ch)	(ADC_CHAN0_INTR_OFFSET + (ch) * 4)
++#define ADC_CHAN_INTR_REG(ch)		ADC_REG(ADC_CHAN_INTR_OFFSET(ch))
++#endif
++
++#define ADC16_CTRL_OFFSET		0x198
++#define ADC16_CTRL_REG			RCT_REG(ADC16_CTRL_OFFSET)
++
++/* ADC_CONTROL_REG */
++#define ADC_CONTROL_GYRO_SAMPLE_MODE	0x08
++
++/* valid only for S2/S2E/S2L/S3/S3L */
++#define ADC_CONTROL_RESET		0x01
++#define ADC_FIFO_OVER_INT_EN		(0x1 << 31)
++#define ADC_FIFO_UNDR_INT_EN		(0x1 << 30)
++#define ADC_FIFO_DEPTH			0x80
++#define ADC_FIFO_TH			(((ADC_FIFO_DEPTH >> 2)-1) << 16)
++#define ADC_FIFO_CLEAR			0x1
++#define ADC_FIFO_ID_SHIFT		12
++#define ADC_FIFO_CONTROL_CLEAR		0x01
++#define ADC_FIFO_NUMBER		        0x04
++
++#define ADC_CTRL_SCALER_POWERDOWN	0x100
++#define ADC_CTRL_POWERDOWN		0x2
++#define ADC_CTRL_CLK_SOURCE_SCALER	0x0
++#define ADC_CTRL_CLK_SOURCE_AUDIO	0x1
++
++#if (CHIP_REV == A5S)
++#define ADC_CONTROL_MODE		0x04
++#define ADC_CONTROL_ENABLE		0x01
++#define ADC_CONTROL_START		0x02
++#else
++#define ADC_CONTROL_MODE		0x02
++#define ADC_CONTROL_ENABLE		0x04
++#define ADC_CONTROL_START		0x08
++#endif
++#define ADC_CONTROL_STATUS		0x01
++
++#if (CHIP_REV == A5S)
++#define ADC_EN_HI(x)			((x) << 31)
++#define ADC_EN_LO(x)			((x) << 30)
++#else
++#define ADC_EN_HI(x)			((x) << 31)
++#define ADC_EN_LO(x)			((x) << 31)
++#endif
++
++#define ADC_VAL_HI(x)			(((x) & 0xfff) << 16)
++#define ADC_VAL_LO(x)			((x) & 0xfff)
++/* ==========================================================================*/
++
++#define ADC_MAX_SLOT_NUMBER		8
++
++#define ADC_CH0				(1 << 0)
++#define ADC_CH1				(1 << 1)
++#define ADC_CH2				(1 << 2)
++#define ADC_CH3				(1 << 3)
++#define ADC_CH4				(1 << 4)
++#define ADC_CH5				(1 << 5)
++#define ADC_CH6				(1 << 6)
++#define ADC_CH7				(1 << 7)
++#define ADC_CH8				(1 << 8)
++#define ADC_CH9				(1 << 9)
++#define ADC_CH10			(1 << 10)
++#define ADC_CH11			(1 << 11)
++
++enum {
++	AMBADC_ONESHOT = 0,
++	AMBADC_CONTINUOUS,
++};
++
++struct ambadc_host {
++	struct device *dev;
++	u32 irq;
++	u32 clk;
++	bool polling_mode;
++	bool keep_start;
++        bool fifo_mode;
++	struct delayed_work work;
++};
++
++struct ambadc_client;
++typedef int (*ambadc_client_callback)(struct ambadc_client *client,
++			u32 ch, u32 level);
++typedef int (*ambadc_read_level)(u32 ch);
++
++struct ambadc_client {
++	struct device *dev;
++	struct ambadc_host *host;
++	struct list_head node;
++	u32 threshold[ADC_NUM_CHANNELS];
++	u32 mode;
++	ambadc_client_callback callback;
++};
++
++extern struct ambadc_client *ambarella_adc_register_client(struct device *dev,
++			u32 mode, ambadc_client_callback callback);
++extern void ambarella_adc_unregister_client(struct ambadc_client *client);
++
++extern int ambarella_adc_set_threshold(struct ambadc_client *client,
++			u32 ch, u32 low, u32 high);
++extern int ambarella_adc_read_level(u32 ch);
++
++#endif /* __PLAT_AMBARELLA_ADC_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ahci.h b/arch/arm/mach-ambarella/include/plat/ahci.h
+new file mode 100644
+index 00000000..081a2574
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ahci.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ahci.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_AHCI_H__
++#define __PLAT_AMBARELLA_AHCI_H__
++
++/* ==========================================================================*/
++
++#define SATA_OFFSET			0x1A000
++
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_AHCI_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ambasyncproc.h b/arch/arm/mach-ambarella/include/plat/ambasyncproc.h
+new file mode 100644
+index 00000000..375273b4
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ambasyncproc.h
+@@ -0,0 +1,46 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ambasyncproc.h
++ *
++ * Author: Zhenwu Xue <zwxue@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_ASYNC_PROC_H
++#define __PLAT_AMBARELLA_ASYNC_PROC_H
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++struct amb_async_proc_info {
++	char				proc_name[256];
++	struct file_operations		fops;
++	void				*private_data;
++	struct fasync_struct		*fasync_queue;
++	struct mutex			op_mutex;
++	int				use_count;
++};
++
++extern int amb_async_proc_create(struct amb_async_proc_info *pinfo);
++extern int amb_async_proc_remove(struct amb_async_proc_info *pinfo);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ambcache.h b/arch/arm/mach-ambarella/include/plat/ambcache.h
+new file mode 100644
+index 00000000..5520f67f
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ambcache.h
+@@ -0,0 +1,31 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ambcache.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_CACHE_H
++#define __PLAT_AMBARELLA_CACHE_H
++
++#ifndef __ASSEMBLER__
++
++#endif /* __ASSEMBLER__ */
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ambevent.h b/arch/arm/mach-ambarella/include/plat/ambevent.h
+new file mode 100644
+index 00000000..4f29e95f
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ambevent.h
+@@ -0,0 +1,86 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ambevent.h
++ *
++ * History:
++ *    2010/07/23 - [Zhenwu Xue] Create
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __AMB_EVENT_H
++#define __AMB_EVENT_H
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++#include <linux/kobject.h>
++
++/* Copy from build/include/ambas_event.h */
++enum amb_event_type {
++	/* No Event */
++	AMB_EV_NONE				= 0x00000000,
++
++	/* VIN Event */
++	AMB_EV_VIN_DECODER_SOURCE_PLUG		= 0x00010000,
++	AMB_EV_VIN_DECODER_SOURCE_REMOVE,
++
++	/* VOUT Event */
++	AMB_EV_VOUT_CVBS_PLUG			= 0x00020000,
++	AMB_EV_VOUT_CVBS_REMOVE,
++	AMB_EV_VOUT_YPBPR_PLUG,
++	AMB_EV_VOUT_YPBPR_REMOVE,
++	AMB_EV_VOUT_HDMI_PLUG,
++	AMB_EV_VOUT_HDMI_REMOVE,
++
++	/* SENSOR Event*/
++	AMB_EV_ACCELEROMETER_REPORT		= 0x00030000,
++	AMB_EV_MAGNETIC_FIELD_REPORT,
++	AMB_EV_LIGHT_REPORT,
++	AMB_EV_PROXIMITY_REPORT,
++	AMB_EV_GYROSCOPE_REPORT,
++	AMB_EV_TEMPERATURE_REPORT,
++
++	/* FB2 Event */
++	AMB_EV_FB2_PAN_DISPLAY			= 0x00040000,
++
++	/* FDET_EVENT */
++	AMB_EV_FDET_FACE_DETECTED		= 0x00050000,
++};
++
++struct amb_event {
++	u32			sno;		//sequential number
++	u64			time_code;
++	enum amb_event_type	type;
++	u8			data[32];
++};
++
++struct amb_event_pool {
++	struct mutex			op_mutex;
++	struct amb_event		events[256];
++	unsigned int			ev_sno;
++	unsigned char			ev_index;
++};
++
++extern int amb_event_pool_init(struct amb_event_pool *pool);
++extern int amb_event_pool_affuse(struct amb_event_pool *pool,
++	struct amb_event event);
++extern int amb_event_pool_query_index(struct amb_event_pool *pool);
++extern int amb_event_pool_query_event(struct amb_event_pool *pool,
++	struct amb_event *event, unsigned char index);
++extern int amb_event_report_uevent(struct kobject *kobj,
++	enum kobject_action action, char *envp_ext[]);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ambsyncproc.h b/arch/arm/mach-ambarella/include/plat/ambsyncproc.h
+new file mode 100644
+index 00000000..2632949e
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ambsyncproc.h
+@@ -0,0 +1,68 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ambync_proc.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_SYNC_PROC_H
++#define __PLAT_AMBARELLA_SYNC_PROC_H
++
++#include <linux/fs.h>
++
++/* ==========================================================================*/
++#define AMBA_SYNC_PROC_MAX_ID			(31)
++#define AMBA_SYNC_PROC_PAGE_SIZE		(PAGE_SIZE - 16)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++typedef	int(ambsync_read_proc_t)(char *start, void *data);
++
++struct ambsync_proc_pinfo {
++	u32					id;
++	u32					mask;
++	char					*page;
++};
++
++struct ambsync_proc_hinfo {
++	u32					maxid;
++	u32					tmo;
++	wait_queue_head_t			sync_proc_head;
++	atomic_t				sync_proc_flag;
++	struct idr				sync_proc_idr;
++	struct mutex				sync_proc_lock;
++	ambsync_read_proc_t			*sync_read_proc;
++	void					*sync_read_data;
++};
++
++/* ==========================================================================*/
++
++/* ==========================================================================*/
++extern int ambsync_proc_hinit(struct ambsync_proc_hinfo *hinfo);
++extern int ambsync_proc_open(struct inode *inode, struct file *file);
++extern int ambsync_proc_release(struct inode *inode, struct file *file);
++extern ssize_t ambsync_proc_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
++extern ssize_t ambsync_proc_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/audio.h b/arch/arm/mach-ambarella/include/plat/audio.h
+new file mode 100644
+index 00000000..6ddcd327
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/audio.h
+@@ -0,0 +1,203 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/audio.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_AUDIO_H__
++#define __PLAT_AMBARELLA_AUDIO_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define I2S_OFFSET			0x1A000
++#else
++#define I2S_OFFSET			0xA000
++#endif
++#define I2S_BASE			(AHB_BASE + I2S_OFFSET)
++#define I2S_BASE_PHYS 			(AHB_PHYS_BASE + I2S_OFFSET)
++#define I2S_REG(x)			(I2S_BASE + (x))
++#define I2S_REG_PHYS(x)  		(I2S_BASE_PHYS + (x))
++
++/* ==========================================================================*/
++#define I2S_MODE_OFFSET				0x00
++#define I2S_RX_CTRL_OFFSET			0x04
++#define I2S_TX_CTRL_OFFSET			0x08
++#define I2S_WLEN_OFFSET				0x0c
++#define I2S_WPOS_OFFSET				0x10
++#define I2S_SLOT_OFFSET				0x14
++#define I2S_TX_FIFO_LTH_OFFSET			0x18
++#define I2S_RX_FIFO_GTH_OFFSET			0x1c
++#define I2S_CLOCK_OFFSET			0x20
++#define I2S_INIT_OFFSET				0x24
++#define I2S_TX_STATUS_OFFSET			0x28
++#define I2S_TX_LEFT_DATA_OFFSET			0x2c
++#define I2S_TX_RIGHT_DATA_OFFSET		0x30
++#define I2S_RX_STATUS_OFFSET			0x34
++#define I2S_RX_DATA_OFFSET			0x38
++#define I2S_TX_FIFO_CNTR_OFFSET			0x3c
++#define I2S_RX_FIFO_CNTR_OFFSET			0x40
++#define I2S_TX_INT_ENABLE_OFFSET		0x44
++#define I2S_RX_INT_ENABLE_OFFSET		0x48
++#define I2S_RX_ECHO_OFFSET			0x4c
++#define I2S_24BITMUX_MODE_OFFSET		0x50
++#define I2S_GATEOFF_OFFSET			0x54
++#define I2S_CHANNEL_SELECT_OFFSET		0x58
++#define I2S_RX_DATA_DMA_OFFSET			0x80
++#define I2S_TX_LEFT_DATA_DMA_OFFSET		0xc0
++
++#define I2S_MODE_REG				I2S_REG(0x00)
++#define I2S_RX_CTRL_REG				I2S_REG(0x04)
++#define I2S_TX_CTRL_REG				I2S_REG(0x08)
++#define I2S_WLEN_REG				I2S_REG(0x0c)
++#define I2S_WPOS_REG				I2S_REG(0x10)
++#define I2S_SLOT_REG				I2S_REG(0x14)
++#define I2S_TX_FIFO_LTH_REG			I2S_REG(0x18)
++#define I2S_RX_FIFO_GTH_REG			I2S_REG(0x1c)
++#define I2S_CLOCK_REG				I2S_REG(0x20)
++#define I2S_INIT_REG				I2S_REG(0x24)
++#define I2S_TX_STATUS_REG			I2S_REG(0x28)
++#define I2S_TX_LEFT_DATA_REG			I2S_REG(0x2c)
++#define I2S_TX_RIGHT_DATA_REG			I2S_REG(0x30)
++#define I2S_RX_STATUS_REG			I2S_REG(0x34)
++#define I2S_RX_DATA_REG				I2S_REG(0x38)
++#define I2S_TX_FIFO_CNTR_REG			I2S_REG(0x3c)
++#define I2S_RX_FIFO_CNTR_REG			I2S_REG(0x40)
++#define I2S_TX_INT_ENABLE_REG			I2S_REG(0x44)
++#define I2S_RX_INT_ENABLE_REG			I2S_REG(0x48)
++#define I2S_RX_ECHO_REG				I2S_REG(0x4c)
++#define I2S_24BITMUX_MODE_REG			I2S_REG(0x50)
++#define I2S_GATEOFF_REG				I2S_REG(0x54)
++#define I2S_CHANNEL_SELECT_REG			I2S_REG(0x58)
++#define I2S_RX_DATA_DMA_REG			I2S_REG_PHYS(0x80)
++#define I2S_TX_LEFT_DATA_DMA_REG		I2S_REG_PHYS(0xc0)
++
++#define I2S_LEFT_JUSTIFIED_MODE			0x0
++#define I2S_RIGHT_JUSTIFIED_MODE		0x1
++#define I2S_MSB_EXTEND_MODE			0x2
++#define I2S_I2S_MODE				0x4
++#define I2S_DSP_MODE				0x6
++
++#define I2S_TX_FIFO_RESET_BIT			(1 << 4)
++#define I2S_RX_FIFO_RESET_BIT			(1 << 3)
++#define I2S_TX_ENABLE_BIT			(1 << 2)
++#define I2S_RX_ENABLE_BIT			(1 << 1)
++#define I2S_FIFO_RESET_BIT			(1 << 0)
++
++#define I2S_RX_LOOPBACK_BIT			(1 << 3)
++#define I2S_RX_ORDER_BIT			(1 << 2)
++#define I2S_RX_WS_MST_BIT			(1 << 1)
++#define I2S_RX_WS_INV_BIT			(1 << 0)
++
++#define I2S_TX_LOOPBACK_BIT			(1 << 7)
++#define I2S_TX_ORDER_BIT			(1 << 6)
++#define I2S_TX_WS_MST_BIT			(1 << 5)
++#define I2S_TX_WS_INV_BIT			(1 << 4)
++#define I2S_TX_UNISON_BIT			(1 << 3)
++#define I2S_TX_MUTE_BIT				(1 << 2)
++#define I2S_TX_MONO_MASK			0xfffffffc
++#define I2S_TX_MONO_RIGHT			(1 << 1)
++#define I2S_TX_MONO_LEFT			(1 << 0)
++
++#define I2S_CLK_WS_OUT_EN			(1 << 9)
++#define I2S_CLK_BCLK_OUT_EN			(1 << 8)
++#define I2S_CLK_BCLK_OUTPUT			(1 << 7)
++#define I2S_CLK_MASTER_MODE			(I2S_CLK_WS_OUT_EN	|	\
++						 I2S_CLK_BCLK_OUT_EN	|	\
++						 I2S_CLK_BCLK_OUTPUT)
++#define I2S_CLK_TX_PO_FALL			(1 << 6)
++#define I2S_CLK_RX_PO_FALL			(1 << 5)
++#define I2S_CLK_DIV_MASK			0xffffffe0
++
++#define I2S_RX_SHIFT_ENB			(1 << 1)
++#define I2S_TX_SHIFT_ENB			(1 << 0)
++
++#define I2S_2CHANNELS_ENB			0x00
++#define I2S_4CHANNELS_ENB			0x01
++#define I2S_6CHANNELS_ENB			0x02
++
++#define I2S_FIFO_THRESHOLD_INTRPT		0x08
++#define I2S_FIFO_FULL_INTRPT			0x02
++#define I2S_FIFO_EMPTY_INTRPT			0x01
++
++/* I2S_24BITMUX_MODE_REG */
++#define I2S_24BITMUX_MODE_ENABLE		0x1
++#define I2S_24BITMUX_MODE_FDMA_BURST_DIS	0x2
++#define I2S_24BITMUX_MODE_RST_CHAN0		0x4
++#define I2S_24BITMUX_MODE_DMA_BOOTSEL		0x8
++
++/* ==========================================================================*/
++#define DAI_CLOCK_MASK				0x0000001f
++
++#define MAX_MCLK_IDX_NUM			15
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++struct notifier_block;
++
++struct ambarella_i2s_interface {
++	u32 state;
++	u32 mode;
++	u32 clksrc;
++	u32 mclk;
++	u32 div;
++	u32 sfreq;
++	u32 channels;
++	u32 word_len;
++	u32 word_pos;
++	u32 slots;
++	u32 rx_ctrl;
++	u32 tx_ctrl;
++	u32 rx_fifo_len;
++	u32 tx_fifo_len;
++	u32 multi24;
++};
++
++enum Audio_Notify_Type
++{
++	AUDIO_NOTIFY_UNKNOWN,
++	AUDIO_NOTIFY_INIT,
++	AUDIO_NOTIFY_SETHWPARAMS,
++	AUDIO_NOTIFY_REMOVE
++};
++
++#define AMBARELLA_CLKSRC_ONCHIP			0x0
++#define AMBARELLA_CLKSRC_SP_CLK			0x1
++#define AMBARELLA_CLKSRC_CLK_SI			0x2
++#define AMBARELLA_CLKSRC_EXTERNAL		0x3
++#define AMBARELLA_CLKSRC_LVDS_IDSP_SCLK		0x4
++
++#define AMBARELLA_CLKDIV_LRCLK			0
++
++/* ==========================================================================*/
++extern int ambarella_init_audio(void);
++
++extern void ambarella_audio_notify_transition(
++	struct ambarella_i2s_interface *data, unsigned int type);
++extern int ambarella_audio_register_notifier(struct notifier_block *nb);
++extern int ambarella_audio_unregister_notifier(struct notifier_block *nb);
++
++extern struct ambarella_i2s_interface get_audio_i2s_interface(void);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_AUDIO_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/chip.h b/arch/arm/mach-ambarella/include/plat/chip.h
+new file mode 100644
+index 00000000..64683e0c
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/chip.h
+@@ -0,0 +1,83 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/chip.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2013, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_CHIP_H__
++#define __PLAT_AMBARELLA_CHIP_H__
++
++/* ==========================================================================*/
++#define A5S		(5100)
++#define A7L		(7500)
++#define A8		(8000)
++#define S2		(9000)
++#define S2E		(9100)
++#define S2L		(12000)
++#define S3		(11000)
++#define S3L		(13000)
++#define S5		(15000)
++
++#define CHIP_ID(x)	((x / 1000))
++#define CHIP_MAJOR(x)	((x / 100) % 10)
++#define CHIP_MINOR(x)	((x / 10) % 10)
++
++#if	defined(CONFIG_PLAT_AMBARELLA_A5S)
++#define CHIP_REV	A5S
++#elif	defined(CONFIG_PLAT_AMBARELLA_A7L)
++#define CHIP_REV	A7L
++#elif	defined(CONFIG_PLAT_AMBARELLA_S2)
++#define CHIP_REV	S2
++#elif	defined(CONFIG_PLAT_AMBARELLA_S2E)
++#define CHIP_REV	S2E
++#elif	defined(CONFIG_PLAT_AMBARELLA_A8)
++#define CHIP_REV	A8
++#elif	defined(CONFIG_PLAT_AMBARELLA_S2L)
++#define CHIP_REV	S2L
++#elif defined(CONFIG_PLAT_AMBARELLA_S3)
++#define CHIP_REV	S3
++#elif defined(CONFIG_PLAT_AMBARELLA_S3L)
++#define CHIP_REV	S3L
++#elif defined(CONFIG_ARCH_AMBARELLA_S5)
++#define CHIP_REV	S5
++#else
++#error "Undefined CHIP_REV"
++#endif
++
++/* ==========================================================================*/
++#if (CHIP_REV == A8)
++#define REF_CLK_FREQ			27000000
++#else
++#define REF_CLK_FREQ			24000000
++#endif
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
++#define	CHIP_BROKEN_UNALIGNED_ACCESS	1
++#endif
++
++#if (CHIP_REV == S3)
++#define	CHIP_FIX_2NDCORTEX_BOOT	1
++#endif
++
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_CHIP_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/clk.h b/arch/arm/mach-ambarella/include/plat/clk.h
+new file mode 100644
+index 00000000..e4fcc820
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/clk.h
+@@ -0,0 +1,261 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/clk.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_CLK_H__
++#define __PLAT_AMBARELLA_CLK_H__
++
++#include <plat/rct.h>
++
++/* ==========================================================================*/
++enum PLL_CLK_HZ {
++	PLL_CLK_10D1001MHZ	= 9990010,
++	PLL_CLK_10MHZ		= 10000000,
++	PLL_CLK_13D1001MHZ	= 12987012,
++	PLL_CLK_13MHZ		= 13000000,
++	PLL_CLK_13_5D1001MHZ	= 13486513,
++	PLL_CLK_13_5MHZ		= 13500000,
++	PLL_CLK_17_97515MHZ	= 17975154,
++	PLL_CLK_17_97554MHZ	= 17975544,
++	PLL_CLK_17_98201MHZ	= 17982018,
++	PLL_CLK_18_44MHz	= 18440000,
++	PLL_CLK_22_5MHZ		= 22500000,
++	PLL_CLK_23_9772MHZ	= 23977223,
++	PLL_CLK_23_9784MHZ	= 23978422,
++	PLL_CLK_23_99MHZ	= 23998277,
++	PLL_CLK_23_967MHZ	= 23967392,
++	PLL_CLK_23_971MHZ	= 23971444,
++	PLL_CLK_24D1001MHZ	= 23976024,
++	PLL_CLK_23_996MHZ	= 23996483,
++	PLL_CLK_24MHZ		= 24000000,
++	PLL_CLK_24M1001MHZ	= 24024000,
++	PLL_CLK_24_072MHZ	= 24072001,
++	PLL_CLK_24_3MHZ		= 24300000,
++	PLL_CLK_24_54MHZ	= 24545430,
++	PLL_CLK_25MHZ		= 25000000,
++	PLL_CLK_27D1001MHZ	= 26973027,
++	PLL_CLK_26_9823MHZ	= 26982318,
++	PLL_CLK_26_9485MHZ	= 26948544,
++	PLL_CLK_26_9568MHZ	= 26956800,
++	PLL_CLK_27MHZ		= 27000000,
++	PLL_CLK_27_0432MHZ	= 27043200,
++	PLL_CLK_27_0514MHZ	= 27051402,
++	PLL_CLK_27M1001MHZ	= 27027000,
++	PLL_CLK_30MHZ		= 30000000,
++	PLL_CLK_27_1792MHZ	= 27179210,
++	PLL_CLK_32_5D1001MHZ	= 32467532,
++	PLL_CLK_36D1001MHZ	= 35964036,
++	PLL_CLK_36MHZ		= 36000000,
++	PLL_CLK_36_20MHZ	= 36197802,
++	PLL_CLK_36_23MHZ	= 36234000,
++	PLL_CLK_37_125D1001MHZ	= 37087912,
++	PLL_CLK_37_125MHZ	= 37125000,
++	PLL_CLK_42D1001MHZ	= 41958042,
++	PLL_CLK_42MHZ		= 42000000,
++	PLL_CLK_45MHZ		= 45000000,
++	PLL_CLK_48D1001MHZ	= 47952048,
++	PLL_CLK_48MHZ		= 48000000,
++	PLL_CLK_48_6MHZ		= 48600000,
++	PLL_CLK_49_5D1001MHZ	= 49450549,
++	PLL_CLK_49_5MHZ		= 49500000,
++	PLL_CLK_54MHZ		= 54000000,
++	PLL_CLK_54M1001MHZ	= 54054000,
++	PLL_CLK_59_4MHZ		= 59400000,
++	PLL_CLK_60MHZ		= 60000000,
++	PLL_CLK_60M1001MHZ	= 60060000,
++	PLL_CLK_60_05MHz	= 60054545,
++	PLL_CLK_60_16MHZ	= 60164835,
++	PLL_CLK_60_18MHZ	= 60183566,
++	PLL_CLK_60_29MHZ	= 60285794,
++	PLL_CLK_60_33MHZ	= 60329670,
++	PLL_CLK_60_35MHZ	= 60346080,
++	PLL_CLK_60_39MHZ	= 60390000,
++	PLL_CLK_60_48MHz	= 60480000,
++	PLL_CLK_64D1001MHZ	= 63936064,
++	PLL_CLK_64MHZ		= 64000000,
++	PLL_CLK_65D1001MHZ	= 64935064,
++	PLL_CLK_72D1001MHZ	= 71928072,
++	PLL_CLK_72MHZ		= 72000000,
++	PLL_CLK_74_25D1001MHZ	= 74175824,
++	PLL_CLK_74_25MHZ	= 74250000,
++	PLL_CLK_80MHZ		= 80000000,
++	PLL_CLK_90D1001MHZ	= 89910090,
++	PLL_CLK_90MHZ		= 90000000,
++	PLL_CLK_90_62D1001MHZ	= 90525314,
++	PLL_CLK_90_62MHZ	= 90615840,
++	PLL_CLK_90_69D1001MHZ	= 90596763,
++	PLL_CLK_90_69MHZ	= 90687360,
++	PLL_CLK_95_993D1001MHZ	= 95896903,
++	PLL_CLK_96D1001MHZ	= 95904096,
++	PLL_CLK_96MHZ		= 96000000,
++	PLL_CLK_99D1001MHZ	= 98901099,
++	PLL_CLK_99MHZ		= 99000000,
++	PLL_CLK_99_18D1001MHZ	= 99081439,
++	PLL_CLK_99_18MHZ	= 99180720,
++	PLL_CLK_108MHZ		= 108000000,
++	PLL_CLK_148_5D1001MHZ	= 148351648,
++	PLL_CLK_148_5MHZ	= 148500000,
++	PLL_CLK_120MHZ		= 120000000,
++	PLL_CLK_144MHZ		= 144000000,
++	PLL_CLK_150MHZ		= 150000000,
++	PLL_CLK_156MHZ		= 156000000,
++	PLL_CLK_160MHZ		= 160000000,
++	PLL_CLK_192MHZ		= 192000000,
++	PLL_CLK_216MHZ		= 216000000,
++	PLL_CLK_230_4MHZ	= 230400000,
++	PLL_CLK_240MHZ		= 240000000,
++	PLL_CLK_288MHZ		= 288000000,
++	PLL_CLK_296_703MHZ	= 296703000,
++	PLL_CLK_297MHZ		= 297000000,
++	PLL_CLK_320MHZ		= 320000000,
++	PLL_CLK_384MHZ		= 384000000,
++	PLL_CLK_495MHZ		= 495000000,
++	PLL_CLK_594MHZ		= 594000000,
++};
++
++struct clk;
++struct clk_ops {
++	int			(*enable)(struct clk *c);
++	int			(*disable)(struct clk *c);
++	unsigned long		(*get_rate)(struct clk *c);
++	unsigned long		(*round_rate)(struct clk *c, unsigned long rate);
++	int			(*set_rate)(struct clk *c, unsigned long rate);
++	int			(*set_parent)(struct clk *c, struct clk *parent);
++};
++
++struct clk {
++	struct list_head	list;
++	struct clk		*parent;
++	const char		*name;
++	u64			rate;
++	u32			frac_mode;
++	u32			ctrl_reg;
++	u32			pres_reg;
++	u32			pres_val;
++	u32			post_reg;
++	u32			post_val;
++	u32			frac_reg;
++	u32			ctrl2_reg;
++	u32			ctrl2_val;
++	u32			ctrl3_reg;
++	u32			ctrl3_val;
++	u32			lock_reg;
++	u32			lock_bit;
++	u32			divider;
++	u32			max_divider;
++	u32			extra_scaler;
++	struct pll_table	*table;
++	u32			table_size;
++	struct clk_ops		*ops;
++};
++
++struct pll_table {
++	u64	multiplier; /* pll_out / (ref_clk / pre_scaler) */
++
++	u32	intp;
++	u32	sdiv;
++	u32	sout;
++	u32	post;
++};
++
++union ctrl_reg_u {
++	struct {
++		u32	write_enable		: 1;	/* [0] */
++		u32	reserved1		: 1;	/* [1] */
++		u32	bypass			: 1;	/* [2] */
++		u32	frac_mode		: 1;	/* [3] */
++		u32	force_reset		: 1;	/* [4] */
++		u32	power_down		: 1;	/* [5] */
++		u32	halt_vco		: 1;	/* [6] */
++		u32	tristate		: 1;	/* [7] */
++		u32	tout_async		: 4;	/* [11:8] */
++		u32	sdiv			: 4;	/* [15:12] */
++		u32	sout			: 4;	/* [19:16] */
++		u32	force_lock		: 1;	/* [20] */
++		u32	force_bypass		: 1;	/* [21] */
++		u32	reserved2		: 2;	/* [23:22] */
++		u32	intp			: 7;	/* [30:24] */
++		u32	reserved3		: 1;	/* [31] */
++	} s;
++	u32	w;
++};
++
++union frac_reg_u {
++	struct {
++		u32	frac			: 31;	/* [30:0] */
++		u32	nega			: 1;	/* [31] */
++	} s;
++	u32	w;
++};
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#define AMBCLK_DO_DIV(divident, divider)	do {	\
++	do_div((divident), (divider));			\
++	} while (0)
++
++#define AMBCLK_DO_DIV_ROUND(divident, divider)	do {	\
++	(divident) += ((divider) >> 1);			\
++	do_div((divident), (divider));			\
++	} while (0)
++
++extern struct clk_ops ambarella_rct_pll_ops;
++extern struct clk_ops ambarella_rct_scaler_ops;
++
++#ifdef CONFIG_AMBARELLA_CALC_PLL
++#define AMBARELLA_PLL_FRAC_TABLE_SIZE		(0)
++extern struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE];
++#define AMBARELLA_PLL_INT_TABLE_SIZE		(0)
++extern struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE];
++#else
++#define AMBARELLA_PLL_FRAC_TABLE_SIZE		(590)
++extern struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE];
++#define AMBARELLA_PLL_INT_TABLE_SIZE		(93)
++extern struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE];
++#define AMBARELLA_PLL_VOUT_TABLE_SIZE		(797)
++extern struct pll_table ambarella_pll_vout_table[AMBARELLA_PLL_VOUT_TABLE_SIZE];
++#define AMBARELLA_PLL_VOUT2_TABLE_SIZE		(793)
++extern struct pll_table ambarella_pll_vout2_table[AMBARELLA_PLL_VOUT2_TABLE_SIZE];
++#endif
++
++extern u32 ambarella_rct_find_pll_table_index(unsigned long rate,
++		u32 pre_scaler, const struct pll_table *table, u32 table_size);
++
++extern unsigned long ambarella_rct_clk_get_rate(struct clk *c);
++extern int ambarella_rct_clk_set_rate(struct clk *c, unsigned long rate);
++extern int ambarella_rct_clk_adj_rate(struct clk *c, unsigned long rate);
++extern int ambarella_rct_clk_enable(struct clk *c);
++extern int ambarella_rct_clk_disable(struct clk *c);
++
++extern unsigned long ambarella_rct_scaler_get_rate(struct clk *c);
++extern int ambarella_rct_scaler_set_rate(struct clk *c, unsigned long rate);
++
++extern int ambarella_clk_init(void);
++extern int ambarella_clk_add(struct clk *clk);
++extern unsigned int ambarella_clk_get_ref_freq(void);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/cortex.h b/arch/arm/mach-ambarella/include/plat/cortex.h
+new file mode 100644
+index 00000000..4e84793d
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/cortex.h
+@@ -0,0 +1,71 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/cortex.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_CORTEX_H
++#define __PLAT_AMBARELLA_CORTEX_H
++
++/* ==========================================================================*/
++#define AMBARELLA_VA_SCU_BASE			(AXI_BASE + 0x00000000)
++#define AMBARELLA_VA_GIC_CPU_BASE		(AXI_BASE + 0x00000100)
++#define AMBARELLA_VA_GT_BASE			(AXI_BASE + 0x00000200)
++#define AMBARELLA_VA_PT_WD_BASE			(AXI_BASE + 0x00000600)
++#define AMBARELLA_VA_GIC_DIST_BASE		(AXI_BASE + 0x00001000)
++#define AMBARELLA_VA_L2CC_BASE			(AXI_BASE + 0x00002000)
++
++#define AMBARELLA_PA_SCU_BASE			(AXI_PHYS_BASE + 0x00000000)
++#define AMBARELLA_PA_GIC_CPU_BASE		(AXI_PHYS_BASE + 0x00000100)
++#define AMBARELLA_PA_GT_BASE			(AXI_PHYS_BASE + 0x00000200)
++#define AMBARELLA_PA_PT_WD_BASE			(AXI_PHYS_BASE + 0x00000600)
++#define AMBARELLA_PA_GIC_DIST_BASE		(AXI_PHYS_BASE + 0x00001000)
++#define AMBARELLA_PA_L2CC_BASE			(AXI_PHYS_BASE + 0x00002000)
++
++/* ==========================================================================*/
++#define PROCESSOR_START_0			(0)
++#define PROCESSOR_START_1			(1)
++#define PROCESSOR_START_2			(2)
++#define PROCESSOR_START_3			(3)
++
++#define PROCESSOR_STATUS_0			(4)
++#define PROCESSOR_STATUS_1			(5)
++#define PROCESSOR_STATUS_2			(6)
++#define PROCESSOR_STATUS_3			(7)
++
++#define ICDISER0_MASK				(8)
++#define INTDIS_LOCKER				(9)
++#define INTDIS_STATUS				(10)
++
++#define MACHINE_ID				(11)
++#define ATAG_DATA				(12)
++
++#define AMBARELLA_BST_HEAD_CACHE_SIZE		(32)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/cpufreq.h b/arch/arm/mach-ambarella/include/plat/cpufreq.h
+new file mode 100644
+index 00000000..998a3519
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/cpufreq.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/cpufreq.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_CPUFREQ_H
++#define __PLAT_AMBARELLA_CPUFREQ_H
++
++#include <linux/cpufreq.h>
++
++struct ambarella_cpufreq_config {
++	struct cpufreq_frequency_table *freq_table;
++	int (*set_voltage) (unsigned int index);
++	int (*init) (void);
++	int (*exit) (void);
++};
++
++#endif
+diff --git a/arch/arm/mach-ambarella/include/plat/crypto.h b/arch/arm/mach-ambarella/include/plat/crypto.h
+new file mode 100644
+index 00000000..002469d7
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/crypto.h
+@@ -0,0 +1,342 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/crypto.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_CRYPTO_H__
++#define __PLAT_AMBARELLA_CRYPTO_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define CRYPT_UNIT_OFFSET		0x14000
++#define CRYPT_UNIT_BASE			(AHB_BASE + CRYPT_UNIT_OFFSET)
++#else
++#define CRYPT_UNIT_OFFSET		0x20000
++#define CRYPT_UNIT_BASE			(AXI_BASE + CRYPT_UNIT_OFFSET)
++#endif
++
++#define CRYPT_UNIT_REG(x)		(CRYPT_UNIT_BASE + (x))
++
++#define DES_OFFSET(x)			(x)
++#define AES_OFFSET(x)			((1 << 9) | (x))
++#define SHA1_MD5_OFFSET(x)		((2 << 9) | (x))
++
++#define DES_REG(x)			CRYPT_UNIT_REG(DES_OFFSET(x))
++#define AES_REG(x)			CRYPT_UNIT_REG(AES_OFFSET(x))
++#define SHA1_MD5_REG(x)			CRYPT_UNIT_REG(SHA1_MD5_OFFSET(x))
++
++/* ==========================================================================*/
++
++/* AES/DES */
++
++
++#define CRYPT_D_HI_OFFSET			0x00
++#define CRYPT_D_LO_OFFSET			0x04
++#define CRYPT_D_INPUT_ENC_HI_OFFSET		0x08
++#define CRYPT_D_INPUT_ENC_LO_OFFSET		0x0c
++#define CRYPT_D_INPUT_DEC_HI_OFFSET		0x10
++#define CRYPT_D_INPUT_DEC_LO_OFFSET		0x14
++#define CRYPT_D_OUTPUT_HI_OFFSET		0x18
++#define CRYPT_D_OUTPUT_LO_OFFSET		0x1c
++#define CRYPT_D_OUTPUT_READY_OFFSET		0x20
++#define CRYPT_D_INT_EN_OFFSET			0x28
++
++#define CRYPT_A_256_224_OFFSET			0x00
++#define CRYPT_A_256_192_OFFSET			0x04
++#define CRYPT_A_256_160_OFFSET			0x08
++#define CRYPT_A_256_128_OFFSET			0x0c
++#define CRYPT_A_256_96_OFFSET			0x10
++#define CRYPT_A_256_64_OFFSET			0x14
++#define CRYPT_A_256_32_OFFSET			0x18
++#define CRYPT_A_256_0_OFFSET			0x1c
++#define CRYPT_A_192_160_OFFSET			0x20
++#define CRYPT_A_192_128_OFFSET			0x24
++#define CRYPT_A_192_96_OFFSET			0x28
++#define CRYPT_A_192_64_OFFSET			0x2c
++#define CRYPT_A_192_32_OFFSET			0x30
++#define CRYPT_A_192_0_OFFSET			0x34
++#define CRYPT_A_128_96_OFFSET			0x38
++#define CRYPT_A_128_64_OFFSET			0x3c
++#define CRYPT_A_128_32_OFFSET			0x40
++#define CRYPT_A_128_0_OFFSET			0x44
++
++#define CRYPT_A_INPUT_ENC_96_OFFSET		0x48
++#define CRYPT_A_INPUT_ENC_64_OFFSET		0x4c
++#define CRYPT_A_INPUT_ENC_32_OFFSET		0x50
++#define CRYPT_A_INPUT_ENC_0_OFFSET		0x54
++#define CRYPT_A_INPUT_DEC_96_OFFSET		0x58
++#define CRYPT_A_INPUT_DEC_64_OFFSET		0x5c
++#define CRYPT_A_INPUT_DEC_32_OFFSET		0x60
++#define CRYPT_A_INPUT_DEC_0_OFFSET		0x64
++#define CRYPT_A_OUTPUT_96_OFFSET		0x68
++#define CRYPT_A_OUTPUT_64_OFFSET		0x6c
++#define CRYPT_A_OUTPUT_32_OFFSET		0x70
++#define CRYPT_A_OUTPUT_0_OFFSET			0x74
++#define CRYPT_A_OUTPUT_READY_OFFSET		0x78
++#define CRYPT_A_INT_EN_OFFSET			0x80
++
++#define CRYPT_D_HI_REG				DES_REG(0x00)
++#define CRYPT_D_LO_REG				DES_REG(0x04)
++#define CRYPT_D_INPUT_ENC_HI_REG		DES_REG(0x08)
++#define CRYPT_D_INPUT_ENC_LO_REG		DES_REG(0x0c)
++#define CRYPT_D_INPUT_DEC_HI_REG		DES_REG(0x10)
++#define CRYPT_D_INPUT_DEC_LO_REG		DES_REG(0x14)
++#define CRYPT_D_OUTPUT_HI_REG			DES_REG(0x18)
++#define CRYPT_D_OUTPUT_LO_REG			DES_REG(0x1c)
++#define CRYPT_D_OUTPUT_READY_REG		DES_REG(0x20)
++#define CRYPT_D_INT_EN_REG			DES_REG(0x28)
++
++#define CRYPT_A_256_224_REG			AES_REG(0x00)
++#define CRYPT_A_256_192_REG			AES_REG(0x04)
++#define CRYPT_A_256_160_REG			AES_REG(0x08)
++#define CRYPT_A_256_128_REG			AES_REG(0x0c)
++#define CRYPT_A_256_96_REG			AES_REG(0x10)
++#define CRYPT_A_256_64_REG			AES_REG(0x14)
++#define CRYPT_A_256_32_REG			AES_REG(0x18)
++#define CRYPT_A_256_0_REG			AES_REG(0x1c)
++#define CRYPT_A_192_160_REG			AES_REG(0x20)
++#define CRYPT_A_192_128_REG			AES_REG(0x24)
++#define CRYPT_A_192_96_REG			AES_REG(0x28)
++#define CRYPT_A_192_64_REG			AES_REG(0x2c)
++#define CRYPT_A_192_32_REG			AES_REG(0x30)
++#define CRYPT_A_192_0_REG			AES_REG(0x34)
++#define CRYPT_A_128_96_REG			AES_REG(0x38)
++#define CRYPT_A_128_64_REG			AES_REG(0x3c)
++#define CRYPT_A_128_32_REG			AES_REG(0x40)
++#define CRYPT_A_128_0_REG			AES_REG(0x44)
++
++#define CRYPT_A_INPUT_ENC_96_REG		AES_REG(0x48)
++#define CRYPT_A_INPUT_ENC_64_REG		AES_REG(0x4c)
++#define CRYPT_A_INPUT_ENC_32_REG		AES_REG(0x50)
++#define CRYPT_A_INPUT_ENC_0_REG			AES_REG(0x54)
++#define CRYPT_A_INPUT_DEC_96_REG		AES_REG(0x58)
++#define CRYPT_A_INPUT_DEC_64_REG		AES_REG(0x5c)
++#define CRYPT_A_INPUT_DEC_32_REG		AES_REG(0x60)
++#define CRYPT_A_INPUT_DEC_0_REG			AES_REG(0x64)
++#define CRYPT_A_OUTPUT_96_REG			AES_REG(0x68)
++#define CRYPT_A_OUTPUT_64_REG			AES_REG(0x6c)
++#define CRYPT_A_OUTPUT_32_REG			AES_REG(0x70)
++#define CRYPT_A_OUTPUT_0_REG			AES_REG(0x74)
++#define CRYPT_A_OUTPUT_READY_REG		AES_REG(0x78)
++#define CRYPT_A_INT_EN_REG			AES_REG(0x80)
++
++
++/* ==========================================================================*/
++
++/* SHA1/MD5 */
++
++#define CRYPT_SHA1_INIT_31_0_OFFSET		SHA1_MD5_OFFSET(0x0)
++#define CRYPT_SHA1_INIT_63_32_OFFSET		SHA1_MD5_OFFSET(0x4)
++#define CRYPT_SHA1_INIT_95_64_OFFSET		SHA1_MD5_OFFSET(0x8)
++#define CRYPT_SHA1_INIT_127_96_OFFSET		SHA1_MD5_OFFSET(0xc)
++#define CRYPT_SHA1_INIT_159_128_OFFSET		SHA1_MD5_OFFSET(0x10)
++#define CRYPT_SHA1_INPUT_31_0_OFFSET		SHA1_MD5_OFFSET(0x18)
++#define CRYPT_SHA1_INPUT_63_32_OFFSET		SHA1_MD5_OFFSET(0x1c)
++#define CRYPT_SHA1_INPUT_95_64_OFFSET		SHA1_MD5_OFFSET(0x20)
++#define CRYPT_SHA1_INPUT_127_96_OFFSET		SHA1_MD5_OFFSET(0x24)
++#define CRYPT_SHA1_INPUT_159_128_OFFSET		SHA1_MD5_OFFSET(0x28)
++#define CRYPT_SHA1_INPUT_191_160_OFFSET		SHA1_MD5_OFFSET(0x2c)
++#define CRYPT_SHA1_INPUT_223_192_OFFSET		SHA1_MD5_OFFSET(0x30)
++#define CRYPT_SHA1_INPUT_255_224_OFFSET		SHA1_MD5_OFFSET(0x34)
++#define CRYPT_SHA1_INPUT_287_256_OFFSET		SHA1_MD5_OFFSET(0x38)
++#define CRYPT_SHA1_INPUT_319_288_OFFSET		SHA1_MD5_OFFSET(0x3c)
++#define CRYPT_SHA1_INPUT_351_320_OFFSET		SHA1_MD5_OFFSET(0x40)
++#define CRYPT_SHA1_INPUT_383_352_OFFSET		SHA1_MD5_OFFSET(0x44)
++#define CRYPT_SHA1_INPUT_415_384_OFFSET		SHA1_MD5_OFFSET(0x48)
++#define CRYPT_SHA1_INPUT_447_416_OFFSET		SHA1_MD5_OFFSET(0x4c)
++#define CRYPT_SHA1_INPUT_479_448_OFFSET		SHA1_MD5_OFFSET(0x50)
++#define CRYPT_SHA1_INPUT_511_480_OFFSET		SHA1_MD5_OFFSET(0x54)
++#define CRYPT_SHA1_OUTPUT_31_0_OFFSET		SHA1_MD5_OFFSET(0x58)
++#define CRYPT_SHA1_OUTPUT_63_32_OFFSET		SHA1_MD5_OFFSET(0x5c)
++#define CRYPT_SHA1_OUTPUT_95_64_OFFSET		SHA1_MD5_OFFSET(0x60)
++#define CRYPT_SHA1_OUTPUT_127_96_OFFSET		SHA1_MD5_OFFSET(0x64)
++#define CRYPT_SHA1_OUTPUT_159_128_OFFSET	SHA1_MD5_OFFSET(0x68)
++#define CRYPT_SHA1_OUTPUT_READY_OFFSET		SHA1_MD5_OFFSET(0x70)
++#define CRYPT_SHA1_INT_EN_OFFSET		SHA1_MD5_OFFSET(0x78)
++#define CRYPT_MD5_INIT_31_0_OFFSET		SHA1_MD5_OFFSET(0x80)
++#define CRYPT_MD5_INIT_63_32_OFFSET		SHA1_MD5_OFFSET(0x84)
++#define CRYPT_MD5_INIT_95_64_OFFSET		SHA1_MD5_OFFSET(0x88)
++#define CRYPT_MD5_INIT_127_96_OFFSET		SHA1_MD5_OFFSET(0x8c)
++#define CRYPT_MD5_INPUT_31_0_OFFSET		SHA1_MD5_OFFSET(0x90)
++#define CRYPT_MD5_INPUT_63_32_OFFSET		SHA1_MD5_OFFSET(0x94)
++#define CRYPT_MD5_INPUT_95_64_OFFSET		SHA1_MD5_OFFSET(0x98)
++#define CRYPT_MD5_INPUT_127_96_OFFSET		SHA1_MD5_OFFSET(0x9c)
++#define CRYPT_MD5_INPUT_159_128_OFFSET		SHA1_MD5_OFFSET(0xa0)
++#define CRYPT_MD5_INPUT_191_160_OFFSET		SHA1_MD5_OFFSET(0xa4)
++#define CRYPT_MD5_INPUT_223_192_OFFSET		SHA1_MD5_OFFSET(0xa8)
++#define CRYPT_MD5_INPUT_255_224_OFFSET		SHA1_MD5_OFFSET(0xac)
++#define CRYPT_MD5_INPUT_287_256_OFFSET		SHA1_MD5_OFFSET(0xb0)
++#define CRYPT_MD5_INPUT_319_288_OFFSET		SHA1_MD5_OFFSET(0xb4)
++#define CRYPT_MD5_INPUT_351_320_OFFSET		SHA1_MD5_OFFSET(0xb8)
++#define CRYPT_MD5_INPUT_383_352_OFFSET		SHA1_MD5_OFFSET(0xbc)
++#define CRYPT_MD5_INPUT_415_384_OFFSET		SHA1_MD5_OFFSET(0xc0)
++#define CRYPT_MD5_INPUT_447_416_OFFSET		SHA1_MD5_OFFSET(0xc4)
++#define CRYPT_MD5_INPUT_479_448_OFFSET		SHA1_MD5_OFFSET(0xc8)
++#define CRYPT_MD5_INPUT_511_480_OFFSET		SHA1_MD5_OFFSET(0xcc)
++#define CRYPT_MD5_OUTPUT_31_0_OFFSET		SHA1_MD5_OFFSET(0xd0)
++#define CRYPT_MD5_OUTPUT_63_32_OFFSET		SHA1_MD5_OFFSET(0xd4)
++#define CRYPT_MD5_OUTPUT_95_64_OFFSET		SHA1_MD5_OFFSET(0xd8)
++#define CRYPT_MD5_OUTPUT_127_96_OFFSET		SHA1_MD5_OFFSET(0xdc)
++#define CRYPT_MD5_OUTPUT_READY_OFFSET		SHA1_MD5_OFFSET(0xe0)
++#define CRYPT_MD5_INT_EN_OFFSET			SHA1_MD5_OFFSET(0xe8)
++#define CRYPT_MD5_SHA1_READY_INPUT_OFFSET	SHA1_MD5_OFFSET(0xf0)
++
++#define CRYPT_SHA1_INIT_31_0_REG		SHA1_MD5_REG(0x0)
++#define CRYPT_SHA1_INIT_63_32_REG		SHA1_MD5_REG(0x4)
++#define CRYPT_SHA1_INIT_95_64_REG		SHA1_MD5_REG(0x8)
++#define CRYPT_SHA1_INIT_127_96_REG		SHA1_MD5_REG(0xc)
++#define CRYPT_SHA1_INIT_159_128_REG		SHA1_MD5_REG(0x10)
++#define CRYPT_SHA1_INPUT_31_0_REG		SHA1_MD5_REG(0x18)
++#define CRYPT_SHA1_INPUT_63_32_REG		SHA1_MD5_REG(0x1c)
++#define CRYPT_SHA1_INPUT_95_64_REG		SHA1_MD5_REG(0x20)
++#define CRYPT_SHA1_INPUT_127_96_REG		SHA1_MD5_REG(0x24)
++#define CRYPT_SHA1_INPUT_159_128_REG		SHA1_MD5_REG(0x28)
++#define CRYPT_SHA1_INPUT_191_160_REG		SHA1_MD5_REG(0x2c)
++#define CRYPT_SHA1_INPUT_223_192_REG		SHA1_MD5_REG(0x30)
++#define CRYPT_SHA1_INPUT_255_224_REG		SHA1_MD5_REG(0x34)
++#define CRYPT_SHA1_INPUT_287_256_REG		SHA1_MD5_REG(0x38)
++#define CRYPT_SHA1_INPUT_319_288_REG		SHA1_MD5_REG(0x3c)
++#define CRYPT_SHA1_INPUT_351_320_REG		SHA1_MD5_REG(0x40)
++#define CRYPT_SHA1_INPUT_383_352_REG		SHA1_MD5_REG(0x44)
++#define CRYPT_SHA1_INPUT_415_384_REG		SHA1_MD5_REG(0x48)
++#define CRYPT_SHA1_INPUT_447_416_REG		SHA1_MD5_REG(0x4c)
++#define CRYPT_SHA1_INPUT_479_448_REG		SHA1_MD5_REG(0x50)
++#define CRYPT_SHA1_INPUT_511_480_REG		SHA1_MD5_REG(0x54)
++#define CRYPT_SHA1_OUTPUT_31_0_REG		SHA1_MD5_REG(0x58)
++#define CRYPT_SHA1_OUTPUT_63_32_REG		SHA1_MD5_REG(0x5c)
++#define CRYPT_SHA1_OUTPUT_95_64_REG		SHA1_MD5_REG(0x60)
++#define CRYPT_SHA1_OUTPUT_127_96_REG		SHA1_MD5_REG(0x64)
++#define CRYPT_SHA1_OUTPUT_159_128_REG		SHA1_MD5_REG(0x68)
++#define CRYPT_SHA1_OUTPUT_READY_REG		SHA1_MD5_REG(0x70)
++#define CRYPT_SHA1_INT_EN_REG			SHA1_MD5_REG(0x78)
++#define CRYPT_MD5_INIT_31_0_REG			SHA1_MD5_REG(0x80)
++#define CRYPT_MD5_INIT_63_32_REG		SHA1_MD5_REG(0x84)
++#define CRYPT_MD5_INIT_95_64_REG		SHA1_MD5_REG(0x88)
++#define CRYPT_MD5_INIT_127_96_REG		SHA1_MD5_REG(0x8c)
++#define CRYPT_MD5_INPUT_31_0_REG		SHA1_MD5_REG(0x90)
++#define CRYPT_MD5_INPUT_63_32_REG		SHA1_MD5_REG(0x94)
++#define CRYPT_MD5_INPUT_95_64_REG		SHA1_MD5_REG(0x98)
++#define CRYPT_MD5_INPUT_127_96_REG		SHA1_MD5_REG(0x9c)
++#define CRYPT_MD5_INPUT_159_128_REG		SHA1_MD5_REG(0xa0)
++#define CRYPT_MD5_INPUT_191_160_REG		SHA1_MD5_REG(0xa4)
++#define CRYPT_MD5_INPUT_223_192_REG		SHA1_MD5_REG(0xa8)
++#define CRYPT_MD5_INPUT_255_224_REG		SHA1_MD5_REG(0xac)
++#define CRYPT_MD5_INPUT_287_256_REG		SHA1_MD5_REG(0xb0)
++#define CRYPT_MD5_INPUT_319_288_REG		SHA1_MD5_REG(0xb4)
++#define CRYPT_MD5_INPUT_351_320_REG		SHA1_MD5_REG(0xb8)
++#define CRYPT_MD5_INPUT_383_352_REG		SHA1_MD5_REG(0xbc)
++#define CRYPT_MD5_INPUT_415_384_REG		SHA1_MD5_REG(0xc0)
++#define CRYPT_MD5_INPUT_447_416_REG		SHA1_MD5_REG(0xc4)
++#define CRYPT_MD5_INPUT_479_448_REG		SHA1_MD5_REG(0xc8)
++#define CRYPT_MD5_INPUT_511_480_REG		SHA1_MD5_REG(0xcc)
++#define CRYPT_MD5_OUTPUT_31_0_REG		SHA1_MD5_REG(0xd0)
++#define CRYPT_MD5_OUTPUT_63_32_REG		SHA1_MD5_REG(0xd4)
++#define CRYPT_MD5_OUTPUT_95_64_REG		SHA1_MD5_REG(0xd8)
++#define CRYPT_MD5_OUTPUT_127_96_REG		SHA1_MD5_REG(0xdc)
++#define CRYPT_MD5_OUTPUT_READY_REG		SHA1_MD5_REG(0xe0)
++#define CRYPT_MD5_INT_EN_REG			SHA1_MD5_REG(0xe8)
++#define CRYPT_MD5_SHA1_READY_INPUT_REG		SHA1_MD5_REG(0xf0)
++
++/* ==========================================================================*/
++#define AMBARELLA_CRYPTO_ALIGNMENT	(16)
++#define AMBARELLA_CRA_PRIORITY		(300)
++#define AMBARELLA_COMPOSITE_PRIORITY	(400)
++
++#define AMBA_HW_ENCRYPT_CMD		(0)
++#define AMBA_HW_DECRYPT_CMD		(1)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#define	CRYPT_A_INPUT1			CRYPT_A_INPUT_ENC_96_REG
++#define	CRYPT_A_INPUT2			CRYPT_A_INPUT_DEC_96_REG
++#define	CRYPT_A_OPCODE			NULL
++#define	CRYPT_D_INPUT1			CRYPT_D_INPUT_ENC_HI_REG
++#define	CRYPT_D_INPUT2			CRYPT_D_INPUT_DEC_HI_REG
++#define	CRYPT_D_OPCODE			NULL
++
++#define	CRYPT_MD5_SHA1_READY_INPUT	CRYPT_MD5_SHA1_READY_INPUT_REG
++#define	CRYPT_MD5_INIT_31_0		CRYPT_MD5_INIT_31_0_REG
++#define	CRYPT_MD5_INPUT_31_0		CRYPT_MD5_INPUT_31_0_REG
++#define	CRYPT_MD5_OUTPUT_READY		CRYPT_MD5_OUTPUT_READY_REG
++#define	CRYPT_MD5_OUTPUT_31_0		CRYPT_MD5_OUTPUT_31_0_REG
++#define	CRYPT_SHA1_INIT_31_0		CRYPT_SHA1_INIT_31_0_REG
++#define	CRYPT_SHA1_INPUT_31_0		CRYPT_SHA1_INPUT_31_0_REG
++#define	CRYPT_SHA1_OUTPUT_READY		CRYPT_SHA1_OUTPUT_READY_REG
++#define	CRYPT_SHA1_OUTPUT_31_0		CRYPT_SHA1_OUTPUT_31_0_REG
++#define	CRYPT_MD5_INT_EN		CRYPT_MD5_INT_EN_REG
++#define	CRYPT_SHA1_INT_EN		CRYPT_SHA1_INT_EN_REG
++
++#define INDEPENDENT_MD5 1
++
++typedef struct md5_digest_s
++{
++	u32 digest_0;
++	u32 digest_32;
++
++	u32 digest_64;
++	u32 digest_96;
++
++	u32 digest_128;
++	u32 digest_160;
++
++	u32 digest_192;
++	u32 digest_224;
++
++	u32 digest_256;
++	u32 digest_288;
++
++	u32 digest_320;
++	u32 digest_352;
++
++	u32 digest_384;
++	u32 digest_416;
++
++	u32 digest_448;
++	u32 digest_480;
++} md5_digest_t;
++
++typedef struct md5_data_s
++{
++	u32 data[16];
++} md5_data_t;
++
++typedef struct sha1_digest_s
++{
++	u32 digest_0;
++	u32 digest_32;
++	u32 digest_64;
++	u32 digest_96;
++	u32 digest_128;
++	u32 digest_padding;
++
++} sha1_digest_t;
++
++typedef struct sha1_data_s
++{
++	u32 data[16];
++} sha1_data_t;
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/dma.h b/arch/arm/mach-ambarella/include/plat/dma.h
+new file mode 100644
+index 00000000..0833aa6e
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/dma.h
+@@ -0,0 +1,231 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/dma.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_DMA_H__
++#define __PLAT_AMBARELLA_DMA_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
++#define NUM_DMA_CHANNELS 		4
++#elif (CHIP_REV == S2)
++#define NUM_DMA_CHANNELS 		5
++#else
++#define NUM_DMA_CHANNELS 		8
++#endif
++
++#define DMA_OFFSET			0x5000
++#define DMA_BASE			(AHB_BASE + DMA_OFFSET)
++#define DMA_REG(x)			(DMA_BASE + (x))
++
++#define FDMA_OFFSET			0x12000
++#define FDMA_BASE			(AHB_BASE + FDMA_OFFSET)
++#define FDMA_REG(x)			(FDMA_BASE + (x))
++
++/* ==========================================================================*/
++
++#define INVALID_DMA_CHAN		0xFF
++
++#if (CHIP_REV == S2L)
++#define NOR_SPI_TX_DMA_CHAN		0 /* share with SSI0 */
++#define NOR_SPI_RX_DMA_CHAN		1 /* share with SSI0 */
++#define SSI1_TX_DMA_CHAN		2
++#define SSI1_RX_DMA_CHAN		3
++#define UART_TX_DMA_CHAN		4 /* share with SSIS0 */
++#define UART_RX_DMA_CHAN		5 /* share with SSIS0 */
++#define I2S_RX_DMA_CHAN			6
++#define I2S_TX_DMA_CHAN			7
++/* non-existed dma channel */
++#define MS_AHB_SSI_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define SPDIF_AHB_SSI_DMA_CHAN		INVALID_DMA_CHAN
++#define SLIM_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define SLIM_RX_DMA_CHAN		INVALID_DMA_CHAN
++
++#elif (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define NOR_SPI_TX_DMA_CHAN		0
++#define NOR_SPI_RX_DMA_CHAN		1
++#define SSI1_TX_DMA_CHAN		2
++#define SSI1_RX_DMA_CHAN		3
++#define UART_TX_DMA_CHAN		4
++#define UART_RX_DMA_CHAN		5
++#define I2S_RX_DMA_CHAN			6
++#define I2S_TX_DMA_CHAN			7
++
++#elif (CHIP_REV == S2E)
++#define NOR_SPI_TX_DMA_CHAN		0
++#define I2S_RX_DMA_CHAN			1
++#define I2S_TX_DMA_CHAN			2
++#define I2S1_RX_DMA_CHAN		3
++#define I2S1_TX_DMA_CHAN		4
++#define UART_RX_DMA_CHAN		5
++#define UART_TX_DMA_CHAN		6
++#define NOR_SPI_RX_DMA_CHAN		7
++/* non-existed dma channel */
++#define SSI1_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define SSI1_RX_DMA_CHAN		INVALID_DMA_CHAN
++
++#else
++#define I2S_RX_DMA_CHAN			1
++#define I2S_TX_DMA_CHAN			2
++#define MS_AHB_SSI_TX_DMA_CHAN		3
++#define SPDIF_AHB_SSI_DMA_CHAN		4
++/* non-existed dma channel */
++#define NOR_SPI_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define NOR_SPI_RX_DMA_CHAN		INVALID_DMA_CHAN
++#define SSI1_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define SSI1_RX_DMA_CHAN		INVALID_DMA_CHAN
++#define UART_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define UART_RX_DMA_CHAN		INVALID_DMA_CHAN
++#define SLIM_TX_DMA_CHAN		INVALID_DMA_CHAN
++#define SLIM_RX_DMA_CHAN		INVALID_DMA_CHAN
++
++#endif
++
++/* ==========================================================================*/
++#define DMA_CHAN_CTR_REG(x)		DMA_REG((0x300 + ((x) << 4)))
++#define DMA_CHAN_SRC_REG(x)		DMA_REG((0x304 + ((x) << 4)))
++#define DMA_CHAN_DST_REG(x)		DMA_REG((0x308 + ((x) << 4)))
++#define DMA_CHAN_STA_REG(x)		DMA_REG((0x30c + ((x) << 4)))
++#define DMA_CHAN_DA_REG(x)		DMA_REG((0x380 + ((x) << 2)))
++
++/* ==========================================================================*/
++
++#define FDMA_CHAN_CTR_REG(x)		FDMA_REG((0x300 + ((x) << 4)))
++#define FDMA_CHAN_SRC_REG(x)		FDMA_REG((0x304 + ((x) << 4)))
++#define FDMA_CHAN_DST_REG(x)		FDMA_REG((0x308 + ((x) << 4)))
++#define FDMA_CHAN_STA_REG(x)		FDMA_REG((0x30c + ((x) << 4)))
++#define FDMA_CHAN_DA_REG(x)		FDMA_REG((0x380 + ((x) << 2)))
++#define FDMA_CHAN_DSM_CTR_REG(x)	FDMA_REG((0x3a0 + ((x) << 4)))
++
++#define FDMA_CHAN_SPR_CNT_REG(x)	FDMA_REG((0x200 + ((x) << 4)))
++#define FDMA_CHAN_SPR_SRC_REG(x)	FDMA_REG((0x204 + ((x) << 4)))
++#define FDMA_CHAN_SPR_DST_REG(x)	FDMA_REG((0x208 + ((x) << 4)))
++#define FDMA_CHAN_SPR_STA_REG(x)	FDMA_REG((0x20c + ((x) << 4)))
++#define FDMA_CHAN_SPR_DA_REG(x)		FDMA_REG((0x280 + ((x) << 2)))
++
++/* ==========================================================================*/
++
++#define DMA_INT_OFFSET			0x3f0
++#define DMA_PAUSE_SET_OFFSET		0x3f4
++#define DMA_PAUSE_CLR_OFFSET		0x3f8
++#define DMA_EARLY_END_OFFSET		0x3fc
++
++/* ==========================================================================*/
++
++/* DMA_CHANX_CTR_REG */
++#define DMA_CHANX_CTR_EN		0x80000000
++#define DMA_CHANX_CTR_D			0x40000000
++#define DMA_CHANX_CTR_WM		0x20000000
++#define DMA_CHANX_CTR_RM		0x10000000
++#define DMA_CHANX_CTR_NI		0x08000000
++#define DMA_CHANX_CTR_BLK_1024B		0x07000000
++#define DMA_CHANX_CTR_BLK_512B		0x06000000
++#define DMA_CHANX_CTR_BLK_256B		0x05000000
++#define DMA_CHANX_CTR_BLK_128B		0x04000000
++#define DMA_CHANX_CTR_BLK_64B		0x03000000
++#define DMA_CHANX_CTR_BLK_32B		0x02000000
++#define DMA_CHANX_CTR_BLK_16B		0x01000000
++#define DMA_CHANX_CTR_BLK_8B		0x00000000
++#define DMA_CHANX_CTR_TS_8B		0x00C00000
++#define DMA_CHANX_CTR_TS_4B		0x00800000
++#define DMA_CHANX_CTR_TS_2B		0x00400000
++#define DMA_CHANX_CTR_TS_1B		0x00000000
++
++/* DMA descriptor bit fields */
++#define DMA_DESC_EOC			0x01000000
++#define DMA_DESC_WM			0x00800000
++#define DMA_DESC_RM			0x00400000
++#define DMA_DESC_NI			0x00200000
++#define DMA_DESC_TS_8B			0x00180000
++#define DMA_DESC_TS_4B			0x00100000
++#define DMA_DESC_TS_2B			0x00080000
++#define DMA_DESC_TS_1B			0x00000000
++#define DMA_DESC_BLK_1024B		0x00070000
++#define DMA_DESC_BLK_512B		0x00060000
++#define DMA_DESC_BLK_256B		0x00050000
++#define DMA_DESC_BLK_128B		0x00040000
++#define DMA_DESC_BLK_64B		0x00030000
++#define DMA_DESC_BLK_32B		0x00020000
++#define DMA_DESC_BLK_16B		0x00010000
++#define DMA_DESC_BLK_8B			0x00000000
++#define DMA_DESC_ID			0x00000004
++#define DMA_DESC_IE			0x00000002
++#define DMA_DESC_ST			0x00000001
++
++/* DMA_CHANX_STA_REG */
++#define DMA_CHANX_STA_DM		0x80000000
++#define DMA_CHANX_STA_OE		0x40000000
++#define DMA_CHANX_STA_DA		0x20000000
++#define DMA_CHANX_STA_DD		0x10000000
++#define DMA_CHANX_STA_OD		0x08000000
++#define DMA_CHANX_STA_ME		0x04000000
++#define DMA_CHANX_STA_BE		0x02000000
++#define DMA_CHANX_STA_RWE		0x01000000
++#define DMA_CHANX_STA_AE		0x00800000
++#define DMA_CHANX_STA_DN		0x00400000
++
++/* DMA_INT_REG */
++#define DMA_INT_CHAN(x)			(0x1 << (x))
++
++#define DMA_INT_CHAN4			0x00000010
++#define DMA_INT_CHAN3			0x00000008
++#define DMA_INT_CHAN2			0x00000004
++#define DMA_INT_CHAN1			0x00000002
++#define DMA_INT_CHAN0			0x00000001
++
++/* DMA_DUAL_SPACE_MODE_REG */
++#define DMA_DSM_EN                      0x80000000
++#define DMA_DSM_MAJP_2KB                0x00000090
++#define DMA_DSM_SPJP_64B                0x00000004
++#define DMA_DSM_SPJP_128B               0x00000005
++
++#if (CHIP_REV == S3) || (CHIP_REV == S2E) || (CHIP_REV == S3L)
++#define DMA_NODC_MN_BURST_SIZE	(DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_8B)
++#define DMA_NODC_SP_BURST_SIZE	(DMA_CHANX_CTR_BLK_16B | DMA_CHANX_CTR_TS_8B)
++#define DMA_DESC_MN_BURST_SIZE	(DMA_DESC_BLK_512B | DMA_DESC_TS_8B)
++#define DMA_DESC_SP_BURST_SIZE	(DMA_DESC_BLK_16B | DMA_DESC_TS_8B)
++#define DMA_NODC_MN_BURST_SIZE8	(DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_8B)
++#define FIO_MN_BURST_SIZE	(FIO_DMACTR_BLK_512B | FIO_DMACTR_TS8B)
++#define FIO_SP_BURST_SIZE	(FIO_DMACTR_BLK_16B | FIO_DMACTR_TS8B)
++#define FIO_MN_BURST_SIZE8	(FIO_DMACTR_BLK_512B | FIO_DMACTR_TS8B)
++#else
++#define DMA_NODC_MN_BURST_SIZE	(DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_4B)
++#define DMA_NODC_SP_BURST_SIZE	(DMA_CHANX_CTR_BLK_16B | DMA_CHANX_CTR_TS_4B)
++#define DMA_DESC_MN_BURST_SIZE	(DMA_DESC_BLK_512B | DMA_DESC_TS_4B)
++#define DMA_DESC_SP_BURST_SIZE	(DMA_DESC_BLK_16B | DMA_DESC_TS_4B)
++#define DMA_NODC_MN_BURST_SIZE8	(DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_8B)
++#define FIO_MN_BURST_SIZE	(FIO_DMACTR_BLK_512B | FIO_DMACTR_TS4B)
++#define FIO_SP_BURST_SIZE	(FIO_DMACTR_BLK_16B | FIO_DMACTR_TS4B)
++#define FIO_MN_BURST_SIZE8	(FIO_DMACTR_BLK_512B | FIO_DMACTR_TS8B)
++#endif
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++extern int ambarella_dma_channel_id(void *chan);
++
++#endif /* __ASSEMBLER__ */
++
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_DMA_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/drctl.h b/arch/arm/mach-ambarella/include/plat/drctl.h
+new file mode 100644
+index 00000000..5d088e17
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/drctl.h
+@@ -0,0 +1,54 @@
++/*
++ * ambhw/drctl.h
++ *
++ * History:
++ *	2007/01/27 - [Charles Chiou] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __AMBHW__DRCTRL_H__
++#define __AMBHW__DRCTRL_H__
++
++#if (CHIP_REV == A5S) || (CHIP_REV == S2)
++#define DRAM_DRAM_OFFSET 		0x4000
++#define DRAM_DDRC_OFFSET  		DRAM_DRAM_OFFSET
++#else
++#define DRAM_DRAM_OFFSET 		0x0000
++#define DRAM_DDRC_OFFSET  		0x0800
++#endif
++
++#define DDRC_REG(x)			(DRAMC_BASE + DRAM_DDRC_OFFSET + (x))
++#define DRAM_REG(x)			(DRAMC_BASE + DRAM_DRAM_OFFSET + (x))
++
++/* ==========================================================================*/
++#define DDRC_CTL_OFFSET			(0x00)
++#define DDRC_CFG_OFFSET			(0x04)
++#define DDRC_TIMING1_OFFSET		(0x08)
++#define DDRC_TIMING2_OFFSET		(0x0C)
++#define DDRC_TIMING3_OFFSET		(0x10)
++#define DDRC_INIT_CTL_OFFSET		(0x14)
++#define DDRC_MODE_OFFSET		(0x18)
++#define DDRC_SELF_REF_OFFSET		(0x1C)
++#define DDRC_DQS_SYNC_OFFSET		(0x20)
++#define DDRC_PAD_ZCTL_OFFSET		(0x24)
++#define DDRC_ZQ_CALIB_OFFSET		(0x28)
++#define DDRC_RSVD_SPACE_OFFSET		(0x2C)
++#define DDRC_BYTE_MAP_OFFSET		(0x30)
++#define DDRC_DDR3PLUS_BNKGRP_OFFSET	(0x34)
++#define DDRC_POWER_DOWN_OFFSET		(0x38)
++#define DDRC_DLL_CALIB_OFFSET		(0x3C)
++#define DDRC_DEBUG1_OFFSET		(0x40)
++
++/* ==========================================================================*/
++#endif /* __AMBHW__DRCTRL_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/eth.h b/arch/arm/mach-ambarella/include/plat/eth.h
+new file mode 100644
+index 00000000..7764ca52
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/eth.h
+@@ -0,0 +1,440 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/eth.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_ETH_H__
++#define __PLAT_AMBARELLA_ETH_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A7L)
++#define ETH_INSTANCES	0
++#else
++#define ETH_INSTANCES	1
++#endif
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == A8)
++#define SUPPORT_GMII	1
++#else
++#define SUPPORT_GMII	0
++#endif
++
++#if (CHIP_REV == S3)
++#define ETH_ENHANCED 1
++struct ambeth_desc {
++	u32				status;
++	u32				length;
++	u32				buffer1;
++	u32				buffer2;
++	u32				des4;
++	u32				des5;
++	u32				des6;
++	u32				des7;
++} __attribute((packed));
++#else
++#define ETH_ENHANCED 0
++struct ambeth_desc {
++	u32				status;
++	u32				length;
++	u32				buffer1;
++	u32				buffer2;
++} __attribute((packed));
++#endif
++/* ==========================================================================*/
++#define ETH_OFFSET			0xE000
++#define ETH_DMA_OFFSET			0xF000
++#define ETH2_OFFSET			0x18000
++#define ETH2_DMA_OFFSET			0x19000
++
++#define ETH_BASE			(AHB_BASE + ETH_OFFSET)
++#define ETH_DMA_BASE			(AHB_BASE + ETH_DMA_OFFSET)
++#define ETH2_BASE			(AHB_BASE + ETH2_OFFSET)
++#define ETH2_DMA_BASE			(AHB_BASE + ETH2_DMA_OFFSET)
++
++#define ETH_REG(x)			(ETH_BASE + (x))
++#define ETH_DMA_REG(x)			(ETH_DMA_BASE + (x))
++#define ETH2_REG(x)			(ETH2_BASE + (x))
++#define ETH2_DMA_REG(x)			(ETH2_DMA_BASE + (x))
++
++/* ==========================================================================*/
++#define ETH_MAC_CFG_OFFSET		0x0000
++#define ETH_MAC_FRAME_FILTER_OFFSET	0x0004
++#define ETH_MAC_HASH_HI_OFFSET		0x0008
++#define ETH_MAC_HASH_LO_OFFSET		0x000c
++#define ETH_MAC_GMII_ADDR_OFFSET	0x0010
++#define ETH_MAC_GMII_DATA_OFFSET	0x0014
++#define ETH_MAC_FLOW_CTR_OFFSET		0x0018
++#define ETH_MAC_VLAN_TAG_OFFSET		0x001c
++#define ETH_MAC_VERSION_OFFSET		0x0020
++#define ETH_MAC_DEBUG_OFFSET		0x0024
++#define ETH_MAC_WKUPFMFILTER_OFFSET	0x0028
++#define ETH_MAC_PMT_OFFSET		0x002C
++#define ETH_MAC_LPI_CS_OFFSET		0x0030
++#define ETH_MAC_LPI_TIMERS_OFFSET	0x0034
++#define ETH_MAC_INTERRUPT_STATUS_OFFSET	0x0038
++#define ETH_MAC_INTERRUPT_MASK_OFFSET	0x003C
++#define ETH_MAC_MAC0_HI_OFFSET		0x0040
++#define ETH_MAC_MAC0_LO_OFFSET		0x0044
++#define ETH_MAC_MAC1_HI_OFFSET		0x0048
++#define ETH_MAC_MAC1_LO_OFFSET		0x004c
++#define ETH_MAC_MAC2_HI_OFFSET		0x0050
++#define ETH_MAC_MAC2_LO_OFFSET		0x0054
++#define ETH_MAC_AN_STATUS_OFFSET	0x00C4
++#define ETH_MAC_RGMII_CS_OFFSET		0x00D8
++#define ETH_MAC_GPIO_OFFSET		0x00E0
++
++#define ETH_DMA_BUS_MODE_OFFSET		0x1000
++#define ETH_DMA_TX_POLL_DMD_OFFSET	0x1004
++#define ETH_DMA_RX_POLL_DMD_OFFSET	0x1008
++#define ETH_DMA_RX_DESC_LIST_OFFSET	0x100c
++#define ETH_DMA_TX_DESC_LIST_OFFSET	0x1010
++#define ETH_DMA_STATUS_OFFSET		0x1014
++#define ETH_DMA_OPMODE_OFFSET		0x1018
++#define ETH_DMA_INTEN_OFFSET		0x101c
++#define ETH_DMA_MISS_FRAME_BOCNT_OFFSET	0x1020
++#define ETH_DMA_HOST_TX_DESC_OFFSET	0x1048
++#define ETH_DMA_HOST_RX_DESC_OFFSET	0x104c
++#define ETH_DMA_HOST_TX_BUF_OFFSET	0x1050
++#define ETH_DMA_HOST_RX_BUF_OFFSET	0x1054
++
++/* ETH_MAC_CFG_REG */
++#define ETH_MAC_CFG_WD			0x00800000
++#define ETH_MAC_CFG_JD			0x00400000
++#define ETH_MAC_CFG_BE			0x00200000
++#define ETH_MAC_CFG_JE			0x00100000
++#define ETH_MAC_CFG_IFG_96		0x000e0000
++#define ETH_MAC_CFG_IFG_88		0x000c0000
++#define ETH_MAC_CFG_IFG_80		0x000a0000
++#define ETH_MAC_CFG_IFG_72		0x00080000
++#define ETH_MAC_CFG_IFG_64		0x00060000
++#define ETH_MAC_CFG_IFG_56		0x00040000
++#define ETH_MAC_CFG_IFG_48		0x00020000
++#define ETH_MAC_CFG_IFG_40		0x00000000
++#define ETH_MAC_CFG_DCRS		0x00010000
++#define ETH_MAC_CFG_PS			0x00008000
++#define ETH_MAC_CFG_FES			0x00004000
++#define ETH_MAC_CFG_DO			0x00002000
++#define ETH_MAC_CFG_LM			0x00001000
++#define ETH_MAC_CFG_DM			0x00000800
++#define ETH_MAC_CFG_IPC			0x00000400
++#define ETH_MAC_CFG_DR			0x00000200
++#define ETH_MAC_CFG_LUD			0x00000100
++#define ETH_MAC_CFG_ACS			0x00000080
++#define ETH_MAC_CFG_BL_1		0x00000060
++#define ETH_MAC_CFG_BL_4		0x00000040
++#define ETH_MAC_CFG_BL_8		0x00000020
++#define ETH_MAC_CFG_BL_10		0x00000000
++#define ETH_MAC_CFG_DC			0x00000010
++#define ETH_MAC_CFG_TE			0x00000008	/* Transmitter Enable */
++#define ETH_MAC_CFG_RE			0x00000004	/* Receiver Enable  */
++
++/* ETH_MAC_FRAME_FILTER_REG */
++#define ETH_MAC_FRAME_FILTER_RA		0x80000000
++#define ETH_MAC_FRAME_FILTER_SAF	0x00000200
++#define ETH_MAC_FRAME_FILTER_SAIF	0x00000100
++#define ETH_MAC_FRAME_FILTER_PCF_PASS	0x000000c0
++#define ETH_MAC_FRAME_FILTER_PCF_FAIL	0x00000040
++#define ETH_MAC_FRAME_FILTER_PCF_ALL	0x00000000
++#define ETH_MAC_FRAME_FILTER_DBF	0x00000020
++#define ETH_MAC_FRAME_FILTER_PM		0x00000010
++#define ETH_MAC_FRAME_FILTER_DAIF	0x00000008
++#define ETH_MAC_FRAME_FILTER_HMC	0x00000004
++#define ETH_MAC_FRAME_FILTER_HUC	0x00000002
++#define ETH_MAC_FRAME_FILTER_PR		0x00000001
++
++/* ETH_MAC_GMII_ADDR_REG */
++#define ETH_MAC_GMII_ADDR_PA(x)		(((x) & 0x1f) << 11)
++#define ETH_MAC_GMII_ADDR_GR(x)		(((x) & 0x1f) << 6)
++#define ETH_MAC_GMII_ADDR_CR_250_300MHZ	0x00000014
++#define ETH_MAC_GMII_ADDR_CR_150_250MHZ	0x00000010
++#define ETH_MAC_GMII_ADDR_CR_35_60MHZ	0x0000000c
++#define ETH_MAC_GMII_ADDR_CR_20_35MHZ	0x00000008
++#define ETH_MAC_GMII_ADDR_CR_100_150MHZ	0x00000004
++#define ETH_MAC_GMII_ADDR_CR_60_100MHZ	0x00000000
++#define ETH_MAC_GMII_ADDR_GW		0x00000002
++#define ETH_MAC_GMII_ADDR_GB		0x00000001
++
++/* ETH_MAC_FLOW_CTR_REG */
++#define ETH_MAC_FLOW_CTR_PT(x)		(((x) & 0xffff) << 16)
++#define ETH_MAC_FLOW_CTR_PLT_256	0x00000030
++#define ETH_MAC_FLOW_CTR_PLT_144	0x00000020
++#define ETH_MAC_FLOW_CTR_PLT_28		0x00000010
++#define ETH_MAC_FLOW_CTR_PLT_4		0x00000000
++#define ETH_MAC_FLOW_CTR_UP		0x00000008
++#define ETH_MAC_FLOW_CTR_RFE		0x00000004
++#define ETH_MAC_FLOW_CTR_TFE		0x00000002
++#define ETH_MAC_FLOW_CTR_FCBBPA		0x00000001
++
++/* ETH_MAC_VERSION_REG */
++#define ETH_MAC_VERSION_USER(v)		(((x) & 0x0000ff00) >> 8)
++#define ETH_MAC_VERSION_SYN(v)		((x) & 0x000000ff)
++
++/* ETH_DMA_BUS_MODE_REG */
++#define ETH_DMA_BUS_MODE_FB		0x00010000
++#define ETH_DMA_BUS_MODE_PR4		0x0000c000
++#define ETH_DMA_BUS_MODE_PR3		0x00008000
++#define ETH_DMA_BUS_MODE_PR2		0x00004000
++#define ETH_DMA_BUS_MODE_PR1		0x00000000
++#define ETH_DMA_BUS_MODE_PBL_32		0x00002000
++#define ETH_DMA_BUS_MODE_PBL_16		0x00001000
++#define ETH_DMA_BUS_MODE_PBL_8		0x00000800
++#define ETH_DMA_BUS_MODE_PBL_4		0x00000400
++#define ETH_DMA_BUS_MODE_PBL_2		0x00000200
++#define ETH_DMA_BUS_MODE_PBL_1		0x00000100
++#define ETH_DMA_BUS_MODE_ATDS		0x00000080
++#define ETH_DMA_BUS_MODE_DSL(len)	((len & 0x1f) << 2)
++#define ETH_DMA_BUS_MODE_DA_RX		0x00000002
++#define ETH_DMA_BUS_MODE_DA_TX		0x00000000
++#define ETH_DMA_BUS_MODE_SWR		0x00000001
++
++/* ETH_DMA_STATUS_REG */
++#define ETH_DMA_STATUS_GPI		0x10000000
++#define ETH_DMA_STATUS_GMI		0x08000000
++#define ETH_DMA_STATUS_GLI		0x04000000
++#define ETH_DMA_STATUS_EB_MASK		0x03800000
++#define ETH_DMA_STATUS_EB_TXDMA		0x02000000
++#define ETH_DMA_STATUS_EB_RXDMA		0x00000000
++#define ETH_DMA_STATUS_EB_RXFER		0x01000000
++#define ETH_DMA_STATUS_EB_TXFER		0x00000000
++#define ETH_DMA_STATUS_EB_DESC		0x00800000
++#define ETH_DMA_STATUS_EB_DBUF		0x00000000
++#define ETH_DMA_STATUS_TS_MASK		0x00700000
++#define ETH_DMA_STATUS_TS_CTD		0x00700000
++#define ETH_DMA_STATUS_TS_SUSP		0x00600000
++#define ETH_DMA_STATUS_TS_READ		0x00300000
++#define ETH_DMA_STATUS_TS_WAIT		0x00200000
++#define ETH_DMA_STATUS_TS_FETCH		0x00100000
++#define ETH_DMA_STATUS_TS_STOP		0x00000000
++#define ETH_DMA_STATUS_RS_MASK		0x000e0000
++#define ETH_DMA_STATUS_RS_RCV		0x000e0000
++#define ETH_DMA_STATUS_RS_CRD		0x000a0000
++#define ETH_DMA_STATUS_RS_SUSP		0x00080000
++#define ETH_DMA_STATUS_RS_WAIT		0x00060000
++#define ETH_DMA_STATUS_RS_FETCH		0x00020000
++#define ETH_DMA_STATUS_RS_STOP		0x00000000
++#define ETH_DMA_STATUS_NIS		0x00010000
++#define ETH_DMA_STATUS_AIS		0x00008000
++#define ETH_DMA_STATUS_ERI		0x00004000
++#define ETH_DMA_STATUS_FBI		0x00002000
++#define ETH_DMA_STATUS_ETI		0x00000400
++#define ETH_DMA_STATUS_RWT		0x00000200
++#define ETH_DMA_STATUS_RPS		0x00000100
++#define ETH_DMA_STATUS_RU		0x00000080
++#define ETH_DMA_STATUS_RI		0x00000040
++#define ETH_DMA_STATUS_UNF		0x00000020
++#define ETH_DMA_STATUS_OVF		0x00000010
++#define ETH_DMA_STATUS_TJT		0x00000008
++#define ETH_DMA_STATUS_TU		0x00000004
++#define ETH_DMA_STATUS_TPS		0x00000002
++#define ETH_DMA_STATUS_TI		0x00000001
++
++/* ETH_DMA_OPMODE_REG */
++#define ETH_DMA_OPMODE_DT		0x04000000
++#define ETH_DMA_OPMODE_RSF		0x02000000
++#define ETH_DMA_OPMODE_DFF		0x01000000
++#define ETH_DMA_OPMODE_TSF		0x00200000
++#define ETH_DMA_OPMODE_FTF		0x00100000
++#define ETH_DMA_OPMODE_TTC_16		0x0001c000
++#define ETH_DMA_OPMODE_TTC_24		0x00018000
++#define ETH_DMA_OPMODE_TTC_32		0x00014000
++#define ETH_DMA_OPMODE_TTC_40		0x00010000
++#define ETH_DMA_OPMODE_TTC_256		0x0000c000
++#define ETH_DMA_OPMODE_TTC_192		0x00008000
++#define ETH_DMA_OPMODE_TTC_128		0x00004000
++#define ETH_DMA_OPMODE_TTC_64		0x00000000
++#define ETH_DMA_OPMODE_ST		0x00002000
++#define ETH_DMA_OPMODE_RFD_4K		0x00001800
++#define ETH_DMA_OPMODE_RFD_3K		0x00001000
++#define ETH_DMA_OPMODE_RFD_2K		0x00000800
++#define ETH_DMA_OPMODE_RFD_1K		0x00000000
++#define ETH_DMA_OPMODE_RFA_4K		0x00000600
++#define ETH_DMA_OPMODE_RFA_3K		0x00000400
++#define ETH_DMA_OPMODE_RFA_2K		0x00000200
++#define ETH_DMA_OPMODE_RFA_1K		0x00000000
++#define ETH_DMA_OPMODE_EFC		0x00000100
++#define ETH_DMA_OPMODE_FEF		0x00000080
++#define ETH_DMA_OPMODE_FUF		0x00000040
++#define ETH_DMA_OPMODE_RTC_128		0x00000018
++#define ETH_DMA_OPMODE_RTC_96		0x00000010
++#define ETH_DMA_OPMODE_RTC_32		0x00000008
++#define ETH_DMA_OPMODE_RTC_64		0x00000000
++#define ETH_DMA_OPMODE_OSF		0x00000004
++#define ETH_DMA_OPMODE_SR		0x00000002
++
++/* ETH_DMA_INTEN_REG */
++#define ETH_DMA_INTEN_NIE		0x00010000
++#define ETH_DMA_INTEN_AIE		0x00008000
++#define ETH_DMA_INTEN_ERE		0x00004000
++#define ETH_DMA_INTEN_FBE		0x00002000
++#define ETH_DMA_INTEN_ETE		0x00000400
++#define ETH_DMA_INTEN_RWE		0x00000200
++#define ETH_DMA_INTEN_RSE		0x00000100
++#define ETH_DMA_INTEN_RUE		0x00000080
++#define ETH_DMA_INTEN_RIE		0x00000040
++#define ETH_DMA_INTEN_UNE		0x00000020
++#define ETH_DMA_INTEN_OVE		0x00000010
++#define ETH_DMA_INTEN_TJE		0x00000008
++#define ETH_DMA_INTEN_TUE		0x00000004
++#define ETH_DMA_INTEN_TSE		0x00000002
++#define ETH_DMA_INTEN_TIE		0x00000001
++
++/* ETH_DMA_MISS_FRAME_BOCNT_REG */
++#define ETH_DMA_MISS_FRAME_BOCNT_FIFO		0x10000000
++#define ETH_DMA_MISS_FRAME_BOCNT_APP(v)		(((v) & 0x0ffe0000) >> 17)
++#define ETH_DMA_MISS_FRAME_BOCNT_FRAME		0x00001000
++#define ETH_DMA_MISS_FRAME_BOCNT_HOST(v)	((v) & 0x0000ffff)
++
++/* Receive Descriptor 0 (RDES0) */
++#define ETH_RDES0_OWN			0x80000000
++#define ETH_RDES0_AFM			0x40000000
++#define ETH_RDES0_FL(v)			(((v) & 0x3fff0000) >> 16)
++#define ETH_RDES0_ES			0x00008000
++#define ETH_RDES0_DE			0x00004000
++#define ETH_RDES0_SAF			0x00002000
++#define ETH_RDES0_LE			0x00001000
++#define ETH_RDES0_OE			0x00000800
++#define ETH_RDES0_VLAN			0x00000400
++#define ETH_RDES0_FS			0x00000200
++#define ETH_RDES0_LS			0x00000100
++#define ETH_RDES0_IPC			0x00000080
++#define ETH_RDES0_LC			0x00000040
++#define ETH_RDES0_FT			0x00000020
++#define ETH_RDES0_RWT			0x00000010
++#define ETH_RDES0_RE			0x00000008
++#define ETH_RDES0_DBE			0x00000004
++#define ETH_RDES0_CE			0x00000002
++#define ETH_RDES0_RX			0x00000001
++
++#define ETH_RDES0_COE_MASK		0x000000a1
++#define ETH_RDES0_COE_LENLT600		0x00000000	/* Bit(5:7:0)=>0 IEEE 802.3 type frame Length field is Lessthan 0x0600			*/
++#define ETH_RDES0_COE_UNSUPPORTED	0x00000001	/* Bit(5:7:0)=>1 Payload & Ip header checksum bypassed (unsuppported payload) 		*/
++#define ETH_RDES0_COE_RESERVED		0x00000080	/* Bit(5:7:0)=>2 Reserved						 		*/
++#define ETH_RDES0_COE_CHKBYPASS		0x00000081	/* Bit(5:7:0)=>3 Neither IPv4 nor IPV6. So checksum bypassed 		 		*/
++#define ETH_RDES0_COE_NOCHKERROR	0x00000020	/* Bit(5:7:0)=>4 No IPv4/IPv6 Checksum error detected					*/
++#define ETH_RDES0_COE_PLCHKERROR	0x00000021	/* Bit(5:7:0)=>5 Payload checksum error detected for Ipv4/Ipv6 frames			*/
++#define ETH_RDES0_COE_HDRCHKERROR	0x000000a0	/* Bit(5:7:0)=>6 Ip header checksum error detected for Ipv4 frames			*/
++#define ETH_RDES0_COE_HDRPLCHKERROR	0x000000a1	/* Bit(5:7:0)=>7 Payload & Ip header checksum error detected for Ipv4/Ipv6 frames	*/
++
++/* Receive Descriptor 1 (RDES1) */
++#define ETH_RDES1_DIC			0x80000000
++#if (CHIP_REV == S3)
++#define ETH_RDES1_RER			0x00008000
++#define ETH_RDES1_RCH			0x00004000
++#define ETH_RDES1_RBS2(v)		(((v) & 0x1FFF0000) >> 16)
++#define ETH_RDES1_RBS1(v)		((v) & 0x00001FFF)
++#define ETH_RDES1_RBS2x(x)		(((x) << 16) & 0x1FFF0000)
++#define ETH_RDES1_RBS1x(x)		((x) & 0x00001FFF)
++#else
++#define ETH_RDES1_RER			0x02000000
++#define ETH_RDES1_RCH			0x01000000
++#define ETH_RDES1_RBS2(v)		(((v) & 0x003ff800) >> 11)	/* Receive Buffer 2 Size */
++#define ETH_RDES1_RBS1(v)		((v) & 0x000007ff)		/* Receive Buffer 1 Size */
++#define ETH_RDES1_RBS2x(x)		(((x) << 11) & 0x003ff800)	/* Receive Buffer 2 Size */
++#define ETH_RDES1_RBS1x(x)		((x) & 0x000007ff)		/* Receive Buffer 1 Size */
++#endif
++
++/* Transmit Descriptor 0 (TDES0) */
++#define ETH_TDES0_OWN			0x80000000
++#define ETH_TDES0_TTSS			0x00020000
++#define ETH_TDES0_IHE			0x00010000
++#define ETH_TDES0_ES			0x00008000
++#define ETH_TDES0_JT			0x00004000
++#define ETH_TDES0_FF			0x00002000
++#define ETH_TDES0_PCE			0x00001000
++#define ETH_TDES0_LCA			0x00000800
++#define ETH_TDES0_NC			0x00000400
++#define ETH_TDES0_LCO			0x00000200
++#define ETH_TDES0_EC			0x00000100
++#define ETH_TDES0_VF			0x00000080
++#define ETH_TDES0_CC(v)			(((v) & 0x00000078) >> 3)
++#define ETH_TDES0_ED			0x00000004
++#define ETH_TDES0_UF			0x00000002
++#define ETH_TDES0_DB			0x00000001
++#define ETH_TDES0_ES_MASK		(ETH_TDES0_UF | ETH_TDES0_ED | \
++					ETH_TDES0_EC | ETH_TDES0_LCO | \
++					ETH_TDES0_NC | ETH_TDES0_LCA | \
++					ETH_TDES0_FF | ETH_TDES0_JT | \
++					ETH_TDES0_ES)
++
++/* Transmit Descriptor 1 (TDES1) */
++#define ETH_TDES1_IC			0x80000000
++#define ETH_TDES1_LS			0x40000000
++#define ETH_TDES1_FS			0x20000000
++#define ETH_TDES1_CIC_TUI		0x10000000
++#define ETH_TDES1_CIC_HDR		0x08000000
++#define ETH_TDES1_DC			0x04000000
++#define ETH_TDES1_TER			0x02000000
++#define ETH_TDES1_TCH			0x01000000
++#define ETH_TDES1_DP			0x00800000
++#if (CHIP_REV == S3)
++#define ETH_TDES1_TBS2(v)		(((v) & 0x1FFF0000) >> 16)
++#define ETH_TDES1_TBS1(v)		((v) & 0x00001FFF)
++#define ETH_TDES1_TBS2x(x)		(((x) << 16) & 0x1FFF0000)
++#define ETH_TDES1_TBS1x(x)		((x) & 0x00001FFF)
++#else
++#define ETH_TDES1_TBS2(v)		(((v) & 0x003ff800) >> 11)
++#define ETH_TDES1_TBS1(v)		((v) & 0x000007ff)
++#define ETH_TDES1_TBS2x(x)		(((x) << 11) & 0x003ff800)
++#define ETH_TDES1_TBS1x(x)		((x) & 0x000007ff)
++#endif
++/* ==========================================================================*/
++#define ETH_ENHANCED_TDES0_IC		0x40000000
++#define ETH_ENHANCED_TDES0_LS		0x20000000
++#define ETH_ENHANCED_TDES0_FS		0x10000000
++#define ETH_ENHANCED_TDES0_DC		0x08000000
++#define ETH_ENHANCED_TDES0_DP		0x04000000
++#define ETH_ENHANCED_TDES0_CRCR		0x01000000
++#define ETH_ENHANCED_TDES0_CIC_V2	0x00C00000
++#define ETH_ENHANCED_TDES0_CIC_V1	0x00800000
++#define ETH_ENHANCED_TDES0_CIC_HDR	0x00400000
++#define ETH_ENHANCED_TDES0_TER		0x00200000
++#define ETH_ENHANCED_TDES0_TCH		0x00100000
++
++#define ETH_ENHANCED_TDES1_SAIC_MAC1	0x80000000
++#define ETH_ENHANCED_TDES1_SAIC_REPLACE	0x40000000
++#define ETH_ENHANCED_TDES1_SAIC_INCLUDE	0x20000000
++
++/*Different Bit of Descriptor*/
++#define ETH_TDES_IC	0x1
++#define ETH_TDES_LS	0x2
++#define ETH_TDES_FS	0x4
++#define ETH_TDES_DC	0x8
++#define ETH_TDES_TCH	0x10
++#define ETH_TDES_CIC	0x20
++/* ==========================================================================*/
++#define AMBARELLA_ETH_FC_AUTONEG	(1 << 0)
++#define AMBARELLA_ETH_FC_RX		(1 << 1)
++#define AMBARELLA_ETH_FC_TX		(1 << 2)
++
++#if (CHIP_REV == A8)
++#define SYS_CONFIG_ETH_ENABLE		0xffffffff
++#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define SYS_CONFIG_ETH_ENABLE		0x00800000
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define SYS_CONFIG_ETH_ENABLE		0x00000001
++#else
++#define SYS_CONFIG_ETH_ENABLE		0x00000080
++#endif
++
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/event.h b/arch/arm/mach-ambarella/include/plat/event.h
+new file mode 100644
+index 00000000..582fb1db
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/event.h
+@@ -0,0 +1,75 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/event.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_EVENT_H
++#define __PLAT_AMBARELLA_EVENT_H
++
++/* ==========================================================================*/
++#define AMBA_EVENT_PRE			(0x80000000)
++#define AMBA_EVENT_POST			(0x40000000)
++#define AMBA_EVENT_CHECK		(0x20000000)
++
++#define AMBA_EVENT_ID_CPUFREQ		(1)
++#define AMBA_EVENT_ID_PM		(2)
++#define AMBA_EVENT_ID_TOSS		(3)
++#define AMBA_EVENT_ID_GIVEUP_DSP	(4)
++#define AMBA_EVENT_ID_TAKEOVER_DSP	(5)
++#define AMBA_EVENT_ID_VIN_LOSS		(6)
++
++#define AMBA_EVENT_PRE_CPUFREQ		(AMBA_EVENT_ID_CPUFREQ | AMBA_EVENT_PRE)
++#define AMBA_EVENT_POST_CPUFREQ		(AMBA_EVENT_ID_CPUFREQ | AMBA_EVENT_POST)
++#define AMBA_EVENT_CHECK_CPUFREQ	(AMBA_EVENT_ID_CPUFREQ | AMBA_EVENT_CHECK)
++#define AMBA_EVENT_PRE_PM		(AMBA_EVENT_ID_PM | AMBA_EVENT_PRE)
++#define AMBA_EVENT_POST_PM		(AMBA_EVENT_ID_PM | AMBA_EVENT_POST)
++#define AMBA_EVENT_CHECK_PM		(AMBA_EVENT_ID_PM | AMBA_EVENT_CHECK)
++#define AMBA_EVENT_PRE_TOSS		(AMBA_EVENT_ID_TOSS | AMBA_EVENT_PRE)
++#define AMBA_EVENT_POST_TOSS		(AMBA_EVENT_ID_TOSS | AMBA_EVENT_POST)
++#define AMBA_EVENT_CHECK_TOSS		(AMBA_EVENT_ID_TOSS | AMBA_EVENT_CHECK)
++
++#define AMBA_EVENT_PRE_GIVEUP_DSP	(AMBA_EVENT_ID_GIVEUP_DSP | AMBA_EVENT_PRE)
++#define AMBA_EVENT_POST_GIVEUP_DSP	(AMBA_EVENT_ID_GIVEUP_DSP | AMBA_EVENT_POST)
++#define AMBA_EVENT_GIVEUP_DSP		(AMBA_EVENT_ID_GIVEUP_DSP | AMBA_EVENT_CHECK)
++#define AMBA_EVENT_PRE_TAKEOVER_DSP	(AMBA_EVENT_ID_TAKEOVER_DSP | AMBA_EVENT_PRE)
++#define AMBA_EVENT_POST_TAKEOVER_DSP	(AMBA_EVENT_ID_TAKEOVER_DSP | AMBA_EVENT_POST)
++#define AMBA_EVENT_TAKEOVER_DSP		(AMBA_EVENT_ID_TAKEOVER_DSP | AMBA_EVENT_CHECK)
++
++#define AMBA_EVENT_POST_VIN_LOSS	(AMBA_EVENT_ID_VIN_LOSS | AMBA_EVENT_POST)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++
++/* ==========================================================================*/
++extern int ambarella_register_event_notifier(void *nb);
++extern int ambarella_unregister_event_notifier(void *nb);
++extern int ambarella_set_event(unsigned long val, void *v);
++extern int ambarella_register_raw_event_notifier(void *nb);
++extern int ambarella_unregister_raw_event_notifier(void *nb);
++extern int ambarella_set_raw_event(unsigned long val, void *v);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/fb.h b/arch/arm/mach-ambarella/include/plat/fb.h
+new file mode 100644
+index 00000000..f0f4e9ff
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/fb.h
+@@ -0,0 +1,151 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/fb.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_FB_H
++#define __PLAT_AMBARELLA_FB_H
++
++#define AMBARELLA_FB_MAX_NUM			2
++
++/* ==========================================================================*/
++#define AMBARELLA_CLUT_TABLE_SIZE		(256 * 3)
++#define AMBARELLA_BLEND_TABLE_SIZE		(256)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++enum ambarella_fb_color_format {
++	AMBFB_COLOR_AUTO = 0,
++
++	AMBFB_COLOR_CLUT_8BPP,
++	AMBFB_COLOR_RGB565,
++
++	AMBFB_COLOR_BGR565,
++	AMBFB_COLOR_AGBR4444,	//AYUV 4:4:4:4
++	AMBFB_COLOR_RGBA4444,
++	AMBFB_COLOR_BGRA4444,
++	AMBFB_COLOR_ABGR4444,
++	AMBFB_COLOR_ARGB4444,
++	AMBFB_COLOR_AGBR1555,	//AYUV 1:5:5:5
++	AMBFB_COLOR_GBR1555,	//YUV 1(ignored):5:5:5
++	AMBFB_COLOR_RGBA5551,
++	AMBFB_COLOR_BGRA5551,
++	AMBFB_COLOR_ABGR1555,
++	AMBFB_COLOR_ARGB1555,
++	AMBFB_COLOR_AGBR8888,	//AYUV 8:8:8:8
++	AMBFB_COLOR_AYUV8888,
++	AMBFB_COLOR_RGBA8888,
++	AMBFB_COLOR_BGRA8888,
++	AMBFB_COLOR_ABGR8888,
++	AMBFB_COLOR_ARGB8888,
++
++	AMBFB_COLOR_VYU565,
++	AMBFB_COLOR_AYUV4444,
++	AMBFB_COLOR_AYUV1555,
++	AMBFB_COLOR_YUV555,
++
++	AMBFB_COLOR_UNSUPPORTED,  //Reserved only, not supported
++};
++
++enum ambarella_dsp_status {
++	AMBA_DSP_ENCODE_MODE	= 0x00,
++	AMBA_DSP_DECODE_MODE	= 0x01,
++	AMBA_DSP_RESET_MODE	= 0x02,
++	AMBA_DSP_UNKNOWN_MODE	= 0x03,
++	AMBA_DSP_QUICKLOGO_MODE	= 0x04,
++};
++
++enum ambarella_fb_status {
++	AMBFB_UNKNOWN_MODE	= 0x00,
++	AMBFB_ACTIVE_MODE,
++	AMBFB_STOP_MODE,
++};
++
++typedef int (*ambarella_fb_pan_display_fn)(struct fb_var_screeninfo *var,
++	struct fb_info *info);
++typedef int (*ambarella_fb_setcmap_fn)(struct fb_cmap *cmap,
++	struct fb_info *info);
++typedef int (*ambarella_fb_check_var_fn)(struct fb_var_screeninfo *var,
++	struct fb_info *info);
++typedef int (*ambarella_fb_set_par_fn)(struct fb_info *info);
++typedef int (*ambarella_fb_blank_fn)(int blank_mode, struct fb_info *info);
++
++struct ambarella_fb_cvs_buf {		//Conversion Buffer
++	int				available;
++	u32				base_buf_phy;
++	u8				*ping_buf;
++	u32				ping_buf_phy;
++	u32				ping_buf_size;
++	u8				*pong_buf;
++	u32				pong_buf_size;
++	u32				pong_buf_phy;
++};
++
++struct ambarella_fb_iav_info {
++	struct fb_var_screeninfo	screen_var;
++	struct fb_fix_screeninfo	screen_fix;
++	enum ambarella_dsp_status	dsp_status;
++
++	ambarella_fb_pan_display_fn	pan_display;
++	ambarella_fb_setcmap_fn		setcmap;
++	ambarella_fb_check_var_fn	check_var;
++	ambarella_fb_set_par_fn		set_par;
++	ambarella_fb_blank_fn		set_blank;
++};
++
++struct ambarella_platform_fb {
++	struct mutex			lock;
++	struct fb_var_screeninfo	screen_var;
++	struct fb_fix_screeninfo	screen_fix;
++	enum ambarella_dsp_status	dsp_status;
++	enum ambarella_fb_status	fb_status;
++	u8				clut_table[AMBARELLA_CLUT_TABLE_SIZE];
++	u8				blend_table[AMBARELLA_BLEND_TABLE_SIZE];
++	enum ambarella_fb_color_format	color_format;
++	struct ambarella_fb_cvs_buf	conversion_buf;
++	u32				use_prealloc;
++	u32				prealloc_line_length;
++
++	ambarella_fb_pan_display_fn	pan_display;
++	ambarella_fb_setcmap_fn		setcmap;
++	ambarella_fb_check_var_fn	check_var;
++	ambarella_fb_set_par_fn		set_par;
++	ambarella_fb_blank_fn		set_blank;
++
++	struct fb_info			*proc_fb_info;
++	struct proc_dir_entry		*proc_file;
++	wait_queue_head_t		proc_wait;
++	u32				proc_wait_flag;
++};
++
++/* ==========================================================================*/
++
++extern struct ambarella_platform_fb *ambfb_data_ptr[];
++
++/* ==========================================================================*/
++extern int ambarella_fb_get_platform_info(u32, struct ambarella_platform_fb *);
++extern int ambarella_fb_set_iav_info(u32, struct ambarella_fb_iav_info *);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/fio.h b/arch/arm/mach-ambarella/include/plat/fio.h
+new file mode 100644
+index 00000000..ee31d429
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/fio.h
+@@ -0,0 +1,188 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/fio.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_COMMON_FIO_H__
++#define __PLAT_AMBARELLA_COMMON_FIO_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define	FIO_USE_2X_FREQ			1
++#else
++#define	FIO_USE_2X_FREQ			0
++#endif
++
++#if (CHIP_REV == A5S)
++#define	NAND_READ_ID5			0
++#else
++#define	NAND_READ_ID5			1
++#endif
++
++#if (CHIP_REV == A5S) || (CHIP_REV == S2)
++#define	FIO_INDEPENDENT_SD		0
++#else
++#define	FIO_INDEPENDENT_SD		1
++#endif
++
++/* For BCH mode */
++#if (CHIP_REV == S3L)
++#define FIO_SUPPORT_SKIP_BLANK_ECC	1
++#else
++#define FIO_SUPPORT_SKIP_BLANK_ECC	0
++#endif
++
++/* ==========================================================================*/
++#define FIO_FIFO_OFFSET			0x0000
++#define FIO_OFFSET			0x1000
++#if (CHIP_REV == S2E)
++#define FIO_4K_OFFSET			0x1e000
++#else
++#define FIO_4K_OFFSET			0x30000
++#endif
++
++#define FIO_4K_PHYS_BASE		(AHB_PHYS_BASE + FIO_4K_OFFSET)
++
++#define FIO_FIFO_BASE			(AHB_BASE + FIO_FIFO_OFFSET)
++#define FIO_BASE			(AHB_BASE + FIO_OFFSET)
++#define FIO_4K_BASE			(AHB_BASE + FIO_4K_OFFSET)
++#define FIO_REG(x)			(FIO_BASE + (x))
++#define FIO_4K_REG(x)			(FIO_4K_BASE + (x))
++
++/* ==========================================================================*/
++#define FIO_CTR_OFFSET			0x000
++#define FIO_STA_OFFSET			0x004
++#define FIO_DMACTR_OFFSET		0x080
++#define FIO_DMAADR_OFFSET		0x084
++#define FIO_DMASTA_OFFSET		0x08c
++#define FIO_DSM_CTR_OFFSET              0x0a0
++#define FIO_ECC_RPT_STA_OFFSET          0x0a4
++
++#define FIO_CTR_REG			FIO_REG(0x000)
++#define FIO_STA_REG			FIO_REG(0x004)
++#define FIO_DMACTR_REG			FIO_REG(0x080)
++#define FIO_DMAADR_REG			FIO_REG(0x084)
++#define FIO_DMASTA_REG			FIO_REG(0x08c)
++#define FIO_DSM_CTR_REG			FIO_REG(0x0a0)
++#define FIO_ECC_RPT_STA_REG		FIO_REG(0x0a4)
++
++/* FIO_CTR_REG */
++#define FIO_CTR_DA			0x00020000
++#define FIO_CTR_DR			0x00010000
++#define FIO_CTR_SX			0x00000100
++#if (FIO_SUPPORT_SKIP_BLANK_ECC == 1)
++#define FIO_CTR_SKIP_BLANK		0x00000080
++#else
++#define FIO_CTR_SKIP_BLANK		0x00000000
++#endif
++#define FIO_CTR_ECC_8BIT		0x00000060
++#define FIO_CTR_ECC_6BIT		0x00000040
++#define FIO_CTR_RS			0x00000010
++#define FIO_CTR_SE			0x00000008
++#define FIO_CTR_CO			0x00000004
++#define FIO_CTR_RR			0x00000002
++#define FIO_CTR_XD			0x00000001
++
++/* FIO_STA_REG */
++#define FIO_STA_SI			0x00000008
++#define FIO_STA_CI			0x00000004
++#define FIO_STA_XI			0x00000002
++#define FIO_STA_FI			0x00000001
++
++/* FIO_DMACTR_REG */
++#define FIO_DMACTR_EN			0x80000000
++#define FIO_DMACTR_RM			0x40000000
++#define FIO_DMACTR_SD			0x30000000
++#define FIO_DMACTR_CF			0x20000000
++#define FIO_DMACTR_XD			0x10000000
++#define FIO_DMACTR_FL			0x00000000
++#define FIO_DMACTR_BLK_32768B		0x0c000000
++#define FIO_DMACTR_BLK_16384B		0x0b000000
++#define FIO_DMACTR_BLK_8192B		0x0a000000
++#define FIO_DMACTR_BLK_4096B		0x09000000
++#define FIO_DMACTR_BLK_2048B		0x08000000
++#define FIO_DMACTR_BLK_1024B		0x07000000
++#define FIO_DMACTR_BLK_256B		0x05000000
++#define FIO_DMACTR_BLK_512B		0x06000000
++#define FIO_DMACTR_BLK_128B		0x04000000
++#define FIO_DMACTR_BLK_64B		0x03000000
++#define FIO_DMACTR_BLK_32B		0x02000000
++#define FIO_DMACTR_BLK_16B		0x01000000
++#define FIO_DMACTR_BLK_8B		0x00000000
++#define FIO_DMACTR_TS8B			0x00c00000
++#define FIO_DMACTR_TS4B			0x00800000
++#define FIO_DMACTR_TS2B			0x00400000
++#define FIO_DMACTR_TS1B			0x00000000
++
++/* FIO_DMASTA_REG */
++#define FIO_DMASTA_RE			0x04000000
++#define FIO_DMASTA_AE			0x02000000
++#define FIO_DMASTA_DN			0x01000000
++
++/* FIO_DSM_CTR_REG */
++#define FIO_DSM_EN			0x80000000
++#define FIO_DSM_MAJP_2KB		0x00000090
++#define FIO_DSM_SPJP_64B		0x00000004
++#define FIO_DSM_SPJP_128B		0x00000005
++
++/* FIO_ECC_RPT_REG */
++#define FIO_ECC_RPT_ERR			0x80000000
++#define FIO_ECC_RPT_FAIL		0x40000000
++
++/* ==========================================================================*/
++#define SELECT_FIO_FREE		(0x00000000)
++#define SELECT_FIO_FL		(0x00000001)
++#define SELECT_FIO_XD		(0x00000002)
++#define SELECT_FIO_CF		(0x00000004)
++#define SELECT_FIO_SD		(0x00000008)
++#define SELECT_FIO_SDIO		(0x00000010)
++
++#define FIO_OP_NOT_DONE_ER	(-1)	/* operation(xfer) not done error */
++#define FIO_READ_ER		(-2)	/* uncorrected ECC error */
++#define	FIO_ADDR_ER		(-3)	/* address unaligned error */
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++
++#if (FIO_INDEPENDENT_SD == 1)
++static inline void fio_select_lock(int module) { }
++static inline void fio_unlock(int module) { }
++static inline void fio_amb_sd0_set_int(u32 mask, u32 on){ }
++static inline void fio_amb_sdio0_set_int(u32 mask, u32 on){ }
++#else
++extern void fio_select_lock(int module);
++extern void fio_unlock(int module);
++extern void fio_amb_sd0_set_int(u32 mask, u32 on);
++extern void fio_amb_sdio0_set_int(u32 mask, u32 on);
++#endif
++
++extern int ambarella_init_fio(void);
++extern void ambarella_fio_rct_reset(void);
++
++extern void *ambarella_fio_push(void *func, u32 size);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_COMMON_FIO_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/gdma.h b/arch/arm/mach-ambarella/include/plat/gdma.h
+new file mode 100644
+index 00000000..21129d47
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/gdma.h
+@@ -0,0 +1,100 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/gdma.h
++ *
++ * History:
++ *	2013/11/26 - Ken He <jianhe@ambarella.com> created file
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_GDMA_H__
++#define __PLAT_AMBARELLA_GDMA_H__
++
++/****************************************************/
++/* Capabilities based on chip revision              */
++/****************************************************/
++
++#define GDMA_OFFSET			0x15000
++#define GDMA_BASE			(AHB_BASE + GDMA_OFFSET)
++#define GDMA_REG(x)			(GDMA_BASE + (x))
++
++#if (CHIP_REV == A5S)
++#define GDMA_SUPPORT_ALPHA_BLEND	0
++#else
++#define GDMA_SUPPORT_ALPHA_BLEND	1
++#endif
++
++struct gdma_param {
++	u32 dest_addr;
++	u32 dest_virt_addr;
++	u32 src_addr;
++	u32 src_virt_addr;
++	u8 dest_non_cached;
++	u8 src_non_cached;
++	u8 reserved[2];
++	u16 src_pitch;
++	u16 dest_pitch;
++	u16 width;
++	u16 height;
++};
++
++/****************************************************/
++/* Controller registers definitions                 */
++/****************************************************/
++#define GDMA_SRC_1_BASE_OFFSET		0x00
++#define GDMA_SRC_1_PITCH_OFFSET		0x04
++#define GDMA_SRC_2_BASE_OFFSET		0x08
++#define GDMA_SRC_2_PITCH_OFFSET		0x0c
++#define GDMA_DST_BASE_OFFSET		0x10
++#define GDMA_DST_PITCH_OFFSET		0x14
++#define GDMA_WIDTH_OFFSET		0x18
++#define GDMA_HIGHT_OFFSET		0x1c
++#define GDMA_TRANSPARENT_OFFSET		0x20
++#define GDMA_OPCODE_OFFSET		0x24
++#define GDMA_PENDING_OPS_OFFSET		0x28
++
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++#define GDMA_PIXELFORMAT_OFFSET		0x2c
++#define GDMA_ALPHA_OFFSET		0x30
++#define GDMA_CLUT_BASE_OFFSET		0x400
++#endif
++
++#define GDMA_SRC_1_BASE_REG		GDMA_REG(GDMA_SRC_1_BASE_OFFSET)
++#define GDMA_SRC_1_PITCH_REG		GDMA_REG(GDMA_SRC_1_PITCH_OFFSET)
++#define GDMA_SRC_2_BASE_REG		GDMA_REG(GDMA_SRC_2_BASE_OFFSET)
++#define GDMA_SRC_2_PITCH_REG		GDMA_REG(GDMA_SRC_2_PITCH_OFFSET)
++#define GDMA_DST_BASE_REG		GDMA_REG(GDMA_DST_BASE_OFFSET)
++#define GDMA_DST_PITCH_REG		GDMA_REG(GDMA_DST_PITCH_OFFSET)
++#define GDMA_WIDTH_REG			GDMA_REG(GDMA_WIDTH_OFFSET)
++#define GDMA_HEIGHT_REG			GDMA_REG(GDMA_HIGHT_OFFSET)
++#define GDMA_TRANSPARENT_REG		GDMA_REG(GDMA_TRANSPARENT_OFFSET)
++#define GDMA_OPCODE_REG			GDMA_REG(GDMA_OPCODE_OFFSET)
++#define GDMA_PENDING_OPS_REG		GDMA_REG(GDMA_PENDING_OPS_OFFSET)
++
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++#define GDMA_PIXELFORMAT_REG		GDMA_REG(GDMA_PIXELFORMAT_OFFSET)
++#define GDMA_ALPHA_REG			GDMA_REG(GDMA_ALPHA_OFFSET)
++#define GDMA_CLUT_BASE_REG		GDMA_REG(GDMA_CLUT_BASE_OFFSET)
++
++/* GDMA_PIXELFORMAT_REG */
++#define GDMA_PIXELFORMAT_THROTTLE_DRAM	(1L << 11)
++
++#endif /* (GDMA_SUPPORT_ALPHA_BLEND == 1)*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/gpio.h b/arch/arm/mach-ambarella/include/plat/gpio.h
+new file mode 100644
+index 00000000..ee2b64e8
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/gpio.h
+@@ -0,0 +1,201 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/gpio.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_GPIO_H__
++#define __PLAT_AMBARELLA_GPIO_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A7L)
++#define GPIO_INSTANCES			4
++#define GPIO_MAX_LINES			128
++#elif (CHIP_REV == A5S)
++#define GPIO_INSTANCES			3
++#define GPIO_MAX_LINES			96
++#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define GPIO_INSTANCES			5
++#define GPIO_MAX_LINES			138
++#elif (CHIP_REV == A8)
++#define GPIO_INSTANCES			1
++#define GPIO_MAX_LINES			16
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3L)
++#define GPIO_INSTANCES			4
++#define GPIO_MAX_LINES			114
++#elif (CHIP_REV == S3)
++#define GPIO_INSTANCES			7
++#define GPIO_MAX_LINES			201
++#else
++#error "Not supported!"
++#endif
++
++/* ==========================================================================*/
++#define GPIO0_OFFSET			0x9000
++#define GPIO1_OFFSET			0xA000
++#define GPIO2_OFFSET			0xE000
++#if (CHIP_REV == A5S)
++#define GPIO3_OFFSET			0x1F000
++#elif (CHIP_REV == A7L)
++#define GPIO3_OFFSET			0x1E000
++#else
++#define GPIO3_OFFSET			0x10000
++#endif
++#define GPIO4_OFFSET			0x11000
++#if (CHIP_REV == S3)
++#define GPIO5_OFFSET			0xD000
++#else
++#define GPIO5_OFFSET			0x12000
++#endif
++#define GPIO6_OFFSET			0x14000
++
++#define GPIO0_BASE			(APB_BASE + GPIO0_OFFSET)
++#define GPIO1_BASE			(APB_BASE + GPIO1_OFFSET)
++#define GPIO2_BASE			(APB_BASE + GPIO2_OFFSET)
++#define GPIO3_BASE			(APB_BASE + GPIO3_OFFSET)
++#define GPIO4_BASE			(APB_BASE + GPIO4_OFFSET)
++#define GPIO5_BASE			(APB_BASE + GPIO5_OFFSET)
++#define GPIO6_BASE			(APB_BASE + GPIO6_OFFSET)
++
++#define GPIO0_REG(x)			(GPIO0_BASE + (x))
++#define GPIO1_REG(x)			(GPIO1_BASE + (x))
++#define GPIO2_REG(x)			(GPIO2_BASE + (x))
++#define GPIO3_REG(x)			(GPIO3_BASE + (x))
++#define GPIO4_REG(x)			(GPIO4_BASE + (x))
++#define GPIO5_REG(x)			(GPIO5_BASE + (x))
++#define GPIO6_REG(x)			(GPIO6_BASE + (x))
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define GPIO_PAD_PULL_CTRL_SUPPORT		0
++#else
++#define GPIO_PAD_PULL_CTRL_SUPPORT		1
++#endif
++
++#if (CHIP_REV == A7L) || (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == A8)
++#define GPIO_PAD_PULL_OFFSET			0xD000
++#else
++#define GPIO_PAD_PULL_OFFSET			0x15000
++#endif
++
++#define GPIO_PAD_PULL_EN_0_OFFSET	0x80
++#define GPIO_PAD_PULL_EN_1_OFFSET	0x84
++#define GPIO_PAD_PULL_EN_2_OFFSET	0x88
++#define GPIO_PAD_PULL_EN_3_OFFSET	0x8C
++#define GPIO_PAD_PULL_EN_4_OFFSET	0x90
++#define GPIO_PAD_PULL_EN_5_OFFSET	0x100
++#define GPIO_PAD_PULL_EN_6_OFFSET	0x104
++
++#define GPIO_PAD_PULL_DIR_0_OFFSET	0x94
++#define GPIO_PAD_PULL_DIR_1_OFFSET	0x98
++#define GPIO_PAD_PULL_DIR_2_OFFSET	0x9C
++#define GPIO_PAD_PULL_DIR_3_OFFSET	0xA0
++#define GPIO_PAD_PULL_DIR_4_OFFSET	0xA4
++#define GPIO_PAD_PULL_DIR_5_OFFSET	0x10C
++#define GPIO_PAD_PULL_DIR_6_OFFSET	0x110
++
++#define GPIO_PAD_PULL_EN_OFFSET(bank)	((bank) >= 5 ? \
++					(0x100 + (((bank) - 5) * 4)) : \
++					(0x80 + ((bank) * 4)))
++#define GPIO_PAD_PULL_DIR_OFFSET(bank)	((bank) >= 5 ? \
++					(0x10C + (((bank) - 5) * 4)) : \
++					(0x94 + ((bank) * 4)))
++
++#define GPIO_PAD_PULL_BASE		(APB_BASE + GPIO_PAD_PULL_OFFSET)
++#define GPIO_PAD_PULL_REG(x)		(GPIO_PAD_PULL_BASE + (x))
++
++/* ==========================================================================*/
++#define GPIO_DATA_OFFSET		0x00
++#define GPIO_DIR_OFFSET			0x04
++#define GPIO_IS_OFFSET			0x08
++#define GPIO_IBE_OFFSET			0x0c
++#define GPIO_IEV_OFFSET			0x10
++#define GPIO_IE_OFFSET			0x14
++#define GPIO_AFSEL_OFFSET		0x18
++#define GPIO_RIS_OFFSET			0x1c
++#define GPIO_MIS_OFFSET			0x20
++#define GPIO_IC_OFFSET			0x24
++#define GPIO_MASK_OFFSET		0x28
++#define GPIO_ENABLE_OFFSET		0x2c
++
++/* ==========================================================================*/
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define	IOMUX_SUPPORT			1
++#else
++#define	IOMUX_SUPPORT			0
++#endif
++
++#define IOMUX_REG0_0_OFFSET		0x00
++#define IOMUX_REG0_1_OFFSET		0x04
++#define IOMUX_REG0_2_OFFSET		0x08
++#define IOMUX_REG1_0_OFFSET		0x0c
++#define IOMUX_REG1_1_OFFSET		0x10
++#define IOMUX_REG1_2_OFFSET		0x14
++#define IOMUX_REG2_0_OFFSET		0x18
++#define IOMUX_REG2_1_OFFSET		0x1c
++#define IOMUX_REG2_2_OFFSET		0x20
++#define IOMUX_REG3_0_OFFSET		0x24
++#define IOMUX_REG3_1_OFFSET		0x28
++#define IOMUX_REG3_2_OFFSET		0x2c
++#define IOMUX_REG4_0_OFFSET		0x30
++#define IOMUX_REG4_1_OFFSET		0x34
++#define IOMUX_REG4_2_OFFSET		0x38
++#define IOMUX_REG5_0_OFFSET		0x3c
++#define IOMUX_REG5_1_OFFSET		0x40
++#define IOMUX_REG5_2_OFFSET		0x44
++#define IOMUX_REG6_0_OFFSET		0x48
++#define IOMUX_REG6_1_OFFSET		0x4c
++#define IOMUX_REG6_2_OFFSET		0x50
++#define IOMUX_CTRL_SET_OFFSET		0xf0
++#define IOMUX_REG_OFFSET(bank, n)	(((bank) * 0xc) + ((n) * 4))
++
++#define IOMUX_OFFSET			0x16000
++#define IOMUX_BASE			(APB_BASE + IOMUX_OFFSET)
++#define IOMUX_REG(x)			(IOMUX_BASE + (x))
++
++/* ==========================================================================*/
++#define GPIO_BANK_SIZE			32
++#define AMBGPIO_SIZE			(GPIO_INSTANCES * GPIO_BANK_SIZE)
++
++#ifndef CONFIG_AMBARELLA_EXT_GPIO_NUM
++#define CONFIG_AMBARELLA_EXT_GPIO_NUM	(64)
++#endif
++#define EXT_GPIO(x)			(AMBGPIO_SIZE + x)
++
++#define ARCH_NR_GPIOS			EXT_GPIO(CONFIG_AMBARELLA_EXT_GPIO_NUM)
++
++/* ==========================================================================*/
++#define GPIO(x)				(x)
++
++#define GPIO_HIGH			1
++#define GPIO_LOW			0
++
++#define GPIO_FUNC_SW_INPUT		0
++#define GPIO_FUNC_SW_OUTPUT		1
++#define GPIO_FUNC_HW			2
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_GPIO_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/highres_timer.h b/arch/arm/mach-ambarella/include/plat/highres_timer.h
+new file mode 100644
+index 00000000..2f673268
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/highres_timer.h
+@@ -0,0 +1,32 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/highres_timer.h
++ *
++ * Author: Louis Sun <lysun@ambarella.com>
++ *
++ * Copyright (C) 2004-2011, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_HIGHRES_TIMER_H
++#define __PLAT_AMBARELLA_HIGHRES_TIMER_H
++
++extern void highres_timer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode);
++extern int highres_timer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);
++extern int highres_timer_cancel(struct hrtimer *timer);
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/hwlock.h b/arch/arm/mach-ambarella/include/plat/hwlock.h
+new file mode 100644
+index 00000000..a3aab6e5
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/hwlock.h
+@@ -0,0 +1,43 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/hwlock.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_HWLOCK_H__
++#define __PLAT_AMBARELLA_HWLOCK_H__
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++#include <linux/spinlock.h>
++extern spinlock_t ambarella_global_hw_lock;
++extern unsigned long ambarella_global_hw_flags;
++
++#define AMBARELLA_GLOBAL_HW_LOCK()		\
++	spin_lock_irqsave(&ambarella_global_hw_lock, ambarella_global_hw_flags)
++#define AMBARELLA_GLOBAL_HW_UNLOCK()		\
++	spin_unlock_irqrestore(&ambarella_global_hw_lock, ambarella_global_hw_flags)
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_HWLOCK_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/iav_helper.h b/arch/arm/mach-ambarella/include/plat/iav_helper.h
+new file mode 100644
+index 00000000..f74a7936
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/iav_helper.h
+@@ -0,0 +1,85 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/service.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_SERVICE_H
++#define __PLAT_AMBARELLA_SERVICE_H
++
++#ifndef __ASSEMBLER__
++
++/*===========================================================================*/
++
++/* gpio service for private operation */
++enum ambsvc_gpio_service_id {
++	AMBSVC_GPIO_REQUEST = 0,
++	AMBSVC_GPIO_OUTPUT,
++	AMBSVC_GPIO_INPUT,
++	AMBSVC_GPIO_FREE,
++	AMBSVC_GPIO_TO_IRQ,
++};
++
++struct ambsvc_gpio {
++	int svc_id;
++	int gpio;
++	int value;
++};
++
++/* pll service for private operation */
++enum ambsvc_pll_service_id {
++	AMBSVC_PLL_GET_RATE = 0,
++	AMBSVC_PLL_SET_RATE = 1,
++};
++
++struct ambsvc_pll {
++	int svc_id;
++	char *name;
++	int rate;
++};
++
++enum ambarella_service_id {
++	AMBARELLA_SERVICE_GPIO = 1,
++	AMBARELLA_SERVICE_PLL = 2,
++};
++
++typedef int (*ambarella_service_func)(void *arg, void *result);
++
++struct ambarella_service {
++	int service;
++	ambarella_service_func func;
++	struct list_head node;
++};
++
++extern int ambarella_register_service(struct ambarella_service *amb_svc);
++extern int ambarella_unregister_service(struct ambarella_service *amb_svc);
++extern int ambarella_request_service(int service, void *arg, void *result);
++
++/*===========================================================================*/
++extern void ambcache_clean_all(void *addr, unsigned int size);
++extern void ambcache_clean_range(void *addr, unsigned int size);
++extern void ambcache_inv_range(void *addr, unsigned int size);
++
++/*===========================================================================*/
++
++#endif /* __ASSEMBLER__ */
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/idc.h b/arch/arm/mach-ambarella/include/plat/idc.h
+new file mode 100644
+index 00000000..bcf1dc31
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/idc.h
+@@ -0,0 +1,93 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/idc.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_IDC_H__
++#define __PLAT_AMBARELLA_IDC_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
++#define IDC_INSTANCES			2
++#define IDC_SUPPORT_INTERNAL_MUX	1
++#define IDC3_BUS_MUX			GPIO(36)
++#else
++#define IDC_INSTANCES			3
++#define IDC_SUPPORT_INTERNAL_MUX	0
++#endif
++
++/* ==========================================================================*/
++#define IDC_OFFSET			0x3000
++#define IDC_BASE			(APB_BASE + IDC_OFFSET)
++#define IDC_REG(x)			(IDC_BASE + (x))
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define IDC2_OFFSET			0x1000
++#else
++#define IDC2_OFFSET			0x7000
++#endif
++#define IDC2_BASE			(APB_BASE + IDC2_OFFSET)
++#define IDC2_REG(x)			(IDC2_BASE + (x))
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define IDC3_OFFSET			0x13000
++#elif (CHIP_REV == A8)
++#define IDC3_OFFSET			0xE000
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define IDC3_OFFSET			0x7000
++#endif
++#define IDC3_BASE			(APB_BASE + IDC3_OFFSET)
++#define IDC3_REG(x)			(IDC3_BASE + (x))
++
++/* ==========================================================================*/
++#define IDC_ENR_OFFSET			0x00
++#define IDC_CTRL_OFFSET			0x04
++#define IDC_DATA_OFFSET			0x08
++#define IDC_STS_OFFSET			0x0c
++#define IDC_PSLL_OFFSET			0x10
++#define IDC_PSLH_OFFSET			0x14
++#define IDC_FMCTRL_OFFSET		0x18
++#define IDC_FMDATA_OFFSET		0x1c
++#define IDC_DUTYCYCLE_OFFSET	0x24
++#define IDC_STRETCHSCL_OFFSET	0x28
++
++#define IDC_ENR_REG_ENABLE		(0x01)
++#define IDC_ENR_REG_DISABLE		(0x00)
++
++#define IDC_CTRL_STOP			(0x08)
++#define IDC_CTRL_START			(0x04)
++#define IDC_CTRL_IF			(0x02)
++#define IDC_CTRL_ACK			(0x01)
++#define IDC_CTRL_CLS			(0x00)
++
++#define IDC_STS_FIFO_EMP		(0x04)
++#define IDC_STS_FIFO_FUL		(0x02)
++
++#define IDC_FIFO_BUF_SIZE		(63)
++
++#define IDC_FMCTRL_STOP			(0x08)
++#define IDC_FMCTRL_START		(0x04)
++#define IDC_FMCTRL_IF			(0x02)
++
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_IDC_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ir.h b/arch/arm/mach-ambarella/include/plat/ir.h
+new file mode 100644
+index 00000000..7babbc74
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ir.h
+@@ -0,0 +1,58 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ir.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_IR_H__
++#define __PLAT_AMBARELLA_IR_H__
++
++/* ==========================================================================*/
++#define IR_OFFSET			0x6000
++#define IR_BASE				(APB_BASE + IR_OFFSET)
++#define IR_REG(x)			(IR_BASE + (x))
++
++/* ==========================================================================*/
++#define IR_CONTROL_OFFSET		0x00
++#define IR_STATUS_OFFSET		0x04
++#define IR_DATA_OFFSET			0x08
++
++#define IR_CONTROL_REG			IR_REG(0x00)
++#define IR_STATUS_REG			IR_REG(0x04)
++#define IR_DATA_REG			IR_REG(0x08)
++
++/* IR_CONTROL_REG */
++#define IR_CONTROL_RESET		0x00004000
++#define IR_CONTROL_ENB			0x00002000
++#define IR_CONTROL_LEVINT		0x00001000
++#define IR_CONTROL_INTLEV(x)		(((x) & 0x3f)  << 4)
++#define IR_CONTROL_FIFO_OV		0x00000008
++#define IR_CONTROL_INTENB		0x00000004
++
++enum ambarella_ir_protocol {
++	AMBA_IR_PROTOCOL_NEC = 0,
++	AMBA_IR_PROTOCOL_PANASONIC = 1,
++	AMBA_IR_PROTOCOL_SONY = 2,
++	AMBA_IR_PROTOCOL_PHILIPS = 3,
++	AMBA_IR_PROTOCOL_END
++};
++
++#endif /* __PLAT_AMBARELLA_IR_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/irq.h b/arch/arm/mach-ambarella/include/plat/irq.h
+new file mode 100644
+index 00000000..7786c423
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/irq.h
+@@ -0,0 +1,946 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/irq.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_IRQ_H__
++#define __PLAT_AMBARELLA_IRQ_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define VIC_INSTANCES			(2)
++#define VIC_SUPPORT_CPU_OFFLOAD		(0)
++#define VIC_SUPPORT_REPRIORITIZE	(0)
++#elif (CHIP_REV == A7L)
++#define VIC_INSTANCES			(2)
++#define VIC_SUPPORT_CPU_OFFLOAD		(1)
++#define VIC_SUPPORT_REPRIORITIZE	(1)
++#elif (CHIP_REV == S2)
++#define VIC_INSTANCES			(3)
++#define VIC_SUPPORT_CPU_OFFLOAD		(0)
++#define VIC_SUPPORT_REPRIORITIZE	(0)
++#elif (CHIP_REV == S2E) || (CHIP_REV == S3L)
++#define VIC_INSTANCES			(3)
++#define VIC_SUPPORT_CPU_OFFLOAD		(2)
++#define VIC_SUPPORT_REPRIORITIZE	(1)
++#elif (CHIP_REV == A8)
++#define VIC_INSTANCES			(3)
++#define VIC_SUPPORT_CPU_OFFLOAD		(1)
++#define VIC_SUPPORT_REPRIORITIZE	(1)
++#elif (CHIP_REV == S2L)
++#define VIC_INSTANCES			(3)
++#define VIC_SUPPORT_CPU_OFFLOAD		(1)
++#define VIC_SUPPORT_REPRIORITIZE	(1)
++#elif (CHIP_REV == S3)
++#define VIC_INSTANCES			(4)
++#define VIC_SUPPORT_CPU_OFFLOAD		(2)
++#define VIC_SUPPORT_REPRIORITIZE	(1)
++#else
++#error "Not supported!"
++#endif
++
++#if (VIC_SUPPORT_CPU_OFFLOAD == 2)
++#if (CHIP_REV == S3)
++#define VIC_NULL_PRI_IRQ_VAL		(0x00000060)
++#define VIC_NULL_PRI_IRQ_FIX		(0)
++#elif (CHIP_REV == S2E)
++#define VIC_NULL_PRI_IRQ_VAL		(0x00000040)
++#define VIC_NULL_PRI_IRQ_FIX		(1)
++#else
++#define VIC_NULL_PRI_IRQ_VAL		(0xffffffff)
++#define VIC_NULL_PRI_IRQ_FIX		(0)
++#endif
++#endif
++
++#if (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define VIC_2NDGEN_BITASSIGNMENT	(1)
++#endif
++
++/* ==========================================================================*/
++#define VIC0_OFFSET			0x3000
++#define VIC1_OFFSET			0x10000
++#define VIC2_OFFSET			0x1C000
++#define VIC3_OFFSET			0x11000
++
++#define VIC0_BASE			(AHB_BASE + VIC0_OFFSET)
++#define VIC1_BASE			(AHB_BASE + VIC1_OFFSET)
++#define VIC2_BASE			(AHB_BASE + VIC2_OFFSET)
++#define VIC3_BASE			(AHB_BASE + VIC3_OFFSET)
++
++#define VIC0_REG(x)			(VIC0_BASE + (x))
++#define VIC1_REG(x)			(VIC1_BASE + (x))
++#define VIC2_REG(x)			(VIC2_BASE + (x))
++#define VIC3_REG(x)			(VIC3_BASE + (x))
++#define VIC_REG(irq, x)			((irq) < VIC0_INT_VEC(NR_VIC_IRQ_SIZE) ? VIC0_REG((x)) : \
++					 (irq) < VIC1_INT_VEC(NR_VIC_IRQ_SIZE) ? VIC1_REG((x)) : \
++					 (irq) < VIC2_INT_VEC(NR_VIC_IRQ_SIZE) ? VIC2_REG((x)) : \
++					 VIC3_REG((x)))
++
++/* ==========================================================================*/
++#define NR_VIC_IRQ_SIZE			(32)
++
++#if defined(CONFIG_ARM_GIC)
++#define VIC_IRQ(x)			((x) + 32)
++#define NR_SPI_IRQS			(256)
++#define SGI_INT_VEC(x)			(x)
++#define PPI_INT_VEC(x)			(x)
++#define SPI_INT_VEC(x)			(x)
++#else
++#define VIC_IRQ(x)			(x)
++#endif
++
++#define VIC0_INT_VEC(x)			(VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 0)
++#define VIC1_INT_VEC(x)			(VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 1)
++#define VIC2_INT_VEC(x)			(VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 2)
++#define VIC3_INT_VEC(x)			(VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 3)
++
++#ifndef NR_SPI_IRQS
++#define NR_VIC_IRQS			(VIC_INSTANCES * NR_VIC_IRQ_SIZE)
++#define GPIO_INT_VEC(x)			(NR_VIC_IRQS + x)
++#else
++#define NR_VIC_IRQS			NR_SPI_IRQS
++#define GPIO_INT_VEC(x)			(NR_SPI_IRQS + x)
++#endif
++
++#ifndef CONFIG_AMBARELLA_EXT_IRQ_NUM
++#define CONFIG_AMBARELLA_EXT_IRQ_NUM	(64)
++#endif
++#define EXT_IRQ(x)			GPIO_INT_VEC(AMBGPIO_SIZE + x)
++
++#define NR_IRQS				EXT_IRQ(CONFIG_AMBARELLA_EXT_IRQ_NUM)
++
++/* ==========================================================================*/
++#define VIC_IRQ_STA_OFFSET			(0x00)
++#define VIC_FIQ_STA_OFFSET			(0x04)
++#define VIC_RAW_STA_OFFSET			(0x08)
++#define VIC_INT_SEL_OFFSET			(0x0c)
++#define VIC_INTEN_OFFSET			(0x10)
++#define VIC_INTEN_CLR_OFFSET			(0x14)
++#define VIC_SOFTEN_OFFSET			(0x18)
++#define VIC_SOFTEN_CLR_OFFSET			(0x1c)
++#define VIC_PROTEN_OFFSET			(0x20)
++#define VIC_SENSE_OFFSET			(0x24)
++#define VIC_BOTHEDGE_OFFSET			(0x28)
++#define VIC_EVENT_OFFSET			(0x2c)
++#define VIC_INT_PTR0_OFFSET			(0x30)
++#define VIC_INT_PTR1_OFFSET			(0x34)
++#define VIC_EDGE_CLR_OFFSET			(0x38)
++#define VIC_INT_SEL_INT_OFFSET			(0x3c)
++#define VIC_INT_SEL_CLR_INT_OFFSET		(0x40)
++#define VIC_INT_EN_INT_OFFSET			(0x44)
++#define VIC_INT_EN_CLR_INT_OFFSET		(0x48)
++#define VIC_SOFT_INT_INT_OFFSET			(0x4c)
++#define VIC_SOFT_INT_CLR_INT_OFFSET		(0x50)
++#define VIC_INT_SENSE_INT_OFFSET		(0x54)
++#define VIC_INT_SENSE_CLR_INT_OFFSET		(0x58)
++#define VIC_INT_BOTHEDGE_INT_OFFSET		(0x5c)
++#define VIC_INT_BOTHEDGE_CLR_INT_OFFSET		(0x60)
++#define VIC_INT_EVT_INT_OFFSET			(0x64)
++#define VIC_INT_EVT_CLR_INT_OFFSET		(0x68)
++#define VIC_INT_PENDING_OFFSET			(0x6c)
++#define VIC_INT_RE_PRIORITIZE_EN_OFFSET		(0x70)
++#define VIC_INT_PRIORITY_0_OFFSET		(0x74)
++#define VIC_INT_PRIORITY_1_OFFSET		(0x78)
++#define VIC_INT_PRIORITY_2_OFFSET		(0x7c)
++#define VIC_INT_PRIORITY_3_OFFSET		(0x80)
++#define VIC_INT_PRIORITY_4_OFFSET		(0x84)
++#define VIC_INT_PRIORITY_5_OFFSET		(0x88)
++#define VIC_INT_DELAY_EN_OFFSET			(0x8c)
++#define VIC_INT_DELAY_OFFSET			(0x90)
++#define VIC_INT_PENDING_C1_REG			(0x94)
++#define VIC_INT_EDGE_CLR_OFFSET			(0x98)
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define USBVBUS_IRQ			VIC0_INT_VEC(0)
++#define VOUT_IRQ			VIC0_INT_VEC(1)
++#define VIN_IRQ				VIC0_INT_VEC(2)
++#define VDSP_IRQ			VIC0_INT_VEC(3)
++#define USBC_IRQ			VIC0_INT_VEC(4)
++#define HIF_ARM1_IRQ			VIC0_INT_VEC(5)
++#define HIF_ARM2_IRQ			VIC0_INT_VEC(6)
++#define I2STX_IRQ			VIC0_INT_VEC(7)
++#define I2SRX_IRQ			VIC0_INT_VEC(8)
++#define UART0_IRQ			VIC0_INT_VEC(9)
++#define GPIO0_IRQ			VIC0_INT_VEC(10)
++#define GPIO1_IRQ			VIC0_INT_VEC(11)
++#define TIMER1_IRQ			VIC0_INT_VEC(12)
++#define TIMER2_IRQ			VIC0_INT_VEC(13)
++#define TIMER3_IRQ			VIC0_INT_VEC(14)
++#define DMA_IRQ				VIC0_INT_VEC(15)
++#define FIOCMD_IRQ			VIC0_INT_VEC(16)
++#define FIODMA_IRQ			VIC0_INT_VEC(17)
++#define SD_IRQ				VIC0_INT_VEC(18)
++#define IDC_IRQ				VIC0_INT_VEC(19)
++#define SSI_IRQ				VIC0_INT_VEC(20)
++#define WDT_IRQ				VIC0_INT_VEC(21)
++#define IRIF_IRQ			VIC0_INT_VEC(22)
++#define CFCD1_IRQ			VIC0_INT_VEC(23)
++#define SD1CD_IRQ			VIC0_INT_VEC(24)
++#define UART1_IRQ			VIC0_INT_VEC(25)
++#define SSI_SLAVE_IRQ			VIC0_INT_VEC(26)
++#define ETH_IRQ				VIC0_INT_VEC(27)
++#define IDSP_ERROR_IRQ			VIC0_INT_VEC(28)
++#define VOUT_SYNC_MISSED_IRQ		VIC0_INT_VEC(29)
++#define GPIO2_IRQ			VIC0_INT_VEC(30)
++#define CFCD2_IRQ			VIC0_INT_VEC(31)
++
++#define AUDIO_ORC_IRQ			VIC1_INT_VEC(0)
++#define DMA_FIOS_IRQ			VIC1_INT_VEC(1)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(2)
++#define VOUT1_SYNC_MISSED_IRQ		VIC1_INT_VEC(3)
++#define IDC2_IRQ			VIC1_INT_VEC(4)
++#define IDSP_LAST_PIXEL_IRQ		VIC1_INT_VEC(5)
++#define IDSP_VSYNC_IRQ			VIC1_INT_VEC(6)
++#define IDSP_SENSOR_VSYNC_IRQ		VIC1_INT_VEC(7)
++#define HDMI_IRQ			VIC1_INT_VEC(8)
++#define SSI2_IRQ			VIC1_INT_VEC(9)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(10)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(11)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(12)
++#define AES_IRQ				VIC1_INT_VEC(13)
++#define DES_IRQ				VIC1_INT_VEC(14)
++#define MS_IRQ				VIC1_INT_VEC(15)
++#define GDMA_IRQ			VIC1_INT_VEC(16)
++#define MOTOR_IRQ			VIC1_INT_VEC(17)
++#define PMU_IRQ				VIC1_INT_VEC(31)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == A7L)
++#define USBVBUS_IRQ			VIC0_INT_VEC(0)
++#define VOUT_IRQ			VIC0_INT_VEC(1)
++#define VIN_IRQ				VIC0_INT_VEC(2)
++#define GDMA_IRQ			VIC0_INT_VEC(3)
++#define USBC_IRQ			VIC0_INT_VEC(4)
++#define SD1CD_IRQ			VIC0_INT_VEC(5)
++#define VDSP_IRQ			VIC0_INT_VEC(6)
++#define I2STX_IRQ			VIC0_INT_VEC(7)
++#define I2SRX_IRQ			VIC0_INT_VEC(8)
++#define UART0_IRQ			VIC0_INT_VEC(9)
++#define GPIO0_IRQ			VIC0_INT_VEC(10)
++#define GPIO1_IRQ			VIC0_INT_VEC(11)
++#define TIMER1_IRQ			VIC0_INT_VEC(12)
++#define TIMER2_IRQ			VIC0_INT_VEC(13)
++#define TIMER3_IRQ			VIC0_INT_VEC(14)
++#define DMA_IRQ				VIC0_INT_VEC(15)
++#define FIOCMD_IRQ			VIC0_INT_VEC(16)
++#define FIODMA_IRQ			VIC0_INT_VEC(17)
++#define SD_IRQ				VIC0_INT_VEC(18)
++#define IDC_IRQ				VIC0_INT_VEC(19)
++#define SSI_IRQ				VIC0_INT_VEC(20)
++#define WDT_IRQ				VIC0_INT_VEC(21)
++#define IRIF_IRQ			VIC0_INT_VEC(22)
++#define CFCD2_IRQ			VIC0_INT_VEC(24)
++#define UART1_IRQ			VIC0_INT_VEC(25)
++#define IDC2_IRQ			VIC0_INT_VEC(26)
++#define IDSP_ERROR_IRQ			VIC0_INT_VEC(28)
++#define GPIO2_IRQ			VIC0_INT_VEC(30)
++
++#define PMU_IRQ				VIC1_INT_VEC(0)
++#define DMA_FIOS_IRQ			VIC1_INT_VEC(1)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(2)
++#define IDSP_LAST_PIXEL_IRQ		VIC1_INT_VEC(5)
++#define IDSP_VSYNC_IRQ			VIC1_INT_VEC(6)
++#define IDSP_SENSOR_VSYNC_IRQ		VIC1_INT_VEC(7)
++#define HDMI_IRQ			VIC1_INT_VEC(8)
++#define SSI_SLAVE_IRQ			VIC1_INT_VEC(9)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(10)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(11)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(12)
++#define MS_IRQ				VIC1_INT_VEC(15)
++#define MOTOR_IRQ			VIC1_INT_VEC(17)
++#define GPIO3_IRQ			VIC1_INT_VEC(19)
++#define DRAM_ERROR_IRQ			VIC1_INT_VEC(23)
++#define SD2_IRQ				VIC1_INT_VEC(24)
++#define TIMER4_IRQ			VIC1_INT_VEC(27)
++#define TIMER5_IRQ			VIC1_INT_VEC(28)
++#define TIMER6_IRQ			VIC1_INT_VEC(29)
++#define TIMER7_IRQ			VIC1_INT_VEC(30)
++#define TIMER8_IRQ			VIC1_INT_VEC(31)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == S2)
++#define USBVBUS_IRQ			VIC0_INT_VEC(0)
++#define USBC_IRQ			VIC0_INT_VEC(4)
++#define USB_CHARGE_IRQ			VIC0_INT_VEC(5)
++#define I2STX_IRQ			VIC0_INT_VEC(7)
++#define I2SRX_IRQ			VIC0_INT_VEC(8)
++#define UART0_IRQ			VIC0_INT_VEC(9)
++#define GPIO0_IRQ			VIC0_INT_VEC(10)
++#define GPIO1_IRQ			VIC0_INT_VEC(11)
++#define DMA_IRQ				VIC0_INT_VEC(15)
++#define FIOCMD_IRQ			VIC0_INT_VEC(16)
++#define FIODMA_IRQ			VIC0_INT_VEC(17)
++#define SD_IRQ				VIC0_INT_VEC(18)
++#define IDC_IRQ				VIC0_INT_VEC(19)
++#define SSI_IRQ				VIC0_INT_VEC(20)
++#define IRIF_IRQ			VIC0_INT_VEC(22)
++#define CFCD1_IRQ			VIC0_INT_VEC(23)
++#define SD1CD_IRQ			VIC0_INT_VEC(24)
++#define UART1_IRQ			VIC0_INT_VEC(25)
++#define SSI_SLAVE_IRQ			VIC0_INT_VEC(26)
++#define ETH_IRQ				VIC0_INT_VEC(27)
++#define IDSP_SOFT_IRQ			VIC0_INT_VEC(28)
++#define GPIO3_IRQ			VIC0_INT_VEC(29)
++#define GPIO2_IRQ			VIC0_INT_VEC(30)
++
++#define ROLLING_SHUTTER_IRQ		VIC1_INT_VEC(0)
++#define DMA_FIOS_IRQ			VIC1_INT_VEC(1)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(2)
++#define IDSP_VIN_SOFT_IRQ		VIC1_INT_VEC(3)
++#define IDC2_IRQ			VIC1_INT_VEC(4)
++#define IDSP_LAST_PIXEL_IRQ		VIC1_INT_VEC(5)
++#define IDSP_VSYNC_IRQ			VIC1_INT_VEC(6)
++#define IDSP_SENSOR_VSYNC_IRQ		VIC1_INT_VEC(7)
++#define HDMI_IRQ			VIC1_INT_VEC(8)
++#define FIOS_ECC_IRQ			VIC1_INT_VEC(9)
++
++#define GPIO4_IRQ			VIC1_INT_VEC(16)
++#define MOTOR_IRQ			VIC1_INT_VEC(17)
++#define GDMA_IRQ			VIC1_INT_VEC(18)
++#define FACE_DET_IRQ			VIC1_INT_VEC(19)
++#define SD2_IRQ				VIC1_INT_VEC(20)
++#define SSI_MASTER_IRQ			VIC1_INT_VEC(21)
++#define IDSP_PROG_IRQ			VIC1_INT_VEC(26)
++
++#define VDSP_PIP_SVSYNC_IRQ		VIC2_INT_VEC(0)
++#define IDSP_PIP_SVSYNC_IRQ		VIC2_INT_VEC(1)
++#define IDSP_PIP_PROG_IRQ		VIC2_INT_VEC(2)
++#define IDSP_PIP_LAST_PIXEL_IRQ		VIC2_INT_VEC(3)
++#define CORTEX_CORE0_IRQ		VIC2_INT_VEC(4)
++#define CORTEX_CORE1_IRQ		VIC2_INT_VEC(5)
++#define ETH_PMT_INTR_IRQ		VIC2_INT_VEC(6)
++#define I2S1_RX_IRQ			VIC2_INT_VEC(7)
++#define I2S1_TX_IRQ			VIC2_INT_VEC(8)
++#define USB_EHCI_IRQ			VIC2_INT_VEC(9)
++#define AXI_SOFT_IRQ(x)			VIC2_INT_VEC((x) + 10)	/* 0 <= x <= 13 */
++#define CORTEX_WDT_IRQ			VIC2_INT_VEC(24)
++#define USB_OHCI_IRQ			VIC2_INT_VEC(25)
++#define IDC3_IRQ			VIC2_INT_VEC(26)
++#define UART2_IRQ			VIC2_INT_VEC(27)
++#define UART3_IRQ			VIC2_INT_VEC(28)
++#define PMU_IRQ				VIC2_INT_VEC(31)
++
++#if defined(CONFIG_ARM_GIC)
++#define VOUT_IRQ			VIC3_INT_VEC(0)
++#define VIN_IRQ				VIC3_INT_VEC(1)
++#define TIMER1_IRQ			VIC3_INT_VEC(2)
++#define TIMER2_IRQ			VIC3_INT_VEC(3)
++#define TIMER3_IRQ			VIC3_INT_VEC(4)
++#define WDT_IRQ				VIC3_INT_VEC(5)
++#define VOUT_TV_SYNC_IRQ		VIC3_INT_VEC(6)
++#define VOUT_LCD_SYNC_IRQ		VIC3_INT_VEC(7)
++#define ORC_VOUT0_IRQ			VIC3_INT_VEC(8)
++#define TIMER4_IRQ			VIC3_INT_VEC(9)
++#define TIMER5_IRQ			VIC3_INT_VEC(10)
++#define TIMER6_IRQ			VIC3_INT_VEC(11)
++#define TIMER7_IRQ			VIC3_INT_VEC(12)
++#define TIMER8_IRQ			VIC3_INT_VEC(13)
++#define CODE_VDSP_0_IRQ			VIC3_INT_VEC(14)
++#define CODE_VDSP_1_IRQ			VIC3_INT_VEC(15)
++#define CODE_VDSP_2_IRQ			VIC3_INT_VEC(16)
++#define CODE_VDSP_3_IRQ			VIC3_INT_VEC(17)
++#define MD5_IRQ				VIC3_INT_VEC(24)
++#define DES_IRQ				VIC3_INT_VEC(25)
++#define AES_IRQ				VIC3_INT_VEC(26)
++#define SHA1_IRQ			VIC3_INT_VEC(27)
++#else
++#define VOUT_IRQ			VIC0_INT_VEC(1)
++#define VIN_IRQ				VIC0_INT_VEC(2)
++#define TIMER1_IRQ			VIC0_INT_VEC(12)
++#define TIMER2_IRQ			VIC0_INT_VEC(13)
++#define TIMER3_IRQ			VIC0_INT_VEC(14)
++#define WDT_IRQ				VIC0_INT_VEC(21)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(10)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(11)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(14)
++#define TIMER4_IRQ			VIC1_INT_VEC(27)
++#define TIMER5_IRQ			VIC1_INT_VEC(28)
++#define TIMER6_IRQ			VIC1_INT_VEC(29)
++#define TIMER7_IRQ			VIC1_INT_VEC(30)
++#define TIMER8_IRQ			VIC1_INT_VEC(31)
++#define CODE_VDSP_0_IRQ			VIC0_INT_VEC(3)
++#define CODE_VDSP_1_IRQ			VIC1_INT_VEC(24)
++#define CODE_VDSP_2_IRQ			VIC1_INT_VEC(23)
++#define CODE_VDSP_3_IRQ			VIC1_INT_VEC(22)
++#define DES_IRQ				VIC1_INT_VEC(12)
++#define AES_IRQ				VIC1_INT_VEC(13)
++#define MD5_SHA1_IRQ			VIC1_INT_VEC(25)
++#endif
++
++#define GLOBAL_TIMER_IRQ		PPI_INT_VEC(27)
++#define LEGACY_FIQ			PPI_INT_VEC(28)
++#define LOCAL_TIMER_IRQ			PPI_INT_VEC(29)
++#define LOCAL_WDOG_IRQ			PPI_INT_VEC(30)
++#define LEGACY_IRQ			PPI_INT_VEC(31)
++
++#define DDD_IRQ				SPI_INT_VEC(153)
++#define DECODE_ERROR_IRQ		SPI_INT_VEC(154)
++#define SLAVE_ERROR_IRQ			SPI_INT_VEC(155)
++#define FMEM_READ_ERROR_IRQ		SPI_INT_VEC(156)
++#define FMEM_WRITE_ERROR_IRQ		SPI_INT_VEC(157)
++#define L2CC_ECNTR_IRQ			SPI_INT_VEC(158)
++#define L2CC_COMBINED_IRQ		SPI_INT_VEC(159)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == S2E)
++#define USBVBUS_IRQ			VIC0_INT_VEC(0)
++#define VOUT_IRQ			VIC0_INT_VEC(1)
++#define VIN_IRQ				VIC0_INT_VEC(2)
++#define CODE_VDSP_0_IRQ			VIC0_INT_VEC(3)
++#define USBC_IRQ			VIC0_INT_VEC(4)
++#define USB_CHARGE_IRQ			VIC0_INT_VEC(5)
++#define PMU_IRQ				VIC0_INT_VEC(6)
++#define I2STX_IRQ			VIC0_INT_VEC(7)
++#define I2SRX_IRQ			VIC0_INT_VEC(8)
++#define UART0_IRQ			VIC0_INT_VEC(9)
++#define GPIO0_IRQ			VIC0_INT_VEC(10)
++#define GPIO1_IRQ			VIC0_INT_VEC(11)
++#define TIMER1_IRQ			VIC0_INT_VEC(12)
++#define TIMER2_IRQ			VIC0_INT_VEC(13)
++#define TIMER3_IRQ			VIC0_INT_VEC(14)
++#define DMA_IRQ				VIC0_INT_VEC(15)
++#define FIOCMD_IRQ			VIC0_INT_VEC(16)
++#define FIODMA_IRQ			VIC0_INT_VEC(17)
++#define SD_IRQ				VIC0_INT_VEC(18)
++#define IDC_IRQ				VIC0_INT_VEC(19)
++#define SSI_IRQ				VIC0_INT_VEC(20)
++#define WDT_IRQ				VIC0_INT_VEC(21)
++#define IRIF_IRQ			VIC0_INT_VEC(22)
++#define SD1CD_IRQ			VIC0_INT_VEC(23)
++#define SD0CD_IRQ			VIC0_INT_VEC(24)
++#define UART1_IRQ			VIC0_INT_VEC(25)
++#define SSI_SLAVE_IRQ			VIC0_INT_VEC(26)
++#define ETH_IRQ				VIC0_INT_VEC(27)
++#define IDSP_SOFT_IRQ			VIC0_INT_VEC(28)
++#define GPIO3_IRQ			VIC0_INT_VEC(29)
++#define GPIO2_IRQ			VIC0_INT_VEC(30)
++#define PMU1_IRQ			VIC0_INT_VEC(31)
++
++#define ROLLING_SHUTTER_IRQ		VIC1_INT_VEC(0)
++#define DMA_FIOS_IRQ			VIC1_INT_VEC(1)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(2)
++#define IDSP_VIN_SOFT_IRQ		VIC1_INT_VEC(3)
++#define IDC2_IRQ			VIC1_INT_VEC(4)
++#define IDSP_LAST_PIXEL_IRQ		VIC1_INT_VEC(5)
++#define IDSP_VSYNC_IRQ			VIC1_INT_VEC(6)
++#define IDSP_SENSOR_VSYNC_IRQ		VIC1_INT_VEC(7)
++#define HDMI_IRQ			VIC1_INT_VEC(8)
++#define FIOS_ECC_IRQ			VIC1_INT_VEC(9)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(10)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(11)
++#define AES_IRQ				VIC1_INT_VEC(12)
++#define DES_IRQ				VIC1_INT_VEC(13)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(14)
++#define MD5_IRQ				VIC1_INT_VEC(15)
++#define GPIO4_IRQ			VIC1_INT_VEC(16)
++#define MOTOR_IRQ			VIC1_INT_VEC(17)
++#define GDMA_IRQ			VIC1_INT_VEC(18)
++#define L2CC_INTR1_IRQ			VIC1_INT_VEC(19)
++#define SD2_IRQ				VIC1_INT_VEC(20)
++#define SSI_MASTER_IRQ			VIC1_INT_VEC(21)
++#define CODE_VDSP_3_IRQ			VIC1_INT_VEC(22)
++#define CODE_VDSP_2_IRQ			VIC1_INT_VEC(23)
++#define CODE_VDSP_1_IRQ			VIC1_INT_VEC(24)
++#define L2CC_INTR_IRQ			VIC1_INT_VEC(25)
++#define IDSP_PROG_IRQ			VIC1_INT_VEC(26)
++#define TIMER4_IRQ			VIC1_INT_VEC(27)
++#define TIMER5_IRQ			VIC1_INT_VEC(28)
++#define TIMER6_IRQ			VIC1_INT_VEC(29)
++#define TIMER7_IRQ			VIC1_INT_VEC(30)
++#define TIMER8_IRQ			VIC1_INT_VEC(31)
++
++#define VDSP_PIP_SVSYNC_IRQ		VIC2_INT_VEC(0)
++#define IDSP_PIP_SVSYNC_IRQ		VIC2_INT_VEC(1)
++#define IDSP_PIP_PROG_IRQ		VIC2_INT_VEC(2)
++#define IDSP_PIP_LAST_PIXEL_IRQ		VIC2_INT_VEC(3)
++#define CORTEX_CORE0_IRQ		VIC2_INT_VEC(4)
++#define CORTEX_CORE1_IRQ		VIC2_INT_VEC(5)
++#define ETH_PMT_INTR_IRQ		VIC2_INT_VEC(6)
++#define I2S1_RX_IRQ			VIC2_INT_VEC(7)
++#define I2S1_TX_IRQ			VIC2_INT_VEC(8)
++#define USB_EHCI_IRQ			VIC2_INT_VEC(9)
++#define IPI00_IRQ			VIC2_INT_VEC(10)
++#define IPI01_IRQ			VIC2_INT_VEC(11)
++#define IPI02_IRQ			VIC2_INT_VEC(12)
++#define IPI03_IRQ			VIC2_INT_VEC(13)
++#define IPI04_IRQ			VIC2_INT_VEC(14)
++#define IPI05_IRQ			VIC2_INT_VEC(15)
++#define IPI06_IRQ			VIC2_INT_VEC(16)
++#define IPI10_IRQ			VIC2_INT_VEC(17)
++#define IPI11_IRQ			VIC2_INT_VEC(18)
++#define IPI12_IRQ			VIC2_INT_VEC(19)
++#define IPI13_IRQ			VIC2_INT_VEC(20)
++#define IPI14_IRQ			VIC2_INT_VEC(21)
++#define IPI15_IRQ			VIC2_INT_VEC(22)
++#define IPI16_IRQ			VIC2_INT_VEC(23)
++#define SHA1_IRQ			VIC2_INT_VEC(24)
++#define USB_OHCI_IRQ			VIC2_INT_VEC(25)
++#define IDC3_IRQ			VIC2_INT_VEC(26)
++#define UART2_IRQ			VIC2_INT_VEC(27)
++#define UART3_IRQ			VIC2_INT_VEC(28)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == A8)
++#define USBVBUS_IRQ			VIC0_INT_VEC(0)
++#define ROLLING_SHUTTER_IRQ		VIC0_INT_VEC(3)
++#define USBC_IRQ			VIC0_INT_VEC(4)
++#define HIF_ARM1_IRQ			VIC0_INT_VEC(5)
++#define HIF_ARM2_IRQ			VIC0_INT_VEC(6)
++#define I2STX_IRQ			VIC0_INT_VEC(7)
++#define I2SRX_IRQ			VIC0_INT_VEC(8)
++#define UART0_IRQ			VIC0_INT_VEC(9)
++#define GPIO0_IRQ			VIC0_INT_VEC(10)
++#define GPIO1_IRQ			VIC0_INT_VEC(11)
++#define DMA_IRQ				VIC0_INT_VEC(15)
++#define FIOCMD_IRQ			VIC0_INT_VEC(16)
++#define FIODMA_IRQ			VIC0_INT_VEC(17)
++#define SD_IRQ				VIC0_INT_VEC(18)
++#define IDC_IRQ				VIC0_INT_VEC(19)
++#define SSI_IRQ				VIC0_INT_VEC(20)
++#define IRIF_IRQ			VIC0_INT_VEC(22)
++#define CFCD1_IRQ			VIC0_INT_VEC(23)
++#define SD1CD_IRQ			VIC0_INT_VEC(24)
++#define UART1_IRQ			VIC0_INT_VEC(25)
++#define SSI_SLAVE_IRQ			VIC0_INT_VEC(26)
++#define ETH_IRQ				VIC0_INT_VEC(27)
++#define IDSP_SOFT_IRQ			VIC0_INT_VEC(28)
++#define ETH_POWER_IRQ			VIC0_INT_VEC(29)
++#define GPIO2_IRQ			VIC0_INT_VEC(30)
++#define CFCD2_IRQ			VIC0_INT_VEC(31)
++
++#define DRAM_AXI_ERROR_IRQ		VIC1_INT_VEC(0)
++#define DMA_FIOS_IRQ			VIC1_INT_VEC(1)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(2)
++#define SSI3_IRQ			VIC1_INT_VEC(3)
++#define IDC2_IRQ			VIC1_INT_VEC(4)
++#define IDSP_LAST_PIXEL_IRQ		VIC1_INT_VEC(5)
++#define IDSP_VSYNC_IRQ			VIC1_INT_VEC(6)
++#define IDSP_SENSOR_VSYNC_IRQ		VIC1_INT_VEC(7)
++#define HDMI_IRQ			VIC1_INT_VEC(8)
++#define SSI2_IRQ			VIC1_INT_VEC(9)
++#define AES_IRQ				VIC1_INT_VEC(13)
++#define DES_IRQ				VIC1_INT_VEC(14)
++#define MS_IRQ				VIC1_INT_VEC(15)
++#define USB_EHCI_IRQ			VIC1_INT_VEC(16)
++#define MOTOR_IRQ			VIC1_INT_VEC(17)
++#define MD5_SHA1_IRQ			VIC1_INT_VEC(18)
++#define GPIO3_IRQ			VIC1_INT_VEC(19)
++#define GPIO4_IRQ			VIC1_INT_VEC(20)
++#define GPIO5_IRQ			VIC1_INT_VEC(21)
++#define SATA_IRQ			VIC1_INT_VEC(22)
++#define DRAM_ERROR_IRQ			VIC1_INT_VEC(23)
++#define SD2_IRQ				VIC1_INT_VEC(24)
++#define UART2_IRQ			VIC1_INT_VEC(25)
++#define UART3_IRQ			VIC1_INT_VEC(26)
++
++#define GSSI_IRQ			VIC2_INT_VEC(0)
++#define SSI4_IRQ			VIC2_INT_VEC(1)
++#define PMU_IRQ				VIC2_INT_VEC(2)
++#define SD2CD_IRQ			VIC2_INT_VEC(3)
++#define CORTEX_CORE0_IRQ		VIC2_INT_VEC(4)
++#define CORTEX_CORE1_IRQ		VIC2_INT_VEC(5)
++#define TS_CH1_RX_IRQ			VIC2_INT_VEC(6)
++#define TS_CH0_RX_IRQ			VIC2_INT_VEC(7)
++#define TS_CH1_TX_IRQ			VIC2_INT_VEC(8)
++#define TS_CH0_TX_IRQ			VIC2_INT_VEC(9)
++#define AXI_SOFT_IRQ(x)			VIC2_INT_VEC((x) + 10)	/* 0 <= x <= 13 */
++#define CORTEX_WDT_IRQ			VIC2_INT_VEC(24)
++#define USB_OHCI_IRQ			VIC2_INT_VEC(25)
++#define SPDIF_IRQ			VIC2_INT_VEC(26)
++#define SSI_AHB_IRQ			VIC2_INT_VEC(27)
++#define IDC3_IRQ			VIC2_INT_VEC(28)
++
++#if defined(CONFIG_ARM_GIC)
++#define VOUT_IRQ			VIC3_INT_VEC(0)
++#define VIN_IRQ				VIC3_INT_VEC(1)
++#define TIMER1_IRQ			VIC3_INT_VEC(2)
++#define TIMER2_IRQ			VIC3_INT_VEC(3)
++#define TIMER3_IRQ			VIC3_INT_VEC(4)
++#define WDT_IRQ				VIC3_INT_VEC(5)
++#define VOUT_TV_SYNC_IRQ		VIC3_INT_VEC(6)
++#define VOUT_LCD_SYNC_IRQ		VIC3_INT_VEC(7)
++#define ORC_VOUT0_IRQ			VIC3_INT_VEC(8)
++#define TIMER4_IRQ			VIC3_INT_VEC(9)
++#define TIMER5_IRQ			VIC3_INT_VEC(10)
++#define TIMER6_IRQ			VIC3_INT_VEC(11)
++#define TIMER7_IRQ			VIC3_INT_VEC(12)
++#define TIMER8_IRQ			VIC3_INT_VEC(13)
++#define CODING_ORC0_IRQ			VIC3_INT_VEC(14)
++#define CODING_ORC1_IRQ			VIC3_INT_VEC(15)
++#define CODING_ORC2_IRQ			VIC3_INT_VEC(16)
++#define CODING_ORC3_IRQ			VIC3_INT_VEC(17)
++#else
++#define VOUT_IRQ			VIC0_INT_VEC(1)
++#define VIN_IRQ				VIC0_INT_VEC(2)
++#define TIMER1_IRQ			VIC0_INT_VEC(12)
++#define TIMER2_IRQ			VIC0_INT_VEC(13)
++#define TIMER3_IRQ			VIC0_INT_VEC(14)
++#define WDT_IRQ				VIC0_INT_VEC(21)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(10)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(11)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(12)
++#define TIMER4_IRQ			VIC1_INT_VEC(27)
++#define TIMER5_IRQ			VIC1_INT_VEC(28)
++#define TIMER6_IRQ			VIC1_INT_VEC(29)
++#define TIMER7_IRQ			VIC1_INT_VEC(30)
++#define TIMER8_IRQ			VIC1_INT_VEC(31)
++#define CODING_ORC0_IRQ			VIC2_INT_VEC(28)
++#define CODING_ORC1_IRQ			VIC2_INT_VEC(29)
++#define CODING_ORC2_IRQ			VIC2_INT_VEC(30)
++#define CODING_ORC3_IRQ			VIC2_INT_VEC(31)
++#endif
++
++#define GLOBAL_TIMER_IRQ		PPI_INT_VEC(27)
++#define LEGACY_FIQ			PPI_INT_VEC(28)
++#define LOCAL_TIMER_IRQ			PPI_INT_VEC(29)
++#define LOCAL_WDOG_IRQ			PPI_INT_VEC(30)
++#define LEGACY_IRQ			PPI_INT_VEC(31)
++
++#define DDD_IRQ				SPI_INT_VEC(153)
++#define DECODE_ERROR_IRQ		SPI_INT_VEC(154)
++#define SLAVE_ERROR_IRQ			SPI_INT_VEC(155)
++#define FMEM_READ_ERROR_IRQ		SPI_INT_VEC(156)
++#define FMEM_WRITE_ERROR_IRQ		SPI_INT_VEC(157)
++#define L2CC_ECNTR_IRQ			SPI_INT_VEC(158)
++#define L2CC_COMBINED_IRQ		SPI_INT_VEC(159)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == S2L)
++#define USBVBUS_IRQ			VIC0_INT_VEC(0)
++#define VOUT_IRQ			VIC0_INT_VEC(1)
++#define VIN_IRQ				VIC0_INT_VEC(2)
++#define CODE_VDSP_0_IRQ			VIC0_INT_VEC(3)
++#define USBC_IRQ			VIC0_INT_VEC(4)
++#define USB_CHARGE_IRQ			VIC0_INT_VEC(5)
++#define SD2CD_IRQ			VIC0_INT_VEC(6)
++#define I2STX_IRQ			VIC0_INT_VEC(7)
++#define I2SRX_IRQ			VIC0_INT_VEC(8)
++#define UART0_IRQ			VIC0_INT_VEC(9)
++#define GPIO0_IRQ			VIC0_INT_VEC(10)
++#define GPIO1_IRQ			VIC0_INT_VEC(11)
++#define TIMER1_IRQ			VIC0_INT_VEC(12)
++#define TIMER2_IRQ			VIC0_INT_VEC(13)
++#define TIMER3_IRQ			VIC0_INT_VEC(14)
++#define DMA_IRQ				VIC0_INT_VEC(15)
++#define FIOCMD_IRQ			VIC0_INT_VEC(16)
++#define FIODMA_IRQ			VIC0_INT_VEC(17)
++#define SD_IRQ				VIC0_INT_VEC(18)
++#define IDC_IRQ				VIC0_INT_VEC(19)
++#define SD3_IRQ				VIC0_INT_VEC(20)
++#define WDT_IRQ				VIC0_INT_VEC(21)
++#define IRIF_IRQ			VIC0_INT_VEC(22)
++#define SD1CD_IRQ			VIC0_INT_VEC(23)
++#define SD0CD_IRQ			VIC0_INT_VEC(24)
++#define UART1_IRQ			VIC0_INT_VEC(25)
++#define MOTOR_IRQ			VIC0_INT_VEC(26)
++#define ETH_IRQ				VIC0_INT_VEC(27)
++#define USB_CONNECT_CHANGE_IRQ		VIC0_INT_VEC(28)
++#define GPIO3_IRQ			VIC0_INT_VEC(29)
++#define GPIO2_IRQ			VIC0_INT_VEC(30)
++
++#define ETH_PMT_IRQ			VIC1_INT_VEC(0)
++#define DMA_FIOS_IRQ			VIC1_INT_VEC(1)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(2)
++#define SSI_MASTER0_IRQ			VIC1_INT_VEC(3)
++#define IDC3_IRQ			VIC1_INT_VEC(4)
++#define SSI_MASTER1_IRQ			VIC1_INT_VEC(5)
++#define SSI_SLAVE_IRQ			VIC1_INT_VEC(6)
++#define USB_EHCI_IRQ			VIC1_INT_VEC(7)
++#define HDMI_IRQ			VIC1_INT_VEC(8)
++#define FIOS_ECC_IRQ			VIC1_INT_VEC(9)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(10)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(11)
++#define USB_OHCI_IRQ			VIC1_INT_VEC(12)
++#define NOR_SPI				VIC1_INT_VEC(13)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(14)
++#define GDMA_IRQ			VIC1_INT_VEC(18)
++#define IDC2_IRQ			VIC1_INT_VEC(19)
++#define SD2_IRQ				VIC1_INT_VEC(20)
++#define IDSP_PIP_VSYNC_IRQ		VIC1_INT_VEC(21)
++#define IDSP_PIP_SOF_IRQ		VIC1_INT_VEC(22)
++#define IDSP_PIP_MVSYNC_IRQ		VIC1_INT_VEC(23)
++#define IDSP_PIP_LAST_PIXEL_IRQ		VIC1_INT_VEC(24)
++#define IDSP_PIP_DVSYNC_IRQ		VIC1_INT_VEC(25)
++#define VDSP_PIP_CODING_IRQ		VIC1_INT_VEC(26)
++#define TIMER4_IRQ			VIC1_INT_VEC(27)
++#define TIMER5_IRQ			VIC1_INT_VEC(28)
++#define TIMER6_IRQ			VIC1_INT_VEC(29)
++#define TIMER7_IRQ			VIC1_INT_VEC(30)
++#define TIMER8_IRQ			VIC1_INT_VEC(31)
++
++#define IDSP_VIN_MVSYNC_IRQ		VIC2_INT_VEC(0)
++#define IDSP_VIN_VSYNC_IRQ		VIC2_INT_VEC(1)
++#define IDSP_VIN_SOF_IRQ		VIC2_INT_VEC(2)
++#define IDSP_VIN_DVSYNC_IRQ		VIC2_INT_VEC(3)
++#define IDSP_VIN_LAST_PIXEL_IRQ		VIC2_INT_VEC(4)
++#define L2CC_INTR_IRQ			VIC2_INT_VEC(21)
++#define MD5_IRQ				VIC2_INT_VEC(22)
++#define DES_IRQ				VIC2_INT_VEC(23)
++#define AES_IRQ				VIC2_INT_VEC(24)
++#define SHA1_IRQ			VIC2_INT_VEC(25)
++#define USB_DIGITAL_ID_CHANGE_IRQ	VIC2_INT_VEC(27)
++#define PMU_IRQ				VIC2_INT_VEC(28)
++#define L2CC_DECERR_IRQ			VIC2_INT_VEC(29)
++#define L2CC_SLVERR_IRQ			VIC2_INT_VEC(30)
++#define L2CC_ECNTR_IRQ			VIC2_INT_VEC(31)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == S3)
++#define IPI00_IRQ			VIC0_INT_VEC(0)
++#define IPI01_IRQ			VIC0_INT_VEC(1)
++#define IPI02_IRQ			VIC0_INT_VEC(2)
++#define IPI03_IRQ			VIC0_INT_VEC(3)
++#define IPI04_IRQ			VIC0_INT_VEC(4)
++#define IPI05_IRQ			VIC0_INT_VEC(5)
++#define IPI06_IRQ			VIC0_INT_VEC(6)
++#define TIMER1_IRQ			VIC0_INT_VEC(7)
++#define TIMER2_IRQ			VIC0_INT_VEC(8)
++#define TIMER3_IRQ			VIC0_INT_VEC(9)
++#define TIMER4_IRQ			VIC0_INT_VEC(10)
++#define TIMER5_IRQ			VIC0_INT_VEC(11)
++#define TIMER6_IRQ			VIC0_INT_VEC(12)
++#define TIMER7_IRQ			VIC0_INT_VEC(13)
++#define TIMER8_IRQ			VIC0_INT_VEC(14)
++#define PMU_IRQ				VIC0_INT_VEC(15)
++#define IPI10_IRQ			VIC0_INT_VEC(16)
++#define IPI11_IRQ			VIC0_INT_VEC(17)
++#define IPI12_IRQ			VIC0_INT_VEC(18)
++#define IPI13_IRQ			VIC0_INT_VEC(19)
++#define IPI14_IRQ			VIC0_INT_VEC(20)
++#define IPI15_IRQ			VIC0_INT_VEC(21)
++#define IPI16_IRQ			VIC0_INT_VEC(22)
++#define TIMER11_IRQ			VIC0_INT_VEC(23)
++#define TIMER12_IRQ			VIC0_INT_VEC(24)
++#define TIMER13_IRQ			VIC0_INT_VEC(25)
++#define TIMER14_IRQ			VIC0_INT_VEC(26)
++#define TIMER15_IRQ			VIC0_INT_VEC(27)
++#define TIMER16_IRQ			VIC0_INT_VEC(28)
++#define TIMER17_IRQ			VIC0_INT_VEC(29)
++#define TIMER18_IRQ			VIC0_INT_VEC(30)
++#define PMU1_IRQ			VIC0_INT_VEC(31)
++
++#define IDSP_VIN_STAT_IRQ		VIC1_INT_VEC(0)
++#define IDSP_VIN_MVSYNC_IRQ		VIC1_INT_VEC(1)
++#define IDSP_VIN_VSYNC_IRQ		VIC1_INT_VEC(2)
++#define IDSP_VIN_SOF_IRQ		VIC1_INT_VEC(3)
++#define IDSP_VIN_DVSYNC_IRQ		VIC1_INT_VEC(4)
++#define IDSP_VIN_LAST_PIXEL_IRQ		VIC1_INT_VEC(5)
++#define IDSP_PIP_STAT_IRQ		VIC1_INT_VEC(6)
++#define IDSP_PIP_MVSYNC_IRQ		VIC1_INT_VEC(7)
++#define IDSP_PIP_VSYNC_IRQ		VIC1_INT_VEC(8)
++#define IDSP_PIP_SOF_IRQ		VIC1_INT_VEC(9)
++#define IDSP_PIP_DVSYNC_IRQ		VIC1_INT_VEC(10)
++#define IDSP_PIP_LAST_PIXEL_IRQ		VIC1_INT_VEC(11)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(12)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(13)
++#define CODE_VDSP_0_IRQ			VIC1_INT_VEC(14)
++#define CODE_VDSP_1_IRQ			VIC1_INT_VEC(15)
++#define CODE_VDSP_2_IRQ			VIC1_INT_VEC(16)
++#define CODE_VDSP_3_IRQ			VIC1_INT_VEC(17)
++#define CODE_VDSP_4_IRQ			VIC1_INT_VEC(18)
++#define CODE_VDSP_5_IRQ			VIC1_INT_VEC(19)
++#define CODE_VDSP_6_IRQ			VIC1_INT_VEC(20)
++#define CODE_VDSP_7_IRQ			VIC1_INT_VEC(21)
++#define VIN_IRQ				VIC1_INT_VEC(22)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(23)
++#define VOUT_IRQ			VIC1_INT_VEC(24)
++#define VDSP_ORC_BKPT_IRQ		VIC1_INT_VEC(25)
++#define VDSP_EORC0_BKPT_IRQ		VIC1_INT_VEC(26)
++#define VDSP_DORC_BRPT_IRQ		VIC1_INT_VEC(27)
++#define VDSP_PIP_CODING_IRQ		VIC1_INT_VEC(28)
++#define FDET_IRQ			VIC1_INT_VEC(29)
++#define TIMER10_IRQ			VIC1_INT_VEC(30)
++#define TIMER9_IRQ			VIC1_INT_VEC(31)
++
++#define CANC_IRQ			VIC2_INT_VEC(0)
++#define ETH_IRQ				VIC2_INT_VEC(1)
++#define USB_EHCI_IRQ			VIC2_INT_VEC(2)
++#define USB_OHCI_IRQ			VIC2_INT_VEC(3)
++#define USBC_IRQ			VIC2_INT_VEC(4)
++#define DMA_IRQ				VIC2_INT_VEC(5)
++#define DMA_FIOS_IRQ			VIC2_INT_VEC(6)
++#define FIOS_ECC_IRQ			VIC2_INT_VEC(7)
++#define FIOCMD_IRQ			VIC2_INT_VEC(8)
++#define FIODMA_IRQ			VIC2_INT_VEC(9)
++#define GDMA_IRQ			VIC2_INT_VEC(10)
++#define SD3_IRQ				VIC2_INT_VEC(11)
++#define SD2_IRQ				VIC2_INT_VEC(12)
++#define SD_IRQ				VIC2_INT_VEC(13)
++#define NOR_SPI				VIC2_INT_VEC(14)
++#define SSI_MASTER1_IRQ			VIC2_INT_VEC(15)
++#define SSI_MASTER0_IRQ			VIC2_INT_VEC(16)
++#define SSI_SLAVE_IRQ			VIC2_INT_VEC(17)
++#define UART1_IRQ			VIC2_INT_VEC(18)
++#define IDC3_IRQ			VIC2_INT_VEC(19)
++#define IDC2_IRQ			VIC2_INT_VEC(20)
++#define IDC_IRQ				VIC2_INT_VEC(21)
++#define IRIF_IRQ			VIC2_INT_VEC(22)
++#define I2STX_IRQ			VIC2_INT_VEC(23)
++#define I2SRX_IRQ			VIC2_INT_VEC(24)
++#define IDC_SLAVE_IRQ			VIC2_INT_VEC(25)
++#define HIF_ARM2_IRQ			VIC2_INT_VEC(26)
++#define HIF_ARM1_IRQ			VIC2_INT_VEC(27)
++#define TS_CH1_RX_IRQ			VIC2_INT_VEC(28)
++#define TS_CH0_RX_IRQ			VIC2_INT_VEC(29)
++#define TS_CH1_TX_IRQ			VIC2_INT_VEC(30)
++#define TS_CH0_TX_IRQ			VIC2_INT_VEC(31)
++
++#define USBVBUS_IRQ			VIC3_INT_VEC(0)
++#define USB_DIGITAL_ID_CHANGE_IRQ	VIC3_INT_VEC(1)
++#define USB_CONNECT_CHANGE_IRQ		VIC3_INT_VEC(2)
++#define USB_CHARGE_IRQ			VIC3_INT_VEC(3)
++#define SD2CD_IRQ			VIC3_INT_VEC(4)
++#define SD1CD_IRQ			VIC3_INT_VEC(5)
++#define SD0CD_IRQ			VIC3_INT_VEC(6)
++#define ADC_LEVEL_IRQ			VIC3_INT_VEC(7)
++#define HDMI_IRQ			VIC3_INT_VEC(8)
++#define WDT_IRQ				VIC3_INT_VEC(9)
++#define SLIM_IRQ			VIC3_INT_VEC(10)
++#define ETH_PMT_IRQ			VIC3_INT_VEC(11)
++#define UART0_IRQ			VIC3_INT_VEC(12)
++#define MOTOR_IRQ			VIC3_INT_VEC(13)
++#define SHA1_IRQ			VIC3_INT_VEC(14)
++#define AES_IRQ				VIC3_INT_VEC(15)
++#define DES_IRQ				VIC3_INT_VEC(16)
++#define MD5_IRQ				VIC3_INT_VEC(17)
++#define L2CC_INTR_IRQ			VIC3_INT_VEC(18)
++#define L2CC_INTR1_IRQ			VIC3_INT_VEC(19)
++#define AXI_SWI_IRQ			VIC3_INT_VEC(20)
++#define AXI_SWI1_IRQ			VIC3_INT_VEC(21)
++#define GPIO6_IRQ			VIC3_INT_VEC(22)
++#define GPIO5_IRQ			VIC3_INT_VEC(23)
++#define GPIO4_IRQ			VIC3_INT_VEC(24)
++#define GPIO3_IRQ			VIC3_INT_VEC(25)
++#define GPIO2_IRQ			VIC3_INT_VEC(26)
++#define GPIO1_IRQ			VIC3_INT_VEC(27)
++#define GPIO0_IRQ			VIC3_INT_VEC(28)
++#define DMIC_IRQ			VIC3_INT_VEC(29)
++#define TIMER20_IRQ			VIC3_INT_VEC(30)
++#define TIMER19_IRQ			VIC3_INT_VEC(31)
++
++/* ==========================================================================*/
++#elif (CHIP_REV == S3L)
++#define TIMER1_IRQ			VIC0_INT_VEC(0)
++#define TIMER2_IRQ			VIC0_INT_VEC(1)
++#define TIMER3_IRQ			VIC0_INT_VEC(2)
++#define TIMER4_IRQ			VIC0_INT_VEC(3)
++#define TIMER5_IRQ			VIC0_INT_VEC(4)
++#define TIMER6_IRQ			VIC0_INT_VEC(5)
++#define TIMER7_IRQ			VIC0_INT_VEC(6)
++#define AXI_SOFT_IRQ(x)			VIC0_INT_VEC((x) + 7)	/* 0 <= x <= 13 */
++#define AXI_SW_IRQ0			VIC0_INT_VEC(21)
++#define AXI_SW_IRQ1			VIC0_INT_VEC(22)
++#define PMU_IRQ				VIC0_INT_VEC(23)
++#define L2CC_INTR_IRQ			VIC0_INT_VEC(24)
++#define L2CC_DECERR_IRQ			VIC0_INT_VEC(25)
++#define L2CC_SLVERR_IRQ			VIC0_INT_VEC(26)
++#define L2CC_ECNTR_IRQ			VIC0_INT_VEC(27)
++#define MD5_IRQ				VIC0_INT_VEC(28)
++#define DES_IRQ				VIC0_INT_VEC(29)
++#define AES_IRQ				VIC0_INT_VEC(30)
++#define SHA1_IRQ			VIC0_INT_VEC(31)
++
++#define IDSP_VIN_MVSYNC_IRQ		VIC1_INT_VEC(0)
++#define IDSP_VIN_VSYNC_IRQ		VIC1_INT_VEC(1)
++#define IDSP_VIN_SOF_IRQ		VIC1_INT_VEC(2)
++#define IDSP_VIN_DVSYNC_IRQ		VIC1_INT_VEC(3)
++#define IDSP_VIN_LAST_PIXEL_IRQ		VIC1_INT_VEC(4)
++#define GDMA_IRQ			VIC1_INT_VEC(5)
++#define IDSP_PIP_MVSYNC_IRQ		VIC1_INT_VEC(6)
++#define IDSP_PIP_VSYNC_IRQ		VIC1_INT_VEC(7)
++#define IDSP_PIP_SOF_IRQ		VIC1_INT_VEC(8)
++#define IDSP_PIP_DVSYNC_IRQ		VIC1_INT_VEC(9)
++#define IDSP_PIP_LAST_PIXEL_IRQ		VIC1_INT_VEC(10)
++#define VOUT_TV_SYNC_IRQ		VIC1_INT_VEC(11)
++#define VOUT_LCD_SYNC_IRQ		VIC1_INT_VEC(12)
++#define CODE_VDSP_0_IRQ			VIC1_INT_VEC(13)
++#define CODE_VDSP_1_IRQ			VIC1_INT_VEC(14)
++#define CODE_VDSP_2_IRQ			VIC1_INT_VEC(15)
++#define CODE_VDSP_3_IRQ			VIC1_INT_VEC(16)
++#define GPIO3_IRQ			VIC1_INT_VEC(17)
++#define GPIO2_IRQ			VIC1_INT_VEC(18)
++#define GPIO1_IRQ			VIC1_INT_VEC(19)
++#define GPIO0_IRQ			VIC1_INT_VEC(20)
++#define VIN_IRQ				VIC1_INT_VEC(21)
++#define ORC_VOUT0_IRQ			VIC1_INT_VEC(22)
++#define VOUT_IRQ			VIC1_INT_VEC(23)
++#define VDSP_PIP_CODING_IRQ		VIC1_INT_VEC(24)
++#define ADC_LEVEL_IRQ			VIC1_INT_VEC(25)
++#define HDMI_IRQ			VIC1_INT_VEC(26)
++#define WDT_IRQ				VIC1_INT_VEC(27)
++#define ETH_PMT_IRQ			VIC1_INT_VEC(28)
++#define UART0_IRQ			VIC1_INT_VEC(29)
++#define MOTOR_IRQ			VIC1_INT_VEC(30)
++#define TIMER8_IRQ			VIC1_INT_VEC(31)
++
++#define PWC_ALRAM			VIC2_INT_VEC(0)
++#define ETH_IRQ				VIC2_INT_VEC(1)
++#define USB_EHCI_IRQ			VIC2_INT_VEC(2)
++#define USB_OHCI_IRQ			VIC2_INT_VEC(3)
++#define USBC_IRQ			VIC2_INT_VEC(4)
++#define DMA_IRQ				VIC2_INT_VEC(5)
++#define DMA_FIOS_IRQ			VIC2_INT_VEC(6)
++#define FIOS_ECC_IRQ			VIC2_INT_VEC(7)
++#define FIOCMD_IRQ			VIC2_INT_VEC(8)
++#define FIODMA_IRQ			VIC2_INT_VEC(9)
++#define SD2_IRQ				VIC2_INT_VEC(10) /* SDXC rather than SDIO */
++#define SD_IRQ				VIC2_INT_VEC(11)
++#define NOR_SPI				VIC2_INT_VEC(12)
++#define SSI_MASTER1_IRQ			VIC2_INT_VEC(13)
++#define SSI_MASTER0_IRQ			VIC2_INT_VEC(14)
++#define SSI_SLAVE_IRQ			VIC2_INT_VEC(15)
++#define UART1_IRQ			VIC2_INT_VEC(16)
++#define IDC3_IRQ			VIC2_INT_VEC(17)
++#define IDC2_IRQ			VIC2_INT_VEC(18)
++#define IDC_IRQ				VIC2_INT_VEC(19)
++#define IRIF_IRQ			VIC2_INT_VEC(20)
++#define I2STX_IRQ			VIC2_INT_VEC(21)
++#define I2SRX_IRQ			VIC2_INT_VEC(22)
++#define USBVBUS_IRQ			VIC2_INT_VEC(23)
++#define USB_DIGITAL_ID_CHANGE_IRQ	VIC2_INT_VEC(24)
++#define USB_CONNECT_CHANGE_IRQ		VIC2_INT_VEC(25)
++#define USB_CHARGE_IRQ			VIC2_INT_VEC(26)
++#define SD2CD_IRQ			VIC2_INT_VEC(27) /* SDXC rather than SDIO */
++#define SD0CD_IRQ			VIC2_INT_VEC(28)
++
++/* ==========================================================================*/
++#else
++#error "Not supported!"
++#endif
++
++/* ==========================================================================*/
++#define VIRQ_RISING_EDGE	0
++#define VIRQ_FALLING_EDGE	1
++#define VIRQ_BOTH_EDGES		2
++#define VIRQ_LEVEL_LOW		3
++#define VIRQ_LEVEL_HIGH		4
++
++#ifndef __ASSEMBLER__
++
++extern void ambvic_sw_set(void __iomem *vic_base, unsigned int vic_irq);
++extern void ambvic_sw_clr(void __iomem *vic_base, unsigned int vic_irq);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/nand.h b/arch/arm/mach-ambarella/include/plat/nand.h
+new file mode 100644
+index 00000000..3cb9e38b
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/nand.h
+@@ -0,0 +1,247 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/nand.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_NAND_H__
++#define __PLAT_AMBARELLA_NAND_H__
++
++/* ==========================================================================*/
++
++#if (CHIP_REV == S2E) || (CHIP_REV == S3L)
++#define NAND_ECC_RPT_NUM_SUPPORT	1
++#else
++#define NAND_ECC_RPT_NUM_SUPPORT	0
++#endif
++
++/* ==========================================================================*/
++#define FLASH_CTR_OFFSET		0x120
++#define FLASH_CMD_OFFSET		0x124
++#define FLASH_TIM0_OFFSET		0x128
++#define FLASH_TIM1_OFFSET		0x12c
++#define FLASH_TIM2_OFFSET		0x130
++#define FLASH_TIM3_OFFSET		0x134
++#define FLASH_TIM4_OFFSET		0x138
++#define FLASH_TIM5_OFFSET		0x13c
++#define FLASH_STA_OFFSET		0x140
++#define FLASH_ID_OFFSET			0x144
++#define FLASH_CFI_OFFSET		0x148
++#define FLASH_LEN_OFFSET		0x14c
++#define FLASH_INT_OFFSET		0x150
++#define FLASH_EX_CTR_OFFSET		0x15c
++#define FLASH_EX_ID_OFFSET		0x160
++/* followings are for customer command, start from S3L */
++#define FLASH_TIM6_OFFSET		0x164
++#define FLASH_CC_OFFSET			0x170
++#define FLASH_CC_WORD_OFFSET		0x174
++#define FLASH_CC_DATA0_OFFSET		0x180
++#define FLASH_CC_DATA1_OFFSET		0x184
++#define FLASH_CC_DATA2_OFFSET		0x188
++#define FLASH_CC_DATA3_OFFSET		0x18c
++#define FLASH_CC_DATA4_OFFSET		0x190
++#define FLASH_CC_DATA5_OFFSET		0x194
++#define FLASH_CC_DATA6_OFFSET		0x198
++#define FLASH_CC_DATA7_OFFSET		0x19c
++
++#define NAND_CTR_REG			FIO_REG(0x120)
++#define NAND_CMD_REG			FIO_REG(0x124)
++#define NAND_TIM0_REG			FIO_REG(0x128)
++#define NAND_TIM1_REG			FIO_REG(0x12c)
++#define NAND_TIM2_REG			FIO_REG(0x130)
++#define NAND_TIM3_REG			FIO_REG(0x134)
++#define NAND_TIM4_REG			FIO_REG(0x138)
++#define NAND_TIM5_REG			FIO_REG(0x13c)
++#define NAND_STA_REG			FIO_REG(0x140)
++#define NAND_ID_REG			FIO_REG(0x144)
++#define NAND_COPY_ADDR_REG		FIO_REG(0x148)
++#define NAND_LEN_REG			FIO_REG(0x14c)
++#define NAND_INT_REG			FIO_REG(0x150)
++#define NAND_EXT_CTR_REG		FIO_REG(0x15c)
++#define NAND_EXT_ID5_REG		FIO_REG(0x160)
++/* followings are for customer command, start from S3L */
++#define NAND_TIM6_REG			FIO_REG(0x164)
++#define NAND_CC_REG			FIO_REG(0x170)
++#define NAND_CC_WORD_REG		FIO_REG(0x174)
++#define NAND_CC_DATA0_REG		FIO_REG(0x180)
++#define NAND_CC_DATA1_REG		FIO_REG(0x184)
++#define NAND_CC_DATA2_REG		FIO_REG(0x188)
++#define NAND_CC_DATA3_REG		FIO_REG(0x18c)
++#define NAND_CC_DATA4_REG		FIO_REG(0x190)
++#define NAND_CC_DATA5_REG		FIO_REG(0x194)
++#define NAND_CC_DATA6_REG		FIO_REG(0x198)
++#define NAND_CC_DATA7_REG		FIO_REG(0x19c)
++
++#define NAND_READ_CMDWORD_REG		FIO_REG(0x154)
++#define NAND_PROG_CMDWORD_REG		FIO_REG(0x158)
++#define NAND_CMDWORD1(x)		((x) << 16)
++#define NAND_CMDWORD2(x)		((x) & 0xff)
++
++#define NAND_CPS1_ADDR_REG		FIO_REG(0x154)
++#define NAND_CPD1_ADDR_REG		FIO_REG(0x158)
++#define NAND_CPS2_ADDR_REG		FIO_REG(0x15c)
++#define NAND_CPD2_ADDR_REG		FIO_REG(0x160)
++#define NAND_CPS3_ADDR_REG		FIO_REG(0x164)
++#define NAND_CPD3_ADDR_REG		FIO_REG(0x168)
++#define NAND_NBR_SPA_REG		FIO_REG(0x16c)
++
++#define NAND_CTR_A(x)			((x) << 28)
++#define NAND_CTR_SA			0x08000000
++#define NAND_CTR_SE			0x04000000
++#define NAND_CTR_C2			0x02000000
++#define NAND_CTR_P3			0x01000000
++#define NAND_CTR_I4			0x00800000
++#define NAND_CTR_RC			0x00400000
++#define NAND_CTR_CC			0x00200000
++#define NAND_CTR_CE			0x00100000
++#define NAND_CTR_EC_MAIN		0x00080000
++#define NAND_CTR_EC_SPARE		0x00040000
++#define NAND_CTR_EG_MAIN		0x00020000
++#define NAND_CTR_EG_SPARE		0x00010000
++#define NAND_CTR_WP			0x00000200
++#define NAND_CTR_IE			0x00000100
++#define NAND_CTR_XS			0x00000080
++#define NAND_CTR_SZ_8G			0x00000070
++#define NAND_CTR_SZ_4G			0x00000060
++#define NAND_CTR_SZ_2G			0x00000050
++#define NAND_CTR_SZ_1G			0x00000040
++#define NAND_CTR_SZ_512M		0x00000030
++#define NAND_CTR_SZ_256M		0x00000020
++#define NAND_CTR_SZ_128M		0x00000010
++#define NAND_CTR_SZ_64M			0x00000000
++#define NAND_CTR_4BANK			0x00000008
++#define NAND_CTR_2BANK			0x00000004
++#define NAND_CTR_1BANK			0x00000000
++#define NAND_CTR_WD_64BIT		0x00000003
++#define NAND_CTR_WD_32BIT		0x00000002
++#define NAND_CTR_WD_16BIT		0x00000001
++#define NAND_CTR_WD_8BIT		0x00000000
++
++#define NAND_CTR_INTLVE			0x80000000
++#define NAND_CTR_SPRBURST		0x40000000
++#define NAND_CFG_STAT_ENB		0x00002000
++#define NAND_CTR_2INTL			0x00001000
++#define NAND_CTR_K9			0x00000800
++
++#define NAND_CTR_WAS			0x00000400
++
++#define NAND_AMB_CMD_ADDR(x)		((x) << 4)
++#define NAND_AMB_CMD_NOP		0x0
++#define NAND_AMB_CMD_DMA		0x1
++#define NAND_AMB_CMD_RESET		0x2
++#define NAND_AMB_CMD_NOP2		0x3
++#define NAND_AMB_CMD_NOP3		0x4
++#define NAND_AMB_CMD_NOP4		0x5
++#define NAND_AMB_CMD_NOP5		0x6
++#define NAND_AMB_CMD_COPYBACK		0x7
++#define NAND_AMB_CMD_NOP6		0x8
++#define NAND_AMB_CMD_ERASE		0x9
++#define NAND_AMB_CMD_READID		0xa
++#define NAND_AMB_CMD_NOP7		0xb
++#define NAND_AMB_CMD_READSTATUS		0xc
++#define NAND_AMB_CMD_NOP8		0xd
++#define NAND_AMB_CMD_READ		0xe
++#define NAND_AMB_CMD_PROGRAM		0xf
++
++/* NAND_TIM0_REG (NAND mode) */
++#define NAND_TIM0_TCLS(x)		((x) << 24)
++#define NAND_TIM0_TALS(x)		((x) << 16)
++#define NAND_TIM0_TCS(x)		((x) << 8)
++#define NAND_TIM0_TDS(x)		(x)
++
++/* NAND_TIM1_REG (NAND mode) */
++#define NAND_TIM1_TCLH(x)		((x) << 24)
++#define NAND_TIM1_TALH(x)		((x) << 16)
++#define NAND_TIM1_TCH(x)		((x) << 8)
++#define NAND_TIM1_TDH(x)		(x)
++
++/* NAND_TIM2_REG (NAND mode) */
++#define NAND_TIM2_TWP(x)		((x) << 24)
++#define NAND_TIM2_TWH(x)		((x) << 16)
++#define NAND_TIM2_TWB(x)		((x) << 8)
++#define NAND_TIM2_TRR(x)		(x)
++
++/* NAND_TIM3_REG (NAND mode) */
++#define NAND_TIM3_TRP(x)		((x) << 24)
++#define NAND_TIM3_TREH(x)		((x) << 16)
++#define NAND_TIM3_TRB(x)		((x) << 8)
++#define NAND_TIM3_TCEH(x)		(x)
++
++/* NAND_TIM4_REG (NAND mode) */
++#define NAND_TIM4_TRDELAY(x)		((x) << 24)
++#define NAND_TIM4_TCLR(x)		((x) << 16)
++#define NAND_TIM4_TWHR(x)		((x) << 8)
++#define NAND_TIM4_TIR(x)		(x)
++
++/* NAND_TIM5_REG (NAND mode) */
++#define NAND_TIM5_TWW(x)		((x) << 16)
++#define NAND_TIM5_TRHZ(x)		((x) << 8)
++#define NAND_TIM5_TAR(x)		(x)
++
++/* NAND_INT_REG (NAND mode) */
++#define NAND_INT_DI			0x1
++
++/* NAND_EXT_CTR_REG */
++#define NAND_EXT_CTR_I5			0x00800000
++#define NAND_EXT_CTR_SP_2X		0x00000001
++
++/* ==========================================================================*/
++#define EC_MDSD		0	/* check main disable and spare disable */
++#define EC_MDSE		1	/* check main disable and spare enable */
++#define EC_MESD		2	/* check main enable and spare disable */
++#define EC_MESE		3	/* check main enable and spare enable */
++
++#define EG_MDSD		0	/* generate main disable and spare disable */
++#define EG_MDSE		1	/* generate main disable and spare enable */
++#define EG_MESD		2	/* generate main enable and spare disable */
++#define EG_MESE		3	/* generate main enable and spare enable */
++
++/**
++ * Define for xdhost and nand_host
++ */
++#define MAIN_ONLY		0
++#define SPARE_ONLY		1
++#define MAIN_ECC		2
++#define SPARE_ECC		3
++#define SPARE_ONLY_BURST	4
++#define SPARE_ECC_BURST		5
++
++/* ECC use bch-x bytes */
++#define NAND_ECC_BCH6_BYTES	40	/* 10Bytes/512Bytes, so 40B/2048B */
++#define NAND_ECC_BCH8_BYTES	52	/* 13Bytes/512Bytes, so 52B/2048B */
++
++
++#define FIO_DMA_CHAN		0
++#define FDMA_CTR_OFFSET		(0x300 + ((FIO_DMA_CHAN) << 4))
++#define FDMA_SRC_OFFSET		(0x304 + ((FIO_DMA_CHAN) << 4))
++#define FDMA_DST_OFFSET		(0x308 + ((FIO_DMA_CHAN) << 4))
++#define FDMA_STA_OFFSET		(0x30c + ((FIO_DMA_CHAN) << 4))
++#define FDMA_DA_OFFSET		(0x380 + ((FIO_DMA_CHAN) << 2))
++#define FDMA_INT_OFFSET		(0x3f0)
++
++#define FDMA_SPR_CNT_OFFSET	(0x200 + ((FIO_DMA_CHAN) << 4))
++#define FDMA_SPR_SRC_OFFSET	(0x204 + ((FIO_DMA_CHAN) << 4))
++#define FDMA_SPR_DST_OFFSET	(0x208 + ((FIO_DMA_CHAN) << 4))
++#define FDMA_SPR_STA_OFFSET	(0x20c + ((FIO_DMA_CHAN) << 4))
++#define FDMA_SPR_DA_OFFSET	(0x280 + ((FIO_DMA_CHAN) << 2))
++#define FDMA_DSM_CTR_OFFSET	(0x3a0 + ((FIO_DMA_CHAN) << 2))
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/pinctrl.h b/arch/arm/mach-ambarella/include/plat/pinctrl.h
+new file mode 100644
+index 00000000..3b2b24eb
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/pinctrl.h
+@@ -0,0 +1,45 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/pinctrl.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_PINCTRL_H__
++#define __PLAT_AMBARELLA_PINCTRL_H__
++
++#ifndef __ASSEMBLER__
++
++#define PINID_TO_BANK(p)	((p) >> 5)
++#define PINID_TO_OFFSET(p)	((p) & 0x1f)
++
++/* pins alternate function */
++enum amb_pin_altfunc {
++	AMB_ALTFUNC_GPIO = 0,
++	AMB_ALTFUNC_HW_1,
++	AMB_ALTFUNC_HW_2,
++	AMB_ALTFUNC_HW_3,
++	AMB_ALTFUNC_HW_4,
++	AMB_ALTFUNC_HW_5,
++};
++
++#endif /* __ASSEMBLER__ */
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/pm.h b/arch/arm/mach-ambarella/include/plat/pm.h
+new file mode 100644
+index 00000000..110b488e
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/pm.h
+@@ -0,0 +1,53 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/pm.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_PM_H
++#define __PLAT_AMBARELLA_PM_H
++
++/* ==========================================================================*/
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++
++/* ==========================================================================*/
++#ifdef CONFIG_PLAT_AMBARELLA_SUPPORT_PM
++extern int ambarella_init_pm(void);
++extern int ambarella_finish_suspend(unsigned long);
++extern void ambarella_cpu_resume(void);
++
++#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
++extern int ambarella_optimize_suspend(unsigned long);
++extern int ambarella_optimize_suspend_sz;
++#endif /* CONFIG_AMBARELLA_SREF_FIFO_EXEC */
++
++#else
++static inline int ambarella_init_pm(void){return 0;}
++#endif
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/ptb.h b/arch/arm/mach-ambarella/include/plat/ptb.h
+new file mode 100644
+index 00000000..99c4f259
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/ptb.h
+@@ -0,0 +1,166 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/ptb.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_PTB_H
++#define __PLAT_AMBARELLA_PTB_H
++
++/* ==========================================================================*/
++#define BOOT_DEV_NAND		0x1
++#define BOOT_DEV_NOR		0x2
++#define BOOT_DEV_SM		0x3
++#define BOOT_DEV_ONENAND	0x4
++#define BOOT_DEV_SNOR		0x5
++
++#define PART_DEV_AUTO		(0x00)
++#define PART_DEV_NAND		(0x01)
++#define PART_DEV_EMMC		(0x02)
++#define PART_DEV_SNOR		(0x04)
++
++#define FW_MODEL_NAME_SIZE	128
++
++#define PART_MAX_WITH_RSV	32
++
++#define PART_MAX		20
++#define CMDLINE_PART_MAX	8
++
++#define HAS_IMG_PARTS		15
++#define HAS_NO_IMG_PARTS	1
++#define TOTAL_FW_PARTS		(HAS_IMG_PARTS + HAS_NO_IMG_PARTS)
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++typedef struct flpart_s
++{
++	u32	crc32;		/**< CRC32 checksum of image */
++	u32	ver_num;	/**< Version number */
++	u32	ver_date;	/**< Version date */
++	u32	img_len;	/**< Lengh of image in the partition */
++	u32	mem_addr;	/**< Starting address to copy to RAM */
++	u32	flag;		/**< Special properties of this partition */
++	u32	magic;		/**< Magic number */
++} __attribute__((packed)) flpart_t;
++
++#define FLDEV_CMD_LINE_SIZE	1024
++
++typedef struct netdev_s
++{
++	/* This section contains networking related settings */
++	u8	mac[6];		/**< MAC address*/
++	u32	ip;		/**< Boot loader's LAN IP */
++	u32	mask;		/**< Boot loader's LAN mask */
++	u32	gw;		/**< Boot loader's LAN gateway */
++} __attribute__((packed)) netdev_t;
++
++typedef struct fldev_s
++{
++	char	sn[32];		/**< Serial number */
++	u8	usbdl_mode;	/**< USB download mode */
++	u8	auto_boot;	/**< Automatic boot */
++	u8	rsv[2];
++	u32	splash_id;
++	char	cmdline[FLDEV_CMD_LINE_SIZE];
++
++	/* This section contains networking related settings */
++	netdev_t eth[2];
++	netdev_t wifi[2];
++	netdev_t usb_eth[2];
++
++	/* This section contains update by network  related settings */
++	u32	auto_dl;	/**< Automatic download? */
++	u32	tftpd;		/**< Boot loader's TFTP server */
++	u32	pri_addr;	/**< RTOS download address */
++	char	pri_file[32];	/**< RTOS file name */
++	u32	pri_comp;	/**< RTOS compressed? */
++	u32	dtb_addr;	/**< DTB download address */
++	char	dtb_file[32];	/**< DTB file name */
++	u32	rmd_addr;	/**< Ramdisk download address */
++	char	rmd_file[32];	/**< Ramdisk file name */
++	u32	rmd_comp;	/**< Ramdisk compressed? */
++	u32	dsp_addr;	/**< DSP download address */
++	char	dsp_file[32];	/**< DSP file name */
++	u32	dsp_comp;	/**< DSP compressed? */
++
++	u32	magic;		/**< Magic number */
++} __attribute__((packed)) fldev_t;
++
++/*The header of PTB*/
++#define PTB_HEADER_SIZE		64
++#define PTB_HEADER_PAD_SIZE	(PTB_HEADER_SIZE - sizeof(u32) * 4)
++typedef struct ptb_header_s
++{
++	u32	magic;
++	u32	crc32;
++	u32	version;
++	u32	dev;
++	u8	rsv[PTB_HEADER_PAD_SIZE];
++} __attribute__((packed)) ptb_header_t;
++
++#define PTB_SIZE		4096
++#define PTB_PAD_SIZE		\
++	(PTB_SIZE - PART_MAX_WITH_RSV * sizeof(flpart_t) - sizeof(fldev_t))
++
++typedef struct flpart_table_s
++{
++	flpart_t	part[PART_MAX_WITH_RSV];/** Partitions */
++	/* ------------------------------------------ */
++	fldev_t		dev;			/**< Device properties */
++	u8		rsv[PTB_PAD_SIZE];	/**< Padding to 2048 bytes */
++} __attribute__((packed)) flpart_table_t;
++
++/**
++ * The meta data table is a region in flash after partition table.
++ * The data need by dual boot are stored.
++ */
++/* For first version of flpart_meta_t */
++#define PTB_META_MAGIC		0x33219fbd
++/* For second version of flpart_meta_t */
++#define PTB_META_MAGIC2		0x4432a0ce
++#define PTB_META_MAGIC3		0x42405891
++#define PART_NAME_LEN		8
++#define PTB_META_ACTURAL_LEN	(sizeof(u32) + (sizeof(u32) * 3 + PART_NAME_LEN) * PART_MAX + \
++				FW_MODEL_NAME_SIZE)
++#define PTB_META_SIZE		2048
++#define PTB_META_PAD_SIZE	(PTB_META_SIZE - PTB_META_ACTURAL_LEN)
++typedef struct flpart_meta_s
++{
++	u32		magic;
++	struct {
++		u32	sblk;
++		u32	nblk;
++		u32	dev;
++		char	name[PART_NAME_LEN];
++	} part_info[PART_MAX];
++	u8		model_name[FW_MODEL_NAME_SIZE];
++	u8 		rsv[PTB_META_PAD_SIZE];
++	/* This meta crc32 doesn't include itself. */
++	/* It's only calc data before this field.  */
++	u32 	crc32;
++} __attribute__((packed)) flpart_meta_t;
++
++#endif /* __ASSEMBLER__ */
++
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/pwm.h b/arch/arm/mach-ambarella/include/plat/pwm.h
+new file mode 100644
+index 00000000..a27c6b45
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/pwm.h
+@@ -0,0 +1,83 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/pwm.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_PWM_H__
++#define __PLAT_AMBARELLA_PWM_H__
++
++#if (CHIP_REV == A8)
++#define PWM_INSTANCES			0
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define PWM_INSTANCES			4
++#else
++#define PWM_INSTANCES			5
++#endif
++
++/* ==========================================================================*/
++#define PWM_OFFSET			0x8000
++#define PWM_BASE			(APB_BASE + PWM_OFFSET)
++#define PWM_REG(x)			(PWM_BASE + (x))
++
++#define STEPPER_OFFSET			0x4000
++#define STEPPER_BASE			(APB_BASE + STEPPER_OFFSET)
++#define	PWM_ST_REG(x)			(STEPPER_BASE + (x))
++
++/* ==========================================================================*/
++#define PWM_CONTROL_OFFSET		0x00
++#define	PWM_ENABLE_OFFSET		0x04
++#define PWM_MODE_OFFSET			0x08
++#define PWM_CONTROL1_OFFSET		0x0c
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define PWM_B0_ENABLE_OFFSET		0x04
++#define PWM_B1_ENABLE_OFFSET		0x0c
++#define PWM_C0_ENABLE_OFFSET		0x14
++#define PWM_C1_ENABLE_OFFSET		0x1c
++#define PWM_B0_DATA1_OFFSET		0x20
++#define PWM_B1_DATA1_OFFSET		0x24
++#define PWM_C0_DATA1_OFFSET		0x28
++#define PWM_C1_DATA1_OFFSET		0x2c
++#else
++#define PWM_B0_ENABLE_OFFSET		0x304
++#define PWM_B1_ENABLE_OFFSET		0x30c
++#define PWM_C0_ENABLE_OFFSET		0x314
++#define PWM_C1_ENABLE_OFFSET		0x31c
++#define PWM_B0_DATA1_OFFSET		0x320
++#define PWM_B1_DATA1_OFFSET		0x324
++#define PWM_C0_DATA1_OFFSET		0x328
++#define PWM_C1_DATA1_OFFSET		0x32c
++#endif
++
++#define PWM_CLK_SRC_BIT			(0x1 << 31)
++#define PWM_INV_EN_BIT			(0x1 << 31)
++#define PWM_DIVIDER_MASK		(0x7ffffffe)
++#define PWM_PWM_EN_BIT			(0x1)
++
++#define PWM_PWM_TICKS_MAX_BITS		16
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define PWM_ST_TICKS_MAX_BITS		16
++#else
++#define PWM_ST_TICKS_MAX_BITS		10
++#endif
++
++#endif /* __PLAT_AMBARELLA_PWM_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/rct.h b/arch/arm/mach-ambarella/include/plat/rct.h
+new file mode 100644
+index 00000000..9d3f5be7
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/rct.h
+@@ -0,0 +1,691 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/rct.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2013, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_RCT_H__
++#define __PLAT_AMBARELLA_RCT_H__
++
++/* ==========================================================================*/
++#define RCT_OFFSET			0x170000
++#if (CHIP_REV == A8) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define RCT_BASE			(DBGBUS_BASE + RCT_OFFSET)
++#define RCT_PHYS_BASE		(DBGBUS_PHYS_BASE + RCT_OFFSET)
++#define	RCT_BUS_BASE		DBGBUS_BASE
++#else
++#define RCT_BASE			(APB_BASE + RCT_OFFSET)
++#define RCT_PHYS_BASE		(APB_PHYS_BASE + RCT_OFFSET)
++#define	RCT_BUS_BASE		APB_BASE
++#endif
++#define RCT_REG(x)			(RCT_BASE + (x))
++
++/* ==========================================================================*/
++#define PLL_LOCK_OFFSET			0x2C
++#define SOFT_OR_DLL_RESET_OFFSET	0x68
++
++#define PLL_LOCK_REG			RCT_REG(PLL_LOCK_OFFSET)
++#define SOFT_OR_DLL_RESET_REG		RCT_REG(SOFT_OR_DLL_RESET_OFFSET)
++
++/* ==========================================================================*/
++#define FIO_RESET_OFFSET		0x74
++#define FIO_RESET_REG			RCT_REG(FIO_RESET_OFFSET)
++#define FIO_RESET_FIO_RST		0x00000008
++#define FIO_RESET_CF_RST		0x00000004
++#define FIO_RESET_XD_RST		0x00000002
++#define FIO_RESET_FLASH_RST		0x00000001
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define USBP1_CTRL_OFFSET		0x88
++#define UDC_SOFT_RESET_OFFSET		USBP1_CTRL_OFFSET
++#define UDC_SOFT_RESET_MASK		0x20000000
++#else
++#define USBC_CTRL_OFFSET		0x2cc
++#define UDC_SOFT_RESET_OFFSET		USBC_CTRL_OFFSET
++#define UDC_SOFT_RESET_MASK		0x2
++#endif
++#define UDC_SOFT_RESET_REG		RCT_REG(UDC_SOFT_RESET_OFFSET)
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define USB0_IS_HOST_MASK		0x00000020
++#else
++#define USBP0_SEL_OFFSET		0x2c0
++#define USBP0_SEL_REG			RCT_REG(USBP0_SEL_OFFSET)
++#define USB0_IS_HOST_MASK		0x00000002
++#endif
++
++/* ==========================================================================*/
++#define PLL_AUDIO_CTRL_OFFSET		0x54
++#define PLL_AUDIO_FRAC_OFFSET		0x58
++#define SCALER_AUDIO_POST_OFFSET	0x5C
++#define SCALER_AUDIO_PRE_OFFSET		0x60
++#define PLL_AUDIO_CTRL2_OFFSET		0x124
++#define PLL_AUDIO_CTRL3_OFFSET		0x12c
++
++#define PLL_AUDIO_CTRL_REG		RCT_REG(PLL_AUDIO_CTRL_OFFSET)
++#define PLL_AUDIO_FRAC_REG		RCT_REG(PLL_AUDIO_FRAC_OFFSET)
++#define SCALER_AUDIO_POST_REG		RCT_REG(SCALER_AUDIO_POST_OFFSET)
++#define SCALER_AUDIO_PRE_REG		RCT_REG(SCALER_AUDIO_PRE_OFFSET)
++#define PLL_AUDIO_CTRL2_REG		RCT_REG(PLL_AUDIO_CTRL2_OFFSET)
++#define PLL_AUDIO_CTRL3_REG		RCT_REG(PLL_AUDIO_CTRL3_OFFSET)
++
++/* ==========================================================================*/
++#define ANA_PWR_OFFSET			0x50
++#define ANA_PWR_REG			RCT_REG(ANA_PWR_OFFSET)
++#define ANA_PWR_POWER_DOWN		0x0020
++
++#define SYS_CONFIG_OFFSET		0x34
++#define SYS_CONFIG_REG			RCT_REG(SYS_CONFIG_OFFSET)
++
++#define WDT_RST_L_OFFSET		0x78
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define UNLOCK_WDT_RST_L_OFFSET		0x50
++#define UNLOCK_WDT_RST_L_VAL		0x80
++#else
++#define UNLOCK_WDT_RST_L_OFFSET		0x260
++#define UNLOCK_WDT_RST_L_VAL		0x01
++#endif
++#define WDT_RST_L_REG			RCT_REG(WDT_RST_L_OFFSET)
++#define UNLOCK_WDT_RST_L_REG		RCT_REG(UNLOCK_WDT_RST_L_OFFSET)
++
++/* ==========================================================================*/
++#define CG_UART_OFFSET			0x38
++#define CG_SSI_OFFSET			0x3C
++#define CG_MOTOR_OFFSET			0x40
++#define CG_IR_OFFSET			0x44
++#define CG_HOST_OFFSET			0x48
++#define CG_PWM_OFFSET			0x84
++#define CG_SSI2_OFFSET			0xEC
++#define CLK_REF_SSI_OFFSET		0x19c
++#define CG_SSI3_OFFSET			0x518
++#define CLK_REF_SSI3_OFFSET		0x51c
++
++#define CG_UART_REG			RCT_REG(CG_UART_OFFSET)
++#define CG_SSI_REG			RCT_REG(CG_SSI_OFFSET)
++#define CG_MOTOR_REG			RCT_REG(CG_MOTOR_OFFSET)
++#define CG_IR_REG			RCT_REG(CG_IR_OFFSET)
++#define CG_HOST_REG			RCT_REG(CG_HOST_OFFSET)
++#define CG_PWM_REG			RCT_REG(CG_PWM_OFFSET)
++#define CG_SSI2_REG			RCT_REG(CG_SSI2_OFFSET)
++#define CG_SSI3_REG			RCT_REG(CG_SSI3_OFFSET)
++#define CLK_REF_SSI_REG			RCT_REG(CLK_REF_SSI_OFFSET)
++#define CLK_REF_SSI3_REG		RCT_REG(CLK_REF_SSI3_OFFSET)
++
++#define UART_CLK_SRC_CLK_REF		0x00
++#define UART_CLK_SRC_CORE		0x01
++#define UART_CLK_SRC_IDSP		0x03
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define UART_CLK_SRC_SEL_OFFSET		0x320
++#else
++#define UART_CLK_SRC_SEL_OFFSET		0x1C8
++#endif
++#define UART_CLK_SRC_SEL_REG		RCT_REG(UART_CLK_SRC_SEL_OFFSET)
++
++/* ==========================================================================*/
++#define PLL_CORE_CTRL_OFFSET		0x00
++#define PLL_CORE_FRAC_OFFSET		0x04
++#define PLL_CORE_CTRL2_OFFSET		0x100
++#define PLL_CORE_CTRL3_OFFSET		0x104
++#define PLL_CORE_CTRL_REG		RCT_REG(PLL_CORE_CTRL_OFFSET)
++#define PLL_CORE_FRAC_REG		RCT_REG(PLL_CORE_FRAC_OFFSET)
++#define PLL_CORE_CTRL2_REG		RCT_REG(PLL_CORE_CTRL2_OFFSET)
++#define PLL_CORE_CTRL3_REG		RCT_REG(PLL_CORE_CTRL3_OFFSET)
++
++#if ((CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E))
++#define SCALER_CORE_POST_OFFSET		0x118
++#define CORE_CLK_RATIO_1X_OFFSET	0x24C
++#define SCALER_CORE_POST_REG		RCT_REG(SCALER_CORE_POST_OFFSET)
++#define CORE_CLK_RATIO_1X_REG		RCT_REG(CORE_CLK_RATIO_1X_OFFSET)
++#endif
++
++/* ==========================================================================*/
++
++#define PLL_HDMILC_CTRL_OFFSET		0x404
++#define PLL_HDMILC_FRAC_OFFSET		0x408
++#define PLL_HDMILC_CTRL2_OFFSET		0x40c
++#define PLL_HDMILC_CTRL3_OFFSET		0x410
++#define PLL_HDMILC_CTRL4_OFFSET		0x418
++#define PLL_HDMILC_CTRL_REG		RCT_REG(PLL_HDMILC_CTRL_OFFSET)
++#define PLL_HDMILC_FRAC_REG		RCT_REG(PLL_HDMILC_FRAC_OFFSET)
++#define PLL_HDMILC_CTRL2_REG		RCT_REG(PLL_HDMILC_CTRL2_OFFSET)
++#define PLL_HDMILC_CTRL3_REG		RCT_REG(PLL_HDMILC_CTRL3_OFFSET)
++#define PLL_HDMILC_CTRL4_REG		RCT_REG(PLL_HDMILC_CTRL4_OFFSET)
++
++/* ==========================================================================*/
++#define CKEN_CLUSTER_REG_OFFSET		0x8C
++#define PLL_IDSP_CTRL_OFFSET		0xE4
++#define PLL_IDSP_FRAC_OFFSET		0xE8
++#define PLL_IDSP_CTRL2_OFFSET		0x108
++#define PLL_IDSP_CTRL3_OFFSET		0x10C
++#define SCALER_IDSP_POST_OFFSET		0x1F4
++
++#define CKEN_CLUSTER_REG		RCT_REG(CKEN_CLUSTER_REG_OFFSET)
++#define PLL_IDSP_CTRL_REG		RCT_REG(PLL_IDSP_CTRL_OFFSET)
++#define PLL_IDSP_FRAC_REG		RCT_REG(PLL_IDSP_FRAC_OFFSET)
++#define PLL_IDSP_CTRL2_REG		RCT_REG(PLL_IDSP_CTRL2_OFFSET)
++#define PLL_IDSP_CTRL3_REG		RCT_REG(PLL_IDSP_CTRL3_OFFSET)
++#define SCALER_IDSP_POST_REG		RCT_REG(SCALER_IDSP_POST_OFFSET)
++
++/* ==========================================================================*/
++#define PLL_DDR_CTRL_OFFSET		0xDC
++#define PLL_DDR_FRAC_OFFSET		0xE0
++#define PLL_DDR_CTRL2_OFFSET		0x110
++#define PLL_DDR_CTRL3_OFFSET		0x114
++
++#define PLL_DDR_CTRL_REG		RCT_REG(PLL_DDR_CTRL_OFFSET)
++#define PLL_DDR_FRAC_REG		RCT_REG(PLL_DDR_FRAC_OFFSET)
++#define PLL_DDR_CTRL2_REG		RCT_REG(PLL_DDR_CTRL2_OFFSET)
++#define PLL_DDR_CTRL3_REG		RCT_REG(PLL_DDR_CTRL3_OFFSET)
++
++/* ==========================================================================*/
++#define PLL_SENSOR_CTRL_OFFSET		0x24
++#define PLL_SENSOR_FRAC_OFFSET		0x28
++#define PLL_SENSOR_CTRL2_OFFSET		0x11C
++#define PLL_SENSOR_CTRL3_OFFSET		0x120
++#define SCALER_SENSOR_PRE_OFFSET	0x4C
++#define SCALER_SENSOR_POST_OFFSET	0x30
++#define CLK_SI_INPUT_MODE_OFFSET	0xBC
++#define SCALER_SENSOR_VIN_OFFSET	0x230
++
++#define PLL_SENSOR_CTRL_REG		RCT_REG(PLL_SENSOR_CTRL_OFFSET)
++#define PLL_SENSOR_FRAC_REG		RCT_REG(PLL_SENSOR_FRAC_OFFSET)
++#define PLL_SENSOR_CTRL2_REG		RCT_REG(PLL_SENSOR_CTRL2_OFFSET)
++#define PLL_SENSOR_CTRL3_REG		RCT_REG(PLL_SENSOR_CTRL3_OFFSET)
++#define SCALER_SENSOR_PRE_REG		RCT_REG(SCALER_SENSOR_PRE_OFFSET)
++#define SCALER_SENSOR_POST_REG		RCT_REG(SCALER_SENSOR_POST_OFFSET)
++#define CLK_SI_INPUT_MODE_REG		RCT_REG(CLK_SI_INPUT_MODE_OFFSET)
++#define SCALER_SENSOR_VIN_REG		RCT_REG(SCALER_SENSOR_VIN_OFFSET)
++
++/* ==========================================================================*/
++
++#define HDMI_CLOCK_CTRL_OFFSET          0x008
++#define PLL_HDMI_CTRL_OFFSET		0x164
++#define PLL_HDMI_CTRL2_OFFSET		0x150
++#define PLL_HDMI_CTRL3_OFFSET		0x154
++#define PLL_HDMI_FRAC_OFFSET		0x168
++#define SCALER_HDMI_PRE_OFFSET		0x170
++#define SCALER_HDMI_POST_OFFSET		0x16C
++
++#define HDMI_CLOCK_CTRL_REG		RCT_REG(HDMI_CLOCK_CTRL_OFFSET)
++#define PLL_HDMI_CTRL_REG		RCT_REG(PLL_HDMI_CTRL_OFFSET)
++#define PLL_HDMI_CTRL2_REG		RCT_REG(PLL_HDMI_CTRL2_OFFSET)
++#define PLL_HDMI_CTRL3_REG		RCT_REG(PLL_HDMI_CTRL3_OFFSET)
++#define PLL_HDMI_FRAC_REG		RCT_REG(PLL_HDMI_FRAC_OFFSET)
++#define SCALER_HDMI_PRE_REG		RCT_REG(SCALER_HDMI_PRE_OFFSET)
++#define SCALER_HDMI_POST_REG		RCT_REG(SCALER_HDMI_POST_OFFSET)
++
++#define USE_CLK_SI_4_CLK_VO_OFFSET  	0xB8
++#define CLK_REF_VIDEO_EXTERNAL_OFFSET	0xAC
++
++#define USE_CLK_SI_4_CLK_VO_REG		RCT_REG(USE_CLK_SI_4_CLK_VO_OFFSET)
++#define CLK_REF_VIDEO_EXTERNAL_REG	RCT_REG(CLK_REF_VIDEO_EXTERNAL_OFFSET)
++
++/* ==========================================================================*/
++#define PLL_VIDEO_CTRL_OFFSET		0x14
++#define PLL_VIDEO_FRAC_OFFSET		0x18
++#define SCALER_VIDEO_PRE_OFFSET		0x1C
++#define SCALER_VIDEO_POST_OFFSET	0xA0
++#define PLL_VIDEO_CTRL2_OFFSET		0x130
++#define PLL_VIDEO_CTRL3_OFFSET		0x134
++#define PLL_VIDEO_CTRL_REG		RCT_REG(PLL_VIDEO_CTRL_OFFSET)
++#define PLL_VIDEO_FRAC_REG		RCT_REG(PLL_VIDEO_FRAC_OFFSET)
++#define SCALER_VIDEO_PRE_REG		RCT_REG(SCALER_VIDEO_PRE_OFFSET)
++#define SCALER_VIDEO_POST_REG		RCT_REG(SCALER_VIDEO_POST_OFFSET)
++#define PLL_VIDEO_CTRL2_REG		RCT_REG(PLL_VIDEO_CTRL2_OFFSET)
++#define PLL_VIDEO_CTRL3_REG		RCT_REG(PLL_VIDEO_CTRL3_OFFSET)
++
++#define PLL_VIDEO2_CTRL_OFFSET		0xC0
++#define PLL_VIDEO2_FRAC_OFFSET		0xC4
++#define SCALER_VIDEO2_PRE_OFFSET	0xC8
++#define SCALER_VIDEO2_POST_OFFSET	0xCC
++#define PLL_VIDEO2_CTRL2_OFFSET		0x13C
++#define PLL_VIDEO2_CTRL3_OFFSET		0x140
++#define USE_CLK_SI_4_VO2_OFFSET		0xD0
++#define USE_EXTERNAL_VD2_CLK_OFFSET	0xD4
++#define CLK_REF_VIDEO2_EXTERNAL_OFFSET	0xD8
++
++#define PLL_VIDEO2_CTRL_REG		RCT_REG(PLL_VIDEO2_CTRL_OFFSET)
++#define PLL_VIDEO2_FRAC_REG		RCT_REG(PLL_VIDEO2_FRAC_OFFSET)
++#define SCALER_VIDEO2_PRE_REG		RCT_REG(SCALER_VIDEO2_PRE_OFFSET)
++#define SCALER_VIDEO2_POST_REG		RCT_REG(SCALER_VIDEO2_POST_OFFSET)
++#define PLL_VIDEO2_CTRL2_REG		RCT_REG(PLL_VIDEO2_CTRL2_OFFSET)
++#define PLL_VIDEO2_CTRL3_REG		RCT_REG(PLL_VIDEO2_CTRL3_OFFSET)
++#define USE_CLK_SI_4_VO2_REG		RCT_REG(USE_CLK_SI_4_VO2_OFFSET)
++#define USE_EXTERNAL_VD2_CLK_REG	RCT_REG(USE_EXTERNAL_VD2_CLK_OFFSET)
++#define CLK_REF_VIDEO2_EXTERNAL_REG	RCT_REG(CLK_REF_VIDEO2_EXTERNAL_OFFSET)
++
++/* ==========================================================================*/
++#define SCALER_ARM_ASYNC_OFFSET		0x1F0
++
++#define SCALER_ARM_ASYNC_REG		RCT_REG(SCALER_ARM_ASYNC_OFFSET)
++
++/* ==========================================================================*/
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define PLL_CORTEX_CTRL_OFFSET		0x264
++#define PLL_CORTEX_FRAC_OFFSET		0x268
++#define PLL_CORTEX_CTRL2_OFFSET		0x26C
++#define PLL_CORTEX_CTRL3_OFFSET		0x270
++#else
++#define PLL_CORTEX_CTRL_OFFSET		0x2B0
++#define PLL_CORTEX_FRAC_OFFSET		0x2B4
++#define PLL_CORTEX_CTRL2_OFFSET		0x2B8
++#define PLL_CORTEX_CTRL3_OFFSET		0x2BC
++#endif
++
++#define PLL_CORTEX_CTRL_REG		RCT_REG(PLL_CORTEX_CTRL_OFFSET)
++#define PLL_CORTEX_FRAC_REG		RCT_REG(PLL_CORTEX_FRAC_OFFSET)
++#define PLL_CORTEX_CTRL2_REG		RCT_REG(PLL_CORTEX_CTRL2_OFFSET)
++#define PLL_CORTEX_CTRL3_REG		RCT_REG(PLL_CORTEX_CTRL3_OFFSET)
++
++/* ==========================================================================*/
++
++#if (CHIP_REV == S3L)
++#define ENET_CLK_SRC_SEL_OFFSET		0x544
++#define ENET_CLK_SRC_SEL_REG		RCT_REG(ENET_CLK_SRC_SEL_OFFSET)
++#elif (CHIP_REV == S2E || CHIP_REV == S2)
++#define ENET_CLK_SRC_SEL_OFFSET		0x2CC
++#define ENET_CLK_SRC_SEL_REG		RCT_REG(ENET_CLK_SRC_SEL_OFFSET)
++#else
++#define ENET_CLK_SRC_SEL_REG		0
++#endif
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define PLL_ENET_CTRL_OFFSET		0x520
++#define PLL_ENET_FRAC_OFFSET		0x524
++#define PLL_ENET_CTRL2_OFFSET		0x528
++#define PLL_ENET_CTRL3_OFFSET		0x52C
++#define SCALER_ENET_POST_OFFSET		0x534
++#endif
++#define PLL_ENET_CTRL_REG		RCT_REG(PLL_ENET_CTRL_OFFSET)
++#define PLL_ENET_FRAC_REG		RCT_REG(PLL_ENET_FRAC_OFFSET)
++#define PLL_ENET_CTRL2_REG		RCT_REG(PLL_ENET_CTRL2_OFFSET)
++#define PLL_ENET_CTRL3_REG		RCT_REG(PLL_ENET_CTRL3_OFFSET)
++#define SCALER_ENET_POST_REG		RCT_REG(SCALER_ENET_POST_OFFSET)
++
++/* ==========================================================================*/
++#define SCALER_SD48_OFFSET		0x0C
++#define SCALER_SD48_REG			RCT_REG(SCALER_SD48_OFFSET)
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define SCALER_SDIO_OFFSET		0x10
++#else
++#define SCALER_SDIO_OFFSET		0x430
++#endif
++#define SCALER_SDIO_REG			RCT_REG(SCALER_SDIO_OFFSET)
++
++#define SCALER_SDXC_OFFSET		0x434
++#define SCALER_SDXC_REG			RCT_REG(SCALER_SDXC_OFFSET)
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define PLL_SD_CTRL_OFFSET		0x4AC
++#define PLL_SD_FRAC_OFFSET		0x4B0
++#define PLL_SD_CTRL2_OFFSET		0x4B4
++#define PLL_SD_CTRL3_OFFSET		0x4B8
++#elif (CHIP_REV == S2E)
++#define SDVCO_FOR_GTX_SOURCE            0x00000010
++#define FUNC_MISC_CTRL_OFFSET           0x328
++#define PLL_SD_CTRL_OFFSET		0x354
++#define PLL_SD_FRAC_OFFSET		0x360
++#define PLL_SD_CTRL2_OFFSET		0x358
++#define PLL_SD_CTRL3_OFFSET		0x35C
++#define FUNC_MISC_CTRL_REG		RCT_REG(FUNC_MISC_CTRL_OFFSET)
++#endif
++#define PLL_SD_CTRL_REG			RCT_REG(PLL_SD_CTRL_OFFSET)
++#define PLL_SD_FRAC_REG			RCT_REG(PLL_SD_FRAC_OFFSET)
++#define PLL_SD_CTRL2_REG		RCT_REG(PLL_SD_CTRL2_OFFSET)
++#define PLL_SD_CTRL3_REG		RCT_REG(PLL_SD_CTRL3_OFFSET)
++
++#if (CHIP_REV == A5S) || (CHIP_REV == S2)
++#define SD_SOFT_PHY_SUPPORT		0
++#else
++#define SD_SOFT_PHY_SUPPORT		1
++#endif
++
++#if (SD_SOFT_PHY_SUPPORT == 1)
++#define SD_PHY_CLKOUT_BYPASS		1 << 26
++#define SD_PHY_RESET			1 << 25
++#define SD_PHY_RX_CLK_POL		1 << 19
++#define SD_PHY_DATA_CMD_BYPASS		1 << 18
++#define SD_PHY_DLL_BYPASS		1 << 17
++
++#if (CHIP_REV == S2E)
++#define SD_PHY_CTRL_0_OFFSET		0x340
++#define SD_PHY_CTRL_1_OFFSET		0x344
++#define SD_PHY_OBSV_OFFSET		0x348
++#else
++#define SD_PHY_CTRL_0_OFFSET		0x4C0
++#define SD_PHY_CTRL_1_OFFSET		0x4C4
++#define SD_PHY_OBSV_OFFSET		0x4F0
++#endif
++#define SD_PHY_CTRL_0_REG		RCT_REG(SD_PHY_CTRL_0_OFFSET)
++#define SD_PHY_CTRL_1_REG		RCT_REG(SD_PHY_CTRL_1_OFFSET)
++#define SD_PHY_OBSV_REG			RCT_REG(SD_PHY_OBSV_OFFSET)
++
++#if (CHIP_REV == S3L)
++#define SDXC_PHY_CTRL_0_OFFSET		0x4C8
++#define SDXC_PHY_CTRL_1_OFFSET		0x4CC
++#define SDXC_PHY_OBSV_OFFSET		0x4F0
++#define SDXC_PHY_CTRL_0_REG		RCT_REG(SDXC_PHY_CTRL_0_OFFSET)
++#define SDXC_PHY_CTRL_1_REG		RCT_REG(SDXC_PHY_CTRL_1_OFFSET)
++#define SDXC_PHY_OBSV_REG		RCT_REG(SDXC_PHY_OBSV_OFFSET)
++#endif
++
++#else
++#define MS_DELAY_CTRL_OFFSET		0x1D0
++#define MS_DELAY_CTRL_REG		RCT_REG(MS_DELAY_CTRL_OFFSET)
++#endif
++
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S) || (CHIP_REV == A7L) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define ADC_SOFT_RESET			0x0
++#else
++#define ADC_SOFT_RESET			0x10000
++#endif
++#define SCALER_ADC_OFFSET		0x09C
++#define SCALER_ADC_REG			RCT_REG(SCALER_ADC_OFFSET)
++
++#define ADC16_CTRL_OFFSET		0x198
++#define ADC16_CTRL_REG			RCT_REG(ADC16_CTRL_OFFSET)
++
++/* ==========================================================================*/
++#define AHB_MISC_EN_OFFSET		0x21C
++#define AHB_MISC_EN_REG			RCT_REG(AHB_MISC_EN_OFFSET)
++
++/* ==========================================================================*/
++#define IOCTRL_GPIO_OFFSET		0x1F8
++#define IOCTRL_GPIO_REG			RCT_REG(IOCTRL_GPIO_OFFSET)
++
++#define IOCTRL_MISC1_OFFSET		0x1FC
++#define IOCTRL_MISC1_REG		RCT_REG(IOCTRL_MISC1_OFFSET)
++
++#define IOCTRL_MISC2_OFFSET		0x200
++#define IOCTRL_MISC2_REG		RCT_REG(IOCTRL_MISC2_OFFSET)
++
++#define IOCTRL_SMIOA_OFFSET		0x204
++#define IOCTRL_SMIOA_REG		RCT_REG(IOCTRL_SMIOA_OFFSET)
++
++#define IOCTRL_SMIOB_OFFSET		0x208
++#define IOCTRL_SMIOB_REG		RCT_REG(IOCTRL_SMIOB_OFFSET)
++
++#define IOCTRL_SMIOC_OFFSET		0x20C
++#define IOCTRL_SMIOC_REG		RCT_REG(IOCTRL_SMIOC_OFFSET)
++
++#define IOCTRL_SMIOD_OFFSET		0x210
++#define IOCTRL_SMIOD_REG		RCT_REG(IOCTRL_SMIOD_OFFSET)
++
++#define IOCTRL_VD1_OFFSET		0x214
++#define IOCTRL_VD1_REG			RCT_REG(IOCTRL_VD1_OFFSET)
++
++#define IOCTRL_SENSOR_OFFSET		0x218
++#define IOCTRL_SENSOR_REG		RCT_REG(IOCTRL_SENSOR_OFFSET)
++
++#define IOCTRL_STRIG_OFFSET		0x250
++#define IOCTRL_STRIG_REG		RCT_REG(IOCTRL_STRIG_OFFSET)
++
++#define IOCTRL_SDXC_OFFSET		0x2F4
++#define IOCTRL_SDXC_REG			RCT_REG(IOCTRL_SDXC_OFFSET)
++
++#define SDXC_PULL_CTRL_OFFSET		0x2F8
++#define SDXC_PULL_CTRL_REG		RCT_REG(SDXC_PULL_CTRL_OFFSET)
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define IOCTRL_DRIVE_STRENGTH_3MA	0x0
++#define IOCTRL_DRIVE_STRENGTH_12MA	0x1
++#define IOCTRL_DRIVE_STRENGTH_6MA	0x2
++#define IOCTRL_DRIVE_STRENGTH_18MA	0x3
++#else
++#define IOCTRL_DRIVE_STRENGTH_2MA	0x0
++#define IOCTRL_DRIVE_STRENGTH_8MA	0x1
++#define IOCTRL_DRIVE_STRENGTH_4MA	0x2
++#define IOCTRL_DRIVE_STRENGTH_12MA	0x3
++#endif
++
++#if (CHIP_REV == A5S)
++#define GPIO_PAD_DS_SUPPORT		0
++#else
++#define GPIO_PAD_DS_SUPPORT		1
++#endif
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define GPIO_DS0_0_OFFSET		0x270
++#define GPIO_DS0_1_OFFSET		0x274
++#define GPIO_DS0_2_OFFSET		0x278
++#define GPIO_DS0_3_OFFSET		0x27C
++#define GPIO_DS0_4_OFFSET		0x280
++#define GPIO_DS1_0_OFFSET		0x284
++#define GPIO_DS1_1_OFFSET		0x288
++#define GPIO_DS1_2_OFFSET		0x28C
++#define GPIO_DS1_3_OFFSET		0x290
++#define GPIO_DS1_4_OFFSET		0x294
++#define GPIO_DS0_OFFSET(bank)		(0x270 + ((bank) * 4))
++#define GPIO_DS1_OFFSET(bank)		(0x284 + ((bank) * 4))
++
++#else
++#define GPIO_DS0_0_OFFSET		0x314
++#define GPIO_DS1_0_OFFSET		0x318
++#define GPIO_DS0_1_OFFSET		0x31C
++#define GPIO_DS1_1_OFFSET		0x320
++#define GPIO_DS0_2_OFFSET		0x324
++#define GPIO_DS1_2_OFFSET		0x328
++#define GPIO_DS0_3_OFFSET		0x32C
++#define GPIO_DS1_3_OFFSET		0x330
++#define GPIO_DS0_4_OFFSET		0x438
++#define GPIO_DS1_4_OFFSET		0x43C
++#define GPIO_DS0_5_OFFSET		0x440
++#define GPIO_DS1_5_OFFSET		0x444
++#define GPIO_DS0_6_OFFSET		0x448
++#define GPIO_DS1_6_OFFSET		0x44C
++#define GPIO_DS0_OFFSET(bank)		((bank) >= 4 ? \
++					(0x438 + (((bank) - 4) * 8)) : \
++					(0x314 + ((bank) * 8)))
++#define GPIO_DS1_OFFSET(bank)		((bank) >= 4 ? \
++					(0x438 + (((bank) - 4) * 8) + 4) : \
++					(0x314 + ((bank) * 8) + 4))
++#endif
++
++#define GPIO_DS0_0_REG			RCT_REG(GPIO_DS0_0_OFFSET)
++#define GPIO_DS1_0_REG			RCT_REG(GPIO_DS1_0_OFFSET)
++#define GPIO_DS0_1_REG			RCT_REG(GPIO_DS0_1_OFFSET)
++#define GPIO_DS1_1_REG			RCT_REG(GPIO_DS1_1_OFFSET)
++#define GPIO_DS0_2_REG			RCT_REG(GPIO_DS0_2_OFFSET)
++#define GPIO_DS1_2_REG			RCT_REG(GPIO_DS1_2_OFFSET)
++#define GPIO_DS0_3_REG			RCT_REG(GPIO_DS0_3_OFFSET)
++#define GPIO_DS1_3_REG			RCT_REG(GPIO_DS1_3_OFFSET)
++#define GPIO_DS0_4_REG			RCT_REG(GPIO_DS0_4_OFFSET)
++#define GPIO_DS1_4_REG			RCT_REG(GPIO_DS1_4_OFFSET)
++#define GPIO_DS0_5_REG			RCT_REG(GPIO_DS0_5_OFFSET)
++#define GPIO_DS1_5_REG			RCT_REG(GPIO_DS1_5_OFFSET)
++#define GPIO_DS0_6_REG			RCT_REG(GPIO_DS0_6_OFFSET)
++#define GPIO_DS1_6_REG			RCT_REG(GPIO_DS1_6_OFFSET)
++
++/* ==========================================================================*/
++#define RCT_TIMER_OFFSET		0x254
++#define RCT_TIMER_CTRL_OFFSET		0x258
++
++#define RCT_TIMER_REG			RCT_REG(RCT_TIMER_OFFSET)
++#define RCT_TIMER_CTRL_REG		RCT_REG(RCT_TIMER_CTRL_OFFSET)
++
++/* ==========================================================================*/
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define AHB_MISC_OFFSET			0x21c
++#endif
++#define AHB_MISC_REG			RCT_REG(AHB_MISC_OFFSET)
++
++/* ==========================================================================*/
++
++/* Secure and Scratchpad */
++#define AHB_SCRATCHPAD_OFFSET		0x1B000
++#define AHB_SECURE_OFFSET		0x1D000
++#define AHB_SCRATCHPAD_BASE		(AHB_BASE + AHB_SCRATCHPAD_OFFSET)
++#define AHB_SECURE_BASE			(AHB_BASE + AHB_SECURE_OFFSET)
++#define AHB_SCRATCHPAD_REG(x)		(AHB_SCRATCHPAD_BASE + (x))
++#define AHB_SECURE_REG(x)		(AHB_SECURE_BASE + (x))
++
++#if (CHIP_REV == S3L)
++#define AHBSP_PRI_IRQ_C0_OFFSET		0x38
++#define AHBSP_PRI_IRQ_C1_OFFSET		-1 /* not supported */
++#else
++#define AHBSP_PRI_IRQ_C0_OFFSET		0x3C
++#define AHBSP_PRI_IRQ_C1_OFFSET		0x40
++#endif
++#define AHBSP_PRI_IRQ_C0_REG		AHB_SCRATCHPAD_REG(AHBSP_PRI_IRQ_C0_OFFSET)
++#define AHBSP_PRI_IRQ_C1_REG		AHB_SCRATCHPAD_REG(AHBSP_PRI_IRQ_C1_OFFSET)
++
++/* ==========================================================================*/
++
++#if (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define DMA_SUPPORT_SELECT_CHANNEL	1
++#else
++#define DMA_SUPPORT_SELECT_CHANNEL	0
++#endif
++
++#if (CHIP_REV == S3)
++#define AHBSP_DMA_CHANNEL_SEL_OFFSET	0x30
++#elif (CHIP_REV == S3L)
++#define AHBSP_DMA_CHANNEL_SEL_OFFSET	0x2C
++#endif
++#define AHBSP_DMA_CHANNEL_SEL_REG	AHB_SCRATCHPAD_REG(AHBSP_DMA_CHANNEL_SEL_OFFSET)
++
++#define SSI0_TX_DMA_REQ_IDX		0
++#define SSI0_RX_DMA_REQ_IDX		1
++#define SSI1_TX_DMA_REQ_IDX		2
++#define SSI1_RX_DMA_REQ_IDX		3
++#define NOR_SPI_TX_DMA_REQ_IDX		4
++#define NOR_SPI_RX_DMA_REQ_IDX		5
++#define SSIS0_TX_DMA_REQ_IDX		6
++#define SSIS0_RX_DMA_REQ_IDX		7
++#define UART_TX_DMA_REQ_IDX		8
++#define UART_RX_DMA_REQ_IDX		9
++#define I2S_TX_DMA_REQ_IDX		10
++#define I2S_RX_DMA_REQ_IDX		11
++#define SLIM_TX_DMA_REQ_IDX		12
++#define SLIM_RX_DMA_REQ_IDX		13
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
++#define	POC_BOOT_MAP_TYPE		0
++#define POC_BOOT_FROM_MASK		0x00010500
++#define POC_BOOT_FROM_USB		0x00000000
++#define POC_BOOT_FROM_BYPASS		0x00000100
++#define POC_BOOT_FROM_NAND		0x00000400
++#define POC_BOOT_FROM_EMMC		0xFFFFFFFF /* not supported */
++#define POC_BOOT_FROM_SPINOR		0xFFFFFFFF /* not supported */
++#define POC_BOOT_FROM_HIF		0xFFFFFFFF /* not supported */
++#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define	POC_BOOT_MAP_TYPE		0
++#define POC_BOOT_FROM_MASK		0x00003140
++#define POC_BOOT_FROM_BYPASS		0x00000040
++#define POC_BOOT_FROM_USB		0x00000000
++#define POC_BOOT_FROM_NAND		0x00000100
++#define POC_BOOT_FROM_SPINOR		0x00001000 /* not supported on S2 */
++#define POC_BOOT_FROM_EMMC		0x00002000
++#define POC_BOOT_FROM_HIF		0xFFFFFFFF /* not supported */
++#elif (CHIP_REV == S3)
++#define	POC_BOOT_MAP_TYPE		1
++#define POC_BOOT_FROM_MASK		0x00000570
++#define POC_BOOT_FROM_BYPASS		0x00000100
++#define POC_BOOT_FROM_USB		0x00000400
++#define POC_BOOT_FROM_SPINOR		0x00000000
++#define POC_BOOT_FROM_NAND		0x00000010
++#define POC_BOOT_FROM_EMMC		0x00000020
++#define POC_BOOT_FROM_HIF		0x00000040
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3L)
++#define	POC_BOOT_MAP_TYPE		1
++#define POC_BOOT_FROM_MASK		0x00000530
++#define POC_BOOT_FROM_BYPASS		0x00000100
++#define POC_BOOT_FROM_USB		0x00000400
++#define POC_BOOT_FROM_SPINOR		0x00000000
++#define POC_BOOT_FROM_NAND		0x00000010
++#define POC_BOOT_FROM_EMMC		0x00000020
++#define POC_BOOT_FROM_HIF		0xFFFFFFFF /* not supported */
++#endif
++
++#define RCT_BOOT_FROM_BYPASS		0x80000000
++#define RCT_BOOT_FROM_NAND		0x00000001
++#define RCT_BOOT_FROM_USB		0x00000002
++#define RCT_BOOT_FROM_EMMC		0x00000004
++#define RCT_BOOT_FROM_SPINOR		0x00000008
++#define RCT_BOOT_FROM_HIF		0x00000010
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define SYS_CONFIG_NAND_PAGE_SIZE	0x00000020
++#define SYS_CONFIG_NAND_READ_CONFIRM	0x00000040
++#define SYS_CONFIG_NAND_ECC_BCH_EN	0x00000000
++#define SYS_CONFIG_NAND_ECC_SPARE_2X	0x00000000
++#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define SYS_CONFIG_NAND_PAGE_SIZE	0x00000010
++#define SYS_CONFIG_NAND_READ_CONFIRM	0x00000020
++#define SYS_CONFIG_NAND_ECC_BCH_EN	0x00000400
++#define SYS_CONFIG_NAND_ECC_SPARE_2X	0x00000800
++#else
++#define SYS_CONFIG_NAND_PAGE_SIZE	0x00040000
++#define SYS_CONFIG_NAND_READ_CONFIRM	0x00020000
++#define SYS_CONFIG_NAND_ECC_BCH_EN	0x00010000
++#define SYS_CONFIG_NAND_ECC_SPARE_2X	0x00008000
++#endif
++
++/* these definition are used by software */
++#define RCT_BOOT_NAND_AUTO		0x00000000
++#define RCT_BOOT_NAND_PAGE_SIZE		0x00000001
++#define RCT_BOOT_NAND_READ_CONFIRM	0x00000002
++#define RCT_BOOT_NAND_ECC_BCH_EN	0x00000004
++#define RCT_BOOT_NAND_ECC_SPARE_2X	0x00000008
++
++/* ==========================================================================*/
++#if (CHIP_REV == S2)
++#define SYS_CONFIG_MMC_HS		0x00010000
++#define SYS_CONFIG_MMC_DDR		0x00020000
++#define SYS_CONFIG_MMC_4BIT		0x00040000
++#define SYS_CONFIG_MMC_8BIT		0x00080000
++#elif (CHIP_REV == S2E)
++#define SYS_CONFIG_MMC_HS		0x00010000
++#define SYS_CONFIG_MMC_DDR		0x00000000 /* not supported */
++#define SYS_CONFIG_MMC_4BIT		0x00040000
++#define SYS_CONFIG_MMC_8BIT		0x00080000
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3)
++#define SYS_CONFIG_MMC_HS		0x00008000
++#define SYS_CONFIG_MMC_DDR		0x00004000
++#define SYS_CONFIG_MMC_4BIT		0x00020000
++#define SYS_CONFIG_MMC_8BIT		0x00010000
++#elif (CHIP_REV == S3L)
++#define SYS_CONFIG_MMC_HS		0x00000000
++#define SYS_CONFIG_MMC_DDR		0x00000000
++#define SYS_CONFIG_MMC_4BIT		0x00010000
++#define SYS_CONFIG_MMC_8BIT		0x00008000
++#else
++#define SYS_CONFIG_MMC_HS		0x00000000
++#define SYS_CONFIG_MMC_DDR		0x00000000
++#define SYS_CONFIG_MMC_4BIT		0x00000000
++#define SYS_CONFIG_MMC_8BIT		0x00000000
++#endif
++
++/* these definition are used by software */
++#define RCT_BOOT_EMMC_AUTO		0x00000000
++#define RCT_BOOT_EMMC_HS		0x00000001
++#define RCT_BOOT_EMMC_DDR		0x00000002
++#define RCT_BOOT_EMMC_4BIT		0x00000004
++#define RCT_BOOT_EMMC_8BIT		0x00000008
++
++#endif /* __PLAT_AMBARELLA_RCT_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/remoteproc.h b/arch/arm/mach-ambarella/include/plat/remoteproc.h
+new file mode 100644
+index 00000000..a59d09b5
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/remoteproc.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/remoteproc.h
++ *
++ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
++ *
++ * Copyright (C) 2012-2012, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_REMOTEPROC_H
++#define __PLAT_AMBARELLA_REMOTEPROC_H
++
++#include <linux/remoteproc.h>
++
++struct ambarella_rproc_pdata {
++	const char *name;
++	struct rproc *rproc;
++	const char *firmware;
++	int svq_tx_irq;
++	int svq_rx_irq;
++	int rvq_tx_irq;
++	int rvq_rx_irq;
++	const struct rproc_ops *ops;
++	unsigned long buf_addr_pa;
++	struct work_struct svq_work;
++	struct work_struct rvq_work;
++	struct resource_table *(*gen_rsc_table)(int *tablesz);
++};
++
++#endif /* __PLAT_AMBARELLA_REMOTEPROC_H */
+diff --git a/arch/arm/mach-ambarella/include/plat/remoteproc_cfg.h b/arch/arm/mach-ambarella/include/plat/remoteproc_cfg.h
+new file mode 100644
+index 00000000..873ef038
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/remoteproc_cfg.h
+@@ -0,0 +1,125 @@
++/**
++ * History:
++ *    2012/09/17 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __PLAT_AMBARELLA_REMOTEPROC_CFG_H
++#define __PLAT_AMBARELLA_REMOTEPROC_CFG_H
++
++
++/*
++ * [Copy from the virtio_ring.h]
++ *
++ * The standard layout for the ring is a continuous chunk of memory which looks
++ * like this.  We assume num is a power of 2.
++ *
++ * struct vring
++ * {
++ *	// The actual descriptors (16 bytes each)
++ *	struct vring_desc desc[num];
++ *
++ *	// A ring of available descriptor heads with free-running index.
++ *	__u16 avail_flags;
++ *	__u16 avail_idx;
++ *	__u16 available[num];
++ *	__u16 used_event_idx;
++ *
++ *	// Padding to the next align boundary.
++ *	char pad[];
++ *
++ *	// A ring of used descriptor heads with free-running index.
++ *	__u16 used_flags;
++ *	__u16 used_idx;
++ *	struct vring_used_elem used[num];
++ *	__u16 avail_event_idx;
++ * };
++ */
++
++/*
++ * Calculation of memory usage for a descriptior rings with n buffers:
++ *
++ *   (16 * n) + 2 + 2 + (2 * n) + PAD + 2 + 2 + (8 * n) + 2
++ *
++ *   = (26 * n) + 10 + PAD( < 4K)
++ *
++ * EX:
++ *   A RPMSG bus with 4096 buffers has two descriptor rings with 2048
++ *   descriptors each. And each of the them needs:
++ *
++ *   26 * 2K + 10 + 4K = 56 K + 10 bytes
++ */
++
++#define RPMSG_VRING_BASE		(CONFIG_RPMSG_VRING_BASE)
++#define RPMSG_NUM_BUFS			(CONFIG_RPMSG_NUM_BUFS)
++#define RPMSG_BUF_SIZE			(CONFIG_RPMSG_BUF_SIZE)
++
++#define RPMSG_TOTAL_BUF_SPACE		(RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
++
++#ifdef CONFIG_MACH_GINKGO
++
++#define VRING_C0_TO_C1			(0x21000000)
++#define VRING_C1_TO_C0			(0x21020000)
++#define VRING_C0_AND_C1_BUF		(0x20000000)
++#define VRING_IRQ_C0_TO_C1_KICK		(106)
++#define VRING_IRQ_C0_TO_C1_ACK		(107)
++#define VRING_IRQ_C1_TO_C0_KICK		(108)
++#define VRING_IRQ_C1_TO_C0_ACK		(109)
++
++#elif defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1)
++/*
++ * On A8, we allocate 4096 4K-byte buffers for each RPMSG bus.
++ * The buffers are partitioned into two dedicated halves for TX and RX.
++ * Besides the 16 MB buffer space, each RPMSG bus also requires two
++ * descriptor rings with 56 KB each.
++ *
++ * Two make it simple for the configuration and debugging,
++ * we allocate 64 MB in total for the 3 RPMSG buses.
++ * The first 16 MB are used for the 3 * 2 descrpitor rings.
++ * And the reset of 48 MB are partitioned for the 3 buses.
++ */
++#define VRING_CA9_B_TO_A		(RPMSG_VRING_BASE + 0x00000000)
++#define VRING_CA9_A_TO_B		(RPMSG_VRING_BASE + 0x00010000)
++
++#define VRING_ARM11_TO_CA9_A		(RPMSG_VRING_BASE + 0x00020000)
++#define VRING_CA9_A_TO_ARM11		(RPMSG_VRING_BASE + 0x00030000)
++
++#define VRING_ARM11_TO_CA9_B		(RPMSG_VRING_BASE + 0x00040000)
++#define VRING_CA9_B_TO_ARM11		(RPMSG_VRING_BASE + 0x00050000)
++
++#define VRING_BUF_CA9_A_AND_B		(RPMSG_VRING_BASE + RPMSG_TOTAL_BUF_SPACE * 1)
++
++#define VRING_BUF_CA9_A_AND_ARM11	(RPMSG_VRING_BASE + RPMSG_TOTAL_BUF_SPACE * 2)
++
++#define VRING_BUF_CA9_B_AND_ARM11	(RPMSG_VRING_BASE + RPMSG_TOTAL_BUF_SPACE * 3)
++
++#define VRING_CA9_A_TO_B_CLNT_IRQ	(106)
++#define VRING_CA9_A_TO_B_HOST_IRQ	(107)
++
++#define VRING_CA9_B_TO_A_CLNT_IRQ	(108)
++#define VRING_CA9_B_TO_A_HOST_IRQ	(109)
++
++#define VRING_CA9_A_TO_ARM11_CLNT_IRQ	(110)
++#define VRING_CA9_A_TO_ARM11_HOST_IRQ	(111)
++
++#define VRING_ARM11_TO_CA9_A_CLNT_IRQ	(112)
++#define VRING_ARM11_TO_CA9_A_HOST_IRQ	(113)
++
++#define VRING_CA9_B_TO_ARM11_CLNT_IRQ	(114)
++#define VRING_CA9_B_TO_ARM11_HOST_IRQ	(115)
++
++#define VRING_ARM11_TO_CA9_B_CLNT_IRQ	(116)
++#define VRING_ARM11_TO_CA9_B_HOST_IRQ	(117)
++#endif /* CONFIG_MACH_XXX */
++
++#endif /* __PLAT_AMBARELLA_REMOTEPROC_CFG_H */
+diff --git a/arch/arm/mach-ambarella/include/plat/rpdev.h b/arch/arm/mach-ambarella/include/plat/rpdev.h
+new file mode 100644
+index 00000000..d8a4ce12
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/rpdev.h
+@@ -0,0 +1,68 @@
++/**
++ * system/src/rpclnt/rpdev.h
++ *
++ * History:
++ *    2012/08/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __RPDEV_H__
++#define __RPDEV_H__
++
++#define RPMSG_VRING_ALIGN		(4096)
++#define RPMSG_RESERVED_ADDRESSES	(1024)
++#define RPMSG_ADDRESS_ANY		(0xffffffff)
++#define RPMSG_NS_ADDR			(53)
++#define RPMSG_NAME_LEN			(32)
++
++#if defined (__KERNEL__)
++#include <plat/remoteproc_cfg.h>
++#include <linux/sched.h>
++#include <linux/rpmsg.h>
++#else
++#include "rpmsg.h"
++#endif
++
++struct rpdev;
++typedef void (*rpdev_cb)(struct rpdev* rpdev, void *data, int len,
++			 void *priv, u32 src);
++struct rpdev {
++
++#if defined(__KERNEL__)
++	struct completion	comp;
++#else
++	ID			flgid;
++#endif
++
++	struct rpclnt		*rpclnt;
++	char			name[RPMSG_NAME_LEN];
++	u32     		src;
++	u32     		dst;
++	u32			flags;
++
++	rpdev_cb		cb;
++	void			*priv;
++};
++
++extern int rpdev_register(struct rpdev *rpdev, const char *bus_name);
++
++extern struct rpdev *rpdev_alloc(const char *name, int flags,
++                                 rpdev_cb cb, void *priv);
++
++extern int rpdev_send_offchannel(struct rpdev *rpdev, u32 src, u32 dst,
++                                 void *data, int len);
++
++extern int rpdev_send(struct rpdev *rpdev, void *data, int len);
++extern int rpdev_trysend(struct rpdev *rpdev, void *data, int len);
++
++#endif /* __RPDEV_H__ */
+diff --git a/arch/arm/mach-ambarella/include/plat/rtc.h b/arch/arm/mach-ambarella/include/plat/rtc.h
+new file mode 100644
+index 00000000..6d7c638f
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/rtc.h
+@@ -0,0 +1,98 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/rtc.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_RTC_H__
++#define __PLAT_AMBARELLA_RTC_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define RTC_SUPPORT_30BITS_PASSED_SECONDS	1
++#else
++#define RTC_SUPPORT_30BITS_PASSED_SECONDS	0
++#endif
++
++#if (CHIP_REV == A5S)
++#define RTC_POWER_LOST_DETECT			0
++#else
++#define RTC_POWER_LOST_DETECT			1
++#endif
++
++/* ==========================================================================*/
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define RTC_OFFSET			0x15000
++#else
++#define RTC_OFFSET			0xD000
++#endif
++#define RTC_BASE			(APB_BASE + RTC_OFFSET)
++#define RTC_REG(x)			(RTC_BASE + (x))
++
++/* ==========================================================================*/
++#define RTC_POS0_OFFSET			0x20
++#define RTC_POS1_OFFSET			0x24
++#define RTC_POS2_OFFSET			0x28
++#define RTC_PWC_ALAT_OFFSET		0x2C
++#define RTC_PWC_CURT_OFFSET		0x30
++#define RTC_CURT_OFFSET			0x34
++#define RTC_ALAT_OFFSET			0x38
++#define RTC_STATUS_OFFSET		0x3C
++#define RTC_RESET_OFFSET		0x40
++#define RTC_WO_OFFSET			0x7C
++
++#define RTC_PWC_DNALERT_OFFSET		0xA8
++#define RTC_PWC_LBAT_OFFSET		0xAC
++#define RTC_PWC_REG_WKUPC_OFFSET	0xB0
++#define RTC_PWC_REG_STA_OFFSET		0xB4
++#define RTC_PWC_SET_STATUS_OFFSET	0xC0
++#define RTC_PWC_CLR_REG_WKUPC_OFFSET	0xC4
++#define RTC_PWC_WKENC_OFFSET		0xC8
++#define RTC_POS3_OFFSET			0xD0
++
++#define RTC_PWC_ENP1C_OFFSET		0xD4
++#define RTC_PWC_ENP2C_OFFSET		0xD8
++#define RTC_PWC_ENP3C_OFFSET		0xDC
++#define RTC_PWC_ENP1_OFFSET		0xE0
++#define RTC_PWC_ENP2_OFFSET		0xE4
++#define RTC_PWC_ENP3_OFFSET		0xE8
++#define RTC_PWC_DISP1C_OFFSET		0xEC
++#define RTC_PWC_DISP2C_OFFSET		0xF0
++#define RTC_PWC_DISP3C_OFFSET		0xF4
++#define RTC_PWC_DISP1_OFFSET		0xF8
++#define RTC_PWC_DISP2_OFFSET		0xB8
++#define RTC_PWC_DISP3_OFFSET		0xBC
++
++/* ==========================================================================*/
++/* RTC_STATUS_OFFSET */
++#define RTC_STATUS_WKUP			0x8
++#define RTC_STATUS_ALA_WK		0x4
++#define RTC_STATUS_PC_RST		0x2
++#define RTC_STATUS_RTC_CLK		0x1
++
++/* RTC_PWC_REG_STA_OFFSET */
++#define RTC_PWC_LOSS_MASK		0x20
++#define RTC_PWC_ALARM_MASK		0x8
++#define RTC_PWC_SR_MASK			0x4
++
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_RTC_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/sd.h b/arch/arm/mach-ambarella/include/plat/sd.h
+new file mode 100644
+index 00000000..f6561d10
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/sd.h
+@@ -0,0 +1,384 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/sd.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_SD_H__
++#define __PLAT_AMBARELLA_SD_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A7L) || (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == S3L)
++#define SD_INSTANCES			2
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3)
++#define SD_INSTANCES			3
++#else
++#define SD_INSTANCES			1
++#endif
++
++#if (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3)
++#define SD_SUPPORT_SDIO			1
++#else
++#define SD_SUPPORT_SDIO			0
++#endif
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define SD_SUPPORT_SDXC			1
++#else
++#define SD_SUPPORT_SDXC			0
++#endif
++
++/* ==========================================================================*/
++#define SD0_OFFSET			0x2000
++#define SD1_OFFSET			0xC000
++#define SD2_OFFSET			0x1F000
++
++#define SD0_BASE			(AHB_BASE + SD0_OFFSET)
++#define SD1_BASE			(AHB_BASE + SD1_OFFSET)
++#define SD2_BASE			(AHB_BASE + SD2_OFFSET)
++#define SD_BASE(id)			((id == 0) ? SD0_BASE : \
++					 (id == 1) ? SD1_BASE : SD2_BASE)
++
++#define SD0_REG(x)			(SD0_BASE + (x))
++#define SD2_REG(x)			(SD1_BASE + (x))
++#define SD3_REG(x)			(SD2_BASE + (x))
++
++/* ==========================================================================*/
++#define SD_DMA_ADDR_OFFSET		0x000
++#define SD_BLK_SZ_OFFSET		0x004	/* Half word */
++#define SD_BLK_CNT_OFFSET		0x006	/* Half word */
++#define SD_ARG_OFFSET			0x008
++#define SD_XFR_OFFSET			0x00C	/* Half word */
++#define SD_CMD_OFFSET			0x00E	/* Half word */
++#define SD_RSP0_OFFSET			0x010
++#define SD_RSP1_OFFSET			0x014
++#define SD_RSP2_OFFSET			0x018
++#define SD_RSP3_OFFSET			0x01C
++#define SD_DATA_OFFSET			0x020
++#define SD_STA_OFFSET			0x024
++#define SD_HOST_OFFSET			0x028	/* Byte */
++#define SD_PWR_OFFSET			0x029	/* Byte */
++#define SD_GAP_OFFSET			0x02A	/* Byte */
++#define SD_WAK_OFFSET			0x02B	/* Byte */
++#define SD_CLK_OFFSET			0x02C	/* Half word */
++#define SD_TMO_OFFSET			0x02E	/* Byte */
++#define SD_RESET_OFFSET			0x02F	/* Byte */
++#define SD_NIS_OFFSET			0x030	/* Half word */
++#define SD_EIS_OFFSET			0x032	/* Half word */
++#define SD_NISEN_OFFSET			0x034	/* Half word */
++#define SD_EISEN_OFFSET			0x036	/* Half word */
++#define SD_NIXEN_OFFSET			0x038	/* Half word */
++#define SD_EIXEN_OFFSET			0x03A	/* Half word */
++#define SD_AC12ES_OFFSET		0x03C	/* Half word */
++#define SD_HOST2_OFFSET			0x03E	/* Half word */
++#define SD_CAP_OFFSET			0x040
++#define SD_CUR_OFFSET			0x048
++#define SD_ADMA_STA_OFFSET		0x054
++#define SD_ADMA_ADDR_OFFSET		0x058
++#define SD_XC_CTR_OFFSET		0x060
++#define SD_BOOT_CTR_OFFSET		0x070
++#define SD_BOOT_STA_OFFSET		0x074
++#define SD_VOL_SW_OFFSET		0x07C
++#define SD_DELAY_SEL_L			0x0D8
++#define SD_DELAY_SEL_H			0x0DC
++#define SD_LAT_CTRL_OFFSET		0x0F8
++#define SD_SIST_OFFSET			0x0FC	/* Half word */
++#define SD_VER_OFFSET			0x0FE	/* Half word */
++
++/* SD_BLK_SZ_REG */
++#define SD_BLK_SZ_4KB			0x0000
++#define SD_BLK_SZ_8KB			0x1000
++#define SD_BLK_SZ_16KB			0x2000
++#define SD_BLK_SZ_32KB			0x3000
++#define SD_BLK_SZ_64KB			0x4000
++#define SD_BLK_SZ_128KB			0x5000
++#define SD_BLK_SZ_256KB			0x6000
++#define SD_BLK_SZ_512KB			0x7000
++
++/* SD_XFR_REG */
++#define SD_XFR_MUL_SEL			0x0020
++#define SD_XFR_SGL_SEL			0x0000
++#define SD_XFR_CTH_SEL			0x0010
++#define SD_XFR_HTC_SEL			0x0000
++#define SD_XFR_AC12_EN			0x0004
++#define SD_XFR_BLKCNT_EN		0x0002
++#define SD_XFR_DMA_EN			0x0001
++
++/* SD_CMD_REG */
++#define SD_CMD_IDX(x)			((x) << 8)
++#define SD_CMD_NORMAL			0x00000000
++#define SD_CMD_SUSPEND			0x00000040
++#define SD_CMD_RESUME			0x00000080
++#define SD_CMD_ABORT			0x000000C0
++#define SD_CMD_DATA			0x00000020
++#define SD_CMD_CHKIDX			0x00000010
++#define SD_CMD_CHKCRC			0x00000008
++#define SD_CMD_RSP_NONE			0x00000000
++#define SD_CMD_RSP_136			0x00000001
++#define SD_CMD_RSP_48			0x00000002
++#define SD_CMD_RSP_48BUSY		0x00000003
++
++/* SD_STA_REG */
++#define SD_STA_DAT_LSL(x)		((((x) & 0x1e000000) >> 25) | \
++					 (((x) & 0x00f00000) >> 20))
++#define SD_STA_CMD_LSL(x)		(((x)  & 0x01000000) >> 24)
++#define SD_STA_WPS_PL			0x00080000
++#define SD_STA_CDP_L			0x00040000
++#define SD_STA_CSS			0x00020000
++#define SD_STA_CARD_INSERTED		0x00010000
++#define SD_STA_BUFFER_READ_EN		0x00000800
++#define SD_STA_BUFFER_WRITE_EN		0x00000400
++#define SD_STA_READ_XFR_ACTIVE		0x00000200
++#define SD_STA_WRITE_XFR_ACTIVE		0x00000100
++#define SD_STA_DAT_ACTIVE		0x00000004
++#define SD_STA_CMD_INHIBIT_DAT		0x00000002
++#define SD_STA_CMD_INHIBIT_CMD		0x00000001
++
++/* SD_HOST_REG */
++#define SD_HOST_ADMA			0x10
++#define SD_HOST_8BIT			0x08
++#define SD_HOST_HIGH_SPEED		0x04
++#define SD_HOST_4BIT			0x02
++#define SD_HOST_LED_ON			0x01
++
++/* SD_PWR_REG */
++#if (CHIP_REV == A5S)
++#define SD_PWR_3_3V			0x0e
++#define SD_PWR_3_0V			0x0c
++#define SD_PWR_1_8V			0x0a
++#else
++/* SD_PWR_REG only care about bit[3] */
++#define SD_PWR_3_3V			0x08
++#define SD_PWR_3_0V			0x08
++#define SD_PWR_1_8V			0x00
++#endif
++
++#define SD_PWR_ON			0x01
++#define SD_PWR_OFF			0x00
++
++/* SD_GAP_REG */
++#define SD_GAP_INT_AT_GAP		0x08
++#define SD_GAP_READ_WAIT		0x04
++#define SD_GAP_CONT_REQ			0x02
++#define SD_GAP_STOP_AT_GAP		0x01
++
++/* SD_WAK_REG */
++#define SD_WAK_ON_CARD_RMV		0x04
++#define SD_WAK_ON_CARD_IST		0x02
++#define SD_WAK_ON_CARD_INT		0x01
++
++/* SD_CLK_REG */
++#define SD_CLK_DIV_256			0x8000
++#define SD_CLK_DIV_128			0x4000
++#define SD_CLK_DIV_64			0x2000
++#define SD_CLK_DIV_32			0x1000
++#define SD_CLK_DIV_16			0x0800
++#define SD_CLK_DIV_8			0x0400
++#define SD_CLK_DIV_4			0x0200
++#define SD_CLK_DIV_2			0x0100
++#define SD_CLK_DIV_1			0x0000
++#define SD_CLK_EN			0x0004
++#define SD_CLK_ICLK_STABLE		0x0002
++#define SD_CLK_ICLK_EN			0x0001
++
++/* SD_TMO_REG */
++
++/* SD_RESET_REG */
++#define SD_RESET_DAT			0x04
++#define SD_RESET_CMD			0x02
++#define SD_RESET_ALL			0x01
++
++/* SD_NIS_REG */
++#define SD_NIS_ERROR			0x8000
++#define SD_NIS_CARD			0x0100
++#define SD_NIS_REMOVAL			0x0080
++#define SD_NIS_INSERT			0x0040
++#define SD_NIS_READ_READY		0x0020
++#define SD_NIS_WRITE_READY		0x0010
++#define SD_NIS_DMA			0x0008
++#define SD_NIS_BLOCK_GAP		0x0004
++#define SD_NIS_XFR_DONE			0x0002
++#define SD_NIS_CMD_DONE			0x0001
++
++/* SD_EIS_REG */
++#define SD_EIS_ADMA_ERR			0x0200
++#define SD_EIS_ACMD12_ERR		0x0100
++#define SD_EIS_CURRENT_ERR		0x0080
++#define SD_EIS_DATA_BIT_ERR		0x0040
++#define SD_EIS_DATA_CRC_ERR		0x0020
++#define SD_EIS_DATA_TMOUT_ERR		0x0010
++#define SD_EIS_CMD_IDX_ERR		0x0008
++#define SD_EIS_CMD_BIT_ERR		0x0004
++#define SD_EIS_CMD_CRC_ERR		0x0002
++#define SD_EIS_CMD_TMOUT_ERR		0x0001
++
++/* SD_NISEN_REG */
++#define SD_NISEN_CARD			0x0100
++#define SD_NISEN_REMOVAL		0x0080
++#define SD_NISEN_INSERT			0x0040
++#define SD_NISEN_READ_READY		0x0020
++#define SD_NISEN_WRITE_READY		0x0010
++#define SD_NISEN_DMA			0x0008
++#define SD_NISEN_BLOCK_GAP		0x0004
++#define SD_NISEN_XFR_DONE		0x0002
++#define SD_NISEN_CMD_DONE		0x0001
++
++/* SD_EISEN_REG */
++#define SD_EISEN_ADMA_ERR		0x0200
++#define SD_EISEN_ACMD12_ERR		0x0100
++#define SD_EISEN_CURRENT_ERR		0x0080
++#define SD_EISEN_DATA_BIT_ERR		0x0040
++#define SD_EISEN_DATA_CRC_ERR		0x0020
++#define SD_EISEN_DATA_TMOUT_ERR		0x0010
++#define SD_EISEN_CMD_IDX_ERR		0x0008
++#define SD_EISEN_CMD_BIT_ERR		0x0004
++#define SD_EISEN_CMD_CRC_ERR		0x0002
++#define SD_EISEN_CMD_TMOUT_ERR		0x0001
++
++/* SD_NIXEN_REG */
++#define SD_NIXEN_CARD			0x0100
++#define SD_NIXEN_REMOVAL		0x0080
++#define SD_NIXEN_INSERT			0x0040
++#define SD_NIXEN_READ_READY		0x0020
++#define SD_NIXEN_WRITE_READY		0x0010
++#define SD_NIXEN_DMA			0x0008
++#define SD_NIXEN_BLOCK_GAP		0x0004
++#define SD_NIXEN_XFR_DONE		0x0002
++#define SD_NIXEN_CMD_DONE		0x0001
++
++/* SD_EIXEN_REG */
++#define SD_EIXEN_ADMA_ERR		0x0200
++#define SD_EIXEN_ACMD12_ERR		0x0100
++#define SD_EIXEN_CURRENT_ERR		0x0080
++#define SD_EIXEN_DATA_BIT_ERR		0x0040
++#define SD_EIXEN_DATA_CRC_ERR		0x0020
++#define SD_EIXEN_DATA_TMOUT_ERR		0x0010
++#define SD_EIXEN_CMD_IDX_ERR		0x0008
++#define SD_EIXEN_CMD_BIT_ERR		0x0004
++#define SD_EIXEN_CMD_CRC_ERR		0x0002
++#define SD_EIXEN_CMD_TMOUT_ERR		0x0001
++
++/* SD_AC12ES_REG */
++#if (CHIP_REV == A5S)
++#define SD_AC12ES_NOT_ISSUED		0x0040
++#define SD_AC12ES_INDEX			0x0020
++#define SD_AC12ES_END_BIT		0x0010
++#else
++#define SD_AC12ES_NOT_ISSUED		0x0080
++#define SD_AC12ES_INDEX			0x0010
++#define SD_AC12ES_END_BIT		0x0008
++#endif
++#define SD_AC12ES_CRC_ERROR		0x0004
++#define SD_AC12ES_TMOUT_ERROR		0x0002
++#define SD_AC12ES_NOT_EXECED		0x0001
++
++/* SD_ADMA_STA_REG */
++#define SD_ADMA_STA_ST_STOP		0x00000000
++#define SD_ADMA_STA_ST_FDS		0x00000001
++#define SD_ADMA_STA_ST_TFR		0x00000003
++#define SD_ADMA_STA_LEN_ERR		0x00000004
++
++/* SD_CAP_REG */
++#define SD_CAP_INTMODE			0x08000000
++#define SD_CAP_VOL_1_8V			0x04000000
++#define SD_CAP_VOL_3_0V			0x02000000
++#define SD_CAP_VOL_3_3V			0x01000000
++#define SD_CAP_SUS_RES			0x00800000
++#define SD_CAP_DMA			0x00400000
++#define SD_CAP_HIGH_SPEED		0x00200000
++#define SD_CAP_ADMA_SUPPORT		0x00080000
++#define SD_CAP_MAX_512B_BLK		0x00000000
++#define SD_CAP_MAX_1KB_BLK		0x00010000
++#define SD_CAP_MAX_2KB_BLK		0x00020000
++#define SD_CAP_BASE_FREQ(x)		(((x) & 0x3f00) >> 8)
++#define SD_CAP_TOCLK_KHZ		0x00000000
++#define SD_CAP_TOCLK_MHZ		0x00000080
++#define SD_CAP_TOCLK_FREQ(x)		(((x) & 0x3f))
++
++/* SD_XC_CTR_REG */
++#define SD_XC_CTR_DDR_EN		0x00008000
++#define SD_XC_CTR_VOL_1_8V		0x00000001
++#define SD_XC_CTR_VOL_3_3V		0x00000000
++
++/* SD_BOOT_CTR_REG */
++#define SD_BOOT_CTR_RST_EN		0x00010000
++
++/* SD_BOOT_STA_REG */
++#define SD_BOOT_STA_END_ALT		0x01010000
++#define SD_BOOT_STA_BOOT_RDY		0x00000001
++
++/* SD_VOL_SW_REG */
++#define SD_VOL_SW_CMD_STAT_H		0x00010000
++#define SD_VOL_SW_DAT_STAT_H		0x00000007
++
++/* SD_VER_REG */
++#define SD_VER_VENDOR(x)		((x) >> 8)
++#define SD_VER_SPEC(x)			((x) & 0xf)
++
++#define SD_ADMA_TBL_LINE_SIZE		(8)
++#define SD_ADMA_TBL_LINE_MAX_LEN	(0x40000)
++#define SD_ADMA_TBL_ATTR_NOP		(0x0000)
++#define SD_ADMA_TBL_ATTR_RSV		(0x0010)
++#define SD_ADMA_TBL_ATTR_TRAN		(0x0020)
++#define SD_ADMA_TBL_ATTR_LINK		(0x0030)
++#define SD_ADMA_TBL_ATTR_WORD		(0x0008)
++#define SD_ADMA_TBL_ATTR_INT		(0x0004)
++#define SD_ADMA_TBL_ATTR_END		(0x0002)
++#define SD_ADMA_TBL_ATTR_VALID		(0x0001)
++
++/* ==========================================================================*/
++#define SMIO_2				GPIO(64)
++#define SMIO_3				GPIO(65)
++#define SMIO_4				GPIO(66)
++#define SMIO_5				GPIO(67)
++#define SD1_CD				GPIO(67)
++#define SMIO_6				GPIO(68)
++#define SMIO_38				GPIO(69)
++#define SMIO_39				GPIO(70)
++#define SMIO_40				GPIO(71)
++#define SMIO_41				GPIO(72)
++#define SMIO_42				GPIO(73)
++#define SMIO_43				GPIO(74)
++#define SMIO_44				GPIO(75)
++#define SMIO_45				GPIO(76)
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define AMBA_SD_MAX_SLOT_NUM		(2)
++#else
++#define AMBA_SD_MAX_SLOT_NUM		(1)
++#endif
++
++#if (CHIP_REV == S3L)
++#define sd_slot_is_valid(slot)		((slot) == 0 || (slot) == 2)
++#else
++#define sd_slot_is_valid(slot)		((slot) < SD_INSTANCES)
++#endif
++
++#if (CHIP_REV == A5S) || (CHIP_REV == A7L) || (CHIP_REV == S2)
++#define sd_addr_is_unlign(addr)		((addr) & 0x3)
++#else
++#define sd_addr_is_unlign(addr)		0
++#endif
++
++#endif
++
++extern void ambarella_detect_sd_slot(int slotid, int fixed_cd);
++
+diff --git a/arch/arm/mach-ambarella/include/plat/spi.h b/arch/arm/mach-ambarella/include/plat/spi.h
+new file mode 100644
+index 00000000..e04a18fc
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/spi.h
+@@ -0,0 +1,319 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/spi.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_SPI_H__
++#define __PLAT_AMBARELLA_SPI_H__
++
++#include <linux/spi/spi.h>
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define SPI_INSTANCES				2
++#define SPI_AHB_INSTANCES			0
++#define SPI_SLAVE_INSTANCES			1
++#define SPI_AHB_SLAVE_INSTANCES			0
++#elif (CHIP_REV == S2)
++#ifdef CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64
++#define SPI_INSTANCES				2
++#else
++#define SPI_INSTANCES				1
++#endif
++#define SPI_AHB_INSTANCES			0
++#define SPI_SLAVE_INSTANCES			1
++#define SPI_AHB_SLAVE_INSTANCES			0
++#elif (CHIP_REV == S2E)
++#define SPI_INSTANCES				1
++#define SPI_AHB_INSTANCES			1
++#define SPI_SLAVE_INSTANCES			1
++#define SPI_AHB_SLAVE_INSTANCES			0
++#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define SPI_INSTANCES				0
++#define SPI_AHB_INSTANCES			2
++#define SPI_SLAVE_INSTANCES			0
++#define SPI_AHB_SLAVE_INSTANCES			1
++#elif (CHIP_REV == A7L)
++#define SPI_INSTANCES				1
++#define SPI_AHB_INSTANCES			0
++#define SPI_SLAVE_INSTANCES			1
++#define SPI_AHB_SLAVE_INSTANCES			0
++#else
++#define SPI_INSTANCES				1
++#define SPI_AHB_INSTANCES			0
++#define SPI_SLAVE_INSTANCES			0
++#define SPI_AHB_SLAVE_INSTANCES			0
++#endif
++
++#if (CHIP_REV == A5S)
++#define SPI_SUPPORT_MASTER_CHANGE_ENA_POLARITY	0
++#define SPI_SUPPORT_MASTER_DELAY_START_TIME	0
++#define SPI_SUPPORT_NSM_SHAKE_START_BIT_CHSANGE	0
++#else
++#define SPI_SUPPORT_MASTER_CHANGE_ENA_POLARITY	1
++#define SPI_SUPPORT_MASTER_DELAY_START_TIME	1 // S2L only support ssi0, remember to fix it
++#define SPI_SUPPORT_NSM_SHAKE_START_BIT_CHSANGE	1 // S2 and S2L is not explain this in PRM
++#endif
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define SPI_TARGET_FRAME	1
++#else
++#define SPI_TARGET_FRAME	0
++#endif
++
++/* ==========================================================================*/
++#if (SPI_INSTANCES >= 1)
++#define SPI_OFFSET			0x2000
++#define SPI_BASE			(APB_BASE + SPI_OFFSET)
++#define SPI_REG(x)			(SPI_BASE + (x))
++#endif
++
++#if (SPI_SLAVE_INSTANCES >= 1)
++#if (CHIP_REV == A7L)
++#define SPI_SLAVE_OFFSET		0x1000
++#else
++#define SPI_SLAVE_OFFSET		0x1E000
++#endif
++#define SPI_SLAVE_BASE			(APB_BASE + SPI_SLAVE_OFFSET)
++#define SPI_SLAVE_REG(x)		(SPI_SLAVE_BASE + (x))
++#endif
++
++#if (SPI_INSTANCES >= 2)
++#define SPI2_OFFSET			0xF000
++#define SPI2_BASE			(APB_BASE + SPI2_OFFSET)
++#define SPI2_REG(x)			(SPI2_BASE + (x))
++#endif
++
++#if (SPI_INSTANCES >= 3)
++#define SPI3_OFFSET			0x15000
++#define SPI3_BASE			(APB_BASE + SPI3_OFFSET)
++#define SPI3_REG(x)			(SPI3_BASE + (x))
++#endif
++
++#if (SPI_INSTANCES >= 4)
++#define SPI4_OFFSET			0x16000
++#define SPI4_BASE			(APB_BASE + SPI4_OFFSET)
++#define SPI4_REG(x)			(SPI4_BASE + (x))
++#endif
++
++#if (SPI_AHB_INSTANCES == 1)
++#define SSI_DMA_OFFSET			0xD000
++#define SSI_DMA_BASE			(AHB_BASE + SSI_DMA_OFFSET)
++#define SSI_DMA_REG(x)			(SSI_DMA_BASE + (x))
++
++#if (SPI_INSTANCES == 1)
++#define SPI2_OFFSET			0x1F000
++#define SPI2_BASE			(AHB_BASE + SPI2_OFFSET)
++#define SPI2_REG(x)			(SPI2_BASE + (x))
++#endif
++#endif
++
++#if (SPI_AHB_INSTANCES == 2)
++#define SPI_OFFSET			0x20000
++#define SPI_BASE			(AHB_BASE + SPI_OFFSET)
++#define SPI_REG(x)			(SPI_BASE + (x))
++
++#define SPI2_OFFSET			0x21000
++#define SPI2_BASE			(AHB_BASE + SPI2_OFFSET)
++#define SPI2_REG(x)			(SPI2_BASE + (x))
++#endif
++
++#if (SPI_AHB_SLAVE_INSTANCES >= 1)
++#define SPI_AHB_SLAVE_OFFSET		0x26000
++#define SPI_AHB_SLAVE_BASE		(AHB_BASE + SPI_AHB_SLAVE_OFFSET)
++#define SPI_AHB_SLAVE_REG(x)		(SPI_AHB_SLAVE_BASE + (x))
++#endif
++
++#define SPI_MASTER_INSTANCES		(SPI_INSTANCES + SPI_AHB_INSTANCES)
++
++
++/* ==========================================================================*/
++/* SPI_FIFO_SIZE */
++#define SPI_DATA_FIFO_SIZE_16		0x10
++#define SPI_DATA_FIFO_SIZE_32		0x20
++#define SPI_DATA_FIFO_SIZE_64		0x40
++#define SPI_DATA_FIFO_SIZE_128		0x80
++
++/****************************************************/
++/* Controller registers definitions                 */
++/****************************************************/
++
++#define SPI_CTRLR0_OFFSET		0x00
++#define SPI_CTRLR1_OFFSET		0x04
++#define SPI_SSIENR_OFFSET		0x08
++#define SPI_MWCR_OFFSET			0x0c // no PRM explain it and no code use it. should be commented after check
++#define SPI_SER_OFFSET			0x10
++#define SPI_BAUDR_OFFSET		0x14
++#define SPI_TXFTLR_OFFSET		0x18
++#define SPI_RXFTLR_OFFSET		0x1c
++#define SPI_TXFLR_OFFSET		0x20
++#define SPI_RXFLR_OFFSET		0x24
++#define SPI_SR_OFFSET			0x28
++#define SPI_IMR_OFFSET			0x2c
++#define SPI_ISR_OFFSET			0x30
++#define SPI_RISR_OFFSET			0x34
++#define SPI_TXOICR_OFFSET		0x38
++#define SPI_RXOICR_OFFSET		0x3c
++#define SPI_RXUICR_OFFSET		0x40
++#define SPI_MSTICR_OFFSET		0x44
++#define SPI_ICR_OFFSET			0x48
++#define SPI_DMAC_OFFSET			0x4c
++#define SPI_IDR_OFFSET			0x58
++#define SPI_VERSION_ID_OFFSET		0x5c
++#define SPI_DR_OFFSET			0x60
++
++#if (SPI_SUPPORT_MASTER_CHANGE_ENA_POLARITY == 1)
++#define SPI_SSIENPOLR_OFFSET		0x260
++#endif
++#if (SPI_SUPPORT_MASTER_DELAY_START_TIME == 1)
++#define SPI_SCLK_OUT_DLY_OFFSET		0x264
++#endif
++#if (SPI_SUPPORT_NSM_SHAKE_START_BIT_CHSANGE == 1)
++#define SPI_START_BIT_OFFSET		0x268
++#endif
++
++#if (SPI_TARGET_FRAME == 1)
++#define SPI_TARGET_FRAME_COUNT	0x27c
++#define SPI_FRAME_COUNT			0x280
++#define SPI_FCRICR				0x284
++#define SPI_TX_FRAME_COUNT		0x288
++#endif
++/* ==========================================================================*/
++/* SPI rw mode */
++#define SPI_WRITE_READ		0
++#define SPI_WRITE_ONLY		1
++#define SPI_READ_ONLY		2
++
++/* Tx FIFO empty interrupt mask */
++#define SPI_TXEIS_MASK		0x00000001
++#define SPI_TXOIS_MASK 		0x00000002
++#define SPI_RXFIS_MASK 		0x00000010
++#define SPI_FCRIS_MASK 		0x00000100
++
++/* SPI Parameters */
++#define SPI_DUMMY_DATA		0xffff
++#define MAX_QUERY_TIMES		10
++
++/* Default SPI settings */
++#define SPI_MODE		SPI_MODE_0
++#define SPI_SCPOL		0
++#define SPI_SCPH		0
++#define SPI_FRF			0
++#define SPI_CFS			0x0
++#define SPI_DFS			0xf
++#define SPI_BAUD_RATE		200000
++
++/* ==========================================================================*/
++typedef union {
++	struct {
++		u32		dfs	: 4;	/* [3:0] */
++		u32		frf	: 2;	/* [5:4] */
++		u32		scph	: 1;	/* [6] */
++		u32		scpol	: 1;	/* [7] */
++		u32		tmod	: 2;	/* [9:8] */
++		u32		slv_oe	: 1;	/* [10] */
++		u32		srl	: 1;	/* [11] */
++		u32		reserv1	: 5;	/* [16:12] */
++		u32		residue	: 1;	/* [17] */
++		u32		tx_lsb	: 1;	/* [18] */
++		u32		rx_lsb	: 1;	/* [19] */
++		u32		reserv2	: 1;	/* [20] */
++		u32		fc_en	: 1;	/* [21] */
++		u32		rxd_mg	: 4;	/* [25:22] */
++		u32		byte_ws	: 1;	/* [26] */
++		u32		hold	: 1;	/* [27] */
++		u32		reserv3	: 4;	/* [31:28] */
++	} s;
++	u32	w;
++} spi_ctrl0_reg_t;
++
++typedef union {
++	struct {
++		u32		busy	: 1;	/* [0] */
++		u32		tfnf	: 1;	/* [1] */
++		u32		tfe	: 1;	/* [2] */
++		u32		rfne	: 1;	/* [3] */
++		u32		rff	: 1;	/* [4] */
++		u32		txe	: 1;	/* [5] */
++		u32		dcol	: 1;	/* [6] */
++		u32		reserve	: 25;	/* [31:7] */
++	} s;
++	u32	w;
++} spi_status_reg_t;
++
++/* ==========================================================================*/
++
++#ifndef __ASSEMBLER__
++
++struct ambarella_spi_cfg_info {
++	u8	spi_mode;
++	u8	cfs_dfs;
++	u8	cs_change;
++	u32	baud_rate;
++};
++typedef struct ambarella_spi_cfg_info amba_spi_cfg_t;
++
++typedef struct {
++	u8	bus_id;
++	u8	cs_id;
++	u8	*buffer;
++	u32	n_size;	// u16	n_size;
++} amba_spi_write_t;
++
++typedef struct {
++	u8	bus_id;
++	u8	cs_id;
++	u8	*buffer;
++	u16	n_size;
++} amba_spi_read_t;
++
++typedef struct {
++	u8	bus_id;
++	u8	cs_id;
++	u8	*w_buffer;
++	u8	*r_buffer;
++	u16	w_size;
++	u16	r_size;
++} amba_spi_write_then_read_t;
++
++typedef struct {
++	u8	bus_id;
++	u8	cs_id;
++	u8	*w_buffer;
++	u8	*r_buffer;
++	u16	n_size;
++} amba_spi_write_and_read_t;
++
++/* ==========================================================================*/
++extern int ambarella_spi_write(amba_spi_cfg_t *spi_cfg,
++	amba_spi_write_t *spi_write);
++extern int ambarella_spi_read(amba_spi_cfg_t *spi_cfg,
++	amba_spi_read_t *spi_read);
++extern int ambarella_spi_write_then_read(amba_spi_cfg_t *spi_cfg,
++	amba_spi_write_then_read_t *spi_write_then_read);
++extern int ambarella_spi_write_and_read(amba_spi_cfg_t *spi_cfg,
++	amba_spi_write_and_read_t *spi_write_and_read);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_SPI_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/timer.h b/arch/arm/mach-ambarella/include/plat/timer.h
+new file mode 100644
+index 00000000..8da17104
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/timer.h
+@@ -0,0 +1,285 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/timer.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_TIMER_H__
++#define __PLAT_AMBARELLA_TIMER_H__
++
++/* ==========================================================================*/
++#define TIMER_OFFSET			0xB000
++#define TIMER_BASE			(APB_BASE + TIMER_OFFSET)
++#define TIMER_REG(x)			(TIMER_BASE + (x))
++
++#define TIMER1_OFFSET			0xF000
++#define TIMER1_BASE			(APB_BASE + TIMER1_OFFSET)
++#define TIMER1_REG(x)			(TIMER1_BASE + (x))
++
++/* ==========================================================================*/
++#if (CHIP_REV == A5S)
++#define INTERVAL_TIMER_INSTANCES		3
++#elif (CHIP_REV == S3)
++#define INTERVAL_TIMER_INSTANCES		20
++#else
++#define INTERVAL_TIMER_INSTANCES		8
++#endif
++
++/* ==========================================================================*/
++#define TIMER1_STATUS_OFFSET		0x00
++#define TIMER1_RELOAD_OFFSET		0x04
++#define TIMER1_MATCH1_OFFSET		0x08
++#define TIMER1_MATCH2_OFFSET		0x0c
++#define TIMER2_STATUS_OFFSET		0x10
++#define TIMER2_RELOAD_OFFSET		0x14
++#define TIMER2_MATCH1_OFFSET		0x18
++#define TIMER2_MATCH2_OFFSET		0x1c
++#define TIMER3_STATUS_OFFSET		0x20
++#define TIMER3_RELOAD_OFFSET		0x24
++#define TIMER3_MATCH1_OFFSET		0x28
++#define TIMER3_MATCH2_OFFSET		0x2c
++
++#if (INTERVAL_TIMER_INSTANCES > 3)
++#define TIMER4_STATUS_OFFSET		0x34
++#define TIMER4_RELOAD_OFFSET		0x38
++#define TIMER4_MATCH1_OFFSET		0x3c
++#define TIMER4_MATCH2_OFFSET		0x40
++#define TIMER5_STATUS_OFFSET		0x44
++#define TIMER5_RELOAD_OFFSET		0x48
++#define TIMER5_MATCH1_OFFSET		0x4c
++#define TIMER5_MATCH2_OFFSET		0x50
++#define TIMER6_STATUS_OFFSET		0x54
++#define TIMER6_RELOAD_OFFSET		0x58
++#define TIMER6_MATCH1_OFFSET		0x5c
++#define TIMER6_MATCH2_OFFSET		0x60
++#define TIMER7_STATUS_OFFSET		0x64
++#define TIMER7_RELOAD_OFFSET		0x68
++#define TIMER7_MATCH1_OFFSET		0x6c
++#define TIMER7_MATCH2_OFFSET		0x70
++#define TIMER8_STATUS_OFFSET		0x74
++#define TIMER8_RELOAD_OFFSET		0x78
++#define TIMER8_MATCH1_OFFSET		0x7c
++#define TIMER8_MATCH2_OFFSET		0x80
++#endif
++
++#if (INTERVAL_TIMER_INSTANCES > 8)
++#define TIMER9_STATUS_OFFSET		0x88
++#define TIMER9_RELOAD_OFFSET		0x8c
++#define TIMER9_MATCH1_OFFSET		0x90
++#define TIMER9_MATCH2_OFFSET		0x94
++#define TIMER10_STATUS_OFFSET		0x98
++#define TIMER10_RELOAD_OFFSET		0x9c
++#define TIMER10_MATCH1_OFFSET		0xa0
++#define TIMER10_MATCH2_OFFSET		0xa4
++
++/* belong to the 2nd timer instance */
++#define TIMER11_STATUS_OFFSET		0x00
++#define TIMER11_RELOAD_OFFSET		0x04
++#define TIMER11_MATCH1_OFFSET		0x08
++#define TIMER11_MATCH2_OFFSET		0x0c
++#define TIMER12_STATUS_OFFSET		0x10
++#define TIMER12_RELOAD_OFFSET		0x14
++#define TIMER12_MATCH1_OFFSET		0x18
++#define TIMER12_MATCH2_OFFSET		0x1c
++#define TIMER13_STATUS_OFFSET		0x20
++#define TIMER13_RELOAD_OFFSET		0x24
++#define TIMER13_MATCH1_OFFSET		0x28
++#define TIMER13_MATCH2_OFFSET		0x2c
++#define TIMER14_STATUS_OFFSET		0x34
++#define TIMER14_RELOAD_OFFSET		0x38
++#define TIMER14_MATCH1_OFFSET		0x3c
++#define TIMER14_MATCH2_OFFSET		0x40
++#define TIMER15_STATUS_OFFSET		0x44
++#define TIMER15_RELOAD_OFFSET		0x48
++#define TIMER15_MATCH1_OFFSET		0x4c
++#define TIMER15_MATCH2_OFFSET		0x50
++#define TIMER16_STATUS_OFFSET		0x54
++#define TIMER16_RELOAD_OFFSET		0x58
++#define TIMER16_MATCH1_OFFSET		0x5c
++#define TIMER16_MATCH2_OFFSET		0x60
++#define TIMER17_STATUS_OFFSET		0x64
++#define TIMER17_RELOAD_OFFSET		0x68
++#define TIMER17_MATCH1_OFFSET		0x6c
++#define TIMER17_MATCH2_OFFSET		0x70
++#define TIMER18_STATUS_OFFSET		0x74
++#define TIMER18_RELOAD_OFFSET		0x78
++#define TIMER18_MATCH1_OFFSET		0x7c
++#define TIMER18_MATCH2_OFFSET		0x80
++#define TIMER19_STATUS_OFFSET		0x88
++#define TIMER19_RELOAD_OFFSET		0x8c
++#define TIMER19_MATCH1_OFFSET		0x90
++#define TIMER19_MATCH2_OFFSET		0x94
++#define TIMER20_STATUS_OFFSET		0x98
++#define TIMER20_RELOAD_OFFSET		0x9c
++#define TIMER20_MATCH1_OFFSET		0xa0
++#define TIMER20_MATCH2_OFFSET		0xa4
++#endif
++
++#define TIMER_CTR_OFFSET		0x30
++#define TIMER_CTR1_OFFSET		0x84
++
++#define TIMER1_STATUS_REG		TIMER_REG(TIMER1_STATUS_OFFSET)
++#define TIMER1_RELOAD_REG		TIMER_REG(TIMER1_RELOAD_OFFSET)
++#define TIMER1_MATCH1_REG		TIMER_REG(TIMER1_MATCH1_OFFSET)
++#define TIMER1_MATCH2_REG		TIMER_REG(TIMER1_MATCH2_OFFSET)
++#define TIMER2_STATUS_REG		TIMER_REG(TIMER2_STATUS_OFFSET)
++#define TIMER2_RELOAD_REG		TIMER_REG(TIMER2_RELOAD_OFFSET)
++#define TIMER2_MATCH1_REG		TIMER_REG(TIMER2_MATCH1_OFFSET)
++#define TIMER2_MATCH2_REG		TIMER_REG(TIMER2_MATCH2_OFFSET)
++#define TIMER3_STATUS_REG		TIMER_REG(TIMER3_STATUS_OFFSET)
++#define TIMER3_RELOAD_REG		TIMER_REG(TIMER3_RELOAD_OFFSET)
++#define TIMER3_MATCH1_REG		TIMER_REG(TIMER3_MATCH1_OFFSET)
++#define TIMER3_MATCH2_REG		TIMER_REG(TIMER3_MATCH2_OFFSET)
++#if (INTERVAL_TIMER_INSTANCES > 3)
++#define TIMER4_STATUS_REG		TIMER_REG(TIMER4_STATUS_OFFSET)
++#define TIMER4_RELOAD_REG		TIMER_REG(TIMER4_RELOAD_OFFSET)
++#define TIMER4_MATCH1_REG		TIMER_REG(TIMER4_MATCH1_OFFSET)
++#define TIMER4_MATCH2_REG		TIMER_REG(TIMER4_MATCH2_OFFSET)
++#define TIMER5_STATUS_REG		TIMER_REG(TIMER5_STATUS_OFFSET)
++#define TIMER5_RELOAD_REG		TIMER_REG(TIMER5_RELOAD_OFFSET)
++#define TIMER5_MATCH1_REG		TIMER_REG(TIMER5_MATCH1_OFFSET)
++#define TIMER5_MATCH2_REG		TIMER_REG(TIMER5_MATCH2_OFFSET)
++#define TIMER6_STATUS_REG		TIMER_REG(TIMER6_STATUS_OFFSET)
++#define TIMER6_RELOAD_REG		TIMER_REG(TIMER6_RELOAD_OFFSET)
++#define TIMER6_MATCH1_REG		TIMER_REG(TIMER6_MATCH1_OFFSET)
++#define TIMER6_MATCH2_REG		TIMER_REG(TIMER6_MATCH2_OFFSET)
++#define TIMER7_STATUS_REG		TIMER_REG(TIMER7_STATUS_OFFSET)
++#define TIMER7_RELOAD_REG		TIMER_REG(TIMER7_RELOAD_OFFSET)
++#define TIMER7_MATCH1_REG		TIMER_REG(TIMER7_MATCH1_OFFSET)
++#define TIMER7_MATCH2_REG		TIMER_REG(TIMER7_MATCH2_OFFSET)
++#define TIMER8_STATUS_REG		TIMER_REG(TIMER8_STATUS_OFFSET)
++#define TIMER8_RELOAD_REG		TIMER_REG(TIMER8_RELOAD_OFFSET)
++#define TIMER8_MATCH1_REG		TIMER_REG(TIMER8_MATCH1_OFFSET)
++#define TIMER8_MATCH2_REG		TIMER_REG(TIMER8_MATCH2_OFFSET)
++#endif
++#if (INTERVAL_TIMER_INSTANCES > 8)
++#define TIMER9_STATUS_REG		TIMER_REG(TIMER9_STATUS_OFFSET)
++#define TIMER9_RELOAD_REG		TIMER_REG(TIMER9_RELOAD_OFFSET)
++#define TIMER9_MATCH1_REG		TIMER_REG(TIMER9_MATCH1_OFFSET)
++#define TIMER9_MATCH2_REG		TIMER_REG(TIMER9_MATCH2_OFFSET)
++#define TIMER10_STATUS_REG		TIMER_REG(TIMER10_STATUS_OFFSET)
++#define TIMER10_RELOAD_REG		TIMER_REG(TIMER10_RELOAD_OFFSET)
++#define TIMER10_MATCH1_REG		TIMER_REG(TIMER10_MATCH1_OFFSET)
++#define TIMER10_MATCH2_REG		TIMER_REG(TIMER10_MATCH2_OFFSET)
++
++/* belong to the 2nd timer instance */
++#define TIMER11_STATUS_REG		TIMER1_REG(TIMER11_STATUS_OFFSET)
++#define TIMER11_RELOAD_REG		TIMER1_REG(TIMER11_RELOAD_OFFSET)
++#define TIMER11_MATCH1_REG		TIMER1_REG(TIMER11_MATCH1_OFFSET)
++#define TIMER11_MATCH2_REG		TIMER1_REG(TIMER11_MATCH2_OFFSET)
++#define TIMER12_STATUS_REG		TIMER1_REG(TIMER12_STATUS_OFFSET)
++#define TIMER12_RELOAD_REG		TIMER1_REG(TIMER12_RELOAD_OFFSET)
++#define TIMER12_MATCH1_REG		TIMER1_REG(TIMER12_MATCH1_OFFSET)
++#define TIMER12_MATCH2_REG		TIMER1_REG(TIMER12_MATCH2_OFFSET)
++#define TIMER13_STATUS_REG		TIMER1_REG(TIMER13_STATUS_OFFSET)
++#define TIMER13_RELOAD_REG		TIMER1_REG(TIMER13_RELOAD_OFFSET)
++#define TIMER13_MATCH1_REG		TIMER1_REG(TIMER13_MATCH1_OFFSET)
++#define TIMER13_MATCH2_REG		TIMER1_REG(TIMER13_MATCH2_OFFSET)
++#define TIMER14_STATUS_REG		TIMER1_REG(TIMER14_STATUS_OFFSET)
++#define TIMER14_RELOAD_REG		TIMER1_REG(TIMER14_RELOAD_OFFSET)
++#define TIMER14_MATCH1_REG		TIMER1_REG(TIMER14_MATCH1_OFFSET)
++#define TIMER14_MATCH2_REG		TIMER1_REG(TIMER14_MATCH2_OFFSET)
++#define TIMER15_STATUS_REG		TIMER1_REG(TIMER15_STATUS_OFFSET)
++#define TIMER15_RELOAD_REG		TIMER1_REG(TIMER15_RELOAD_OFFSET)
++#define TIMER15_MATCH1_REG		TIMER1_REG(TIMER15_MATCH1_OFFSET)
++#define TIMER15_MATCH2_REG		TIMER1_REG(TIMER15_MATCH2_OFFSET)
++#define TIMER16_STATUS_REG		TIMER1_REG(TIMER16_STATUS_OFFSET)
++#define TIMER16_RELOAD_REG		TIMER1_REG(TIMER16_RELOAD_OFFSET)
++#define TIMER16_MATCH1_REG		TIMER1_REG(TIMER16_MATCH1_OFFSET)
++#define TIMER16_MATCH2_REG		TIMER1_REG(TIMER16_MATCH2_OFFSET)
++#define TIMER17_STATUS_REG		TIMER1_REG(TIMER17_STATUS_OFFSET)
++#define TIMER17_RELOAD_REG		TIMER1_REG(TIMER17_RELOAD_OFFSET)
++#define TIMER17_MATCH1_REG		TIMER1_REG(TIMER17_MATCH1_OFFSET)
++#define TIMER17_MATCH2_REG		TIMER1_REG(TIMER17_MATCH2_OFFSET)
++#define TIMER18_STATUS_REG		TIMER1_REG(TIMER18_STATUS_OFFSET)
++#define TIMER18_RELOAD_REG		TIMER1_REG(TIMER18_RELOAD_OFFSET)
++#define TIMER18_MATCH1_REG		TIMER1_REG(TIMER18_MATCH1_OFFSET)
++#define TIMER18_MATCH2_REG		TIMER1_REG(TIMER18_MATCH2_OFFSET)
++#define TIMER19_STATUS_REG		TIMER1_REG(TIMER19_STATUS_OFFSET)
++#define TIMER19_RELOAD_REG		TIMER1_REG(TIMER19_RELOAD_OFFSET)
++#define TIMER19_MATCH1_REG		TIMER1_REG(TIMER19_MATCH1_OFFSET)
++#define TIMER19_MATCH2_REG		TIMER1_REG(TIMER19_MATCH2_OFFSET)
++#define TIMER20_STATUS_REG		TIMER1_REG(TIMER20_STATUS_OFFSET)
++#define TIMER20_RELOAD_REG		TIMER1_REG(TIMER20_RELOAD_OFFSET)
++#define TIMER20_MATCH1_REG		TIMER1_REG(TIMER20_MATCH1_OFFSET)
++#define TIMER20_MATCH2_REG		TIMER1_REG(TIMER20_MATCH2_OFFSET)
++#endif
++
++#define TIMER_CTR_REG			TIMER_REG(TIMER_CTR_OFFSET)
++#define TIMER_CTR1_REG			TIMER_REG(TIMER_CTR1_OFFSET)
++#define TIMER1_CTR_REG			TIMER1_REG(TIMER_CTR_OFFSET)
++#define TIMER1_CTR1_REG			TIMER1_REG(TIMER_CTR1_OFFSET)
++
++#define TIMER_CTR_EN1			0x00000001
++#define TIMER_CTR_CSL1			0x00000002
++#define TIMER_CTR_OF1			0x00000004
++#define TIMER_CTR_EN2			0x00000010
++#define TIMER_CTR_CSL2			0x00000020
++#define TIMER_CTR_OF2			0x00000040
++#define TIMER_CTR_EN3			0x00000100
++#define TIMER_CTR_CSL3			0x00000200
++#define TIMER_CTR_OF3			0x00000400
++#if (INTERVAL_TIMER_INSTANCES > 3)
++#define TIMER_CTR_EN4			0x00001000
++#define TIMER_CTR_CSL4			0x00002000
++#define TIMER_CTR_OF4			0x00004000
++#define TIMER_CTR_EN5			0x00010000
++#define TIMER_CTR_CSL5			0x00020000
++#define TIMER_CTR_OF5			0x00040000
++#define TIMER_CTR_EN6			0x00100000
++#define TIMER_CTR_CSL6			0x00200000
++#define TIMER_CTR_OF6			0x00400000
++#define TIMER_CTR_EN7			0x01000000
++#define TIMER_CTR_CSL7			0x02000000
++#define TIMER_CTR_OF7			0x04000000
++#define TIMER_CTR_EN8			0x10000000
++#define TIMER_CTR_CSL8			0x20000000
++#define TIMER_CTR_OF8			0x40000000
++#endif
++#if (INTERVAL_TIMER_INSTANCES > 8)
++#define TIMER_CTR_EN9			0x00000001
++#define TIMER_CTR_OF9			0x00000004
++#define TIMER_CTR_EN10			0x00000010
++#define TIMER_CTR_OF10			0x00000040
++#endif
++
++#define TIMER_STATUS_OFFSET		0x00
++#define TIMER_RELOAD_OFFSET		0x04
++#define TIMER_MATCH1_OFFSET		0x08
++#define TIMER_MATCH2_OFFSET		0x0c
++
++#define TIMER_CTRL_OF			0x4
++#define TIMER_CTRL_CSL			0x2
++#define TIMER_CTRL_EN			0x1
++
++/* ==========================================================================*/
++#ifndef __ASSEMBLER__
++
++/* ==========================================================================*/
++extern struct sys_timer ambarella_timer;
++
++/* ==========================================================================*/
++extern void ambarella_timer_init(void);
++
++#endif /* __ASSEMBLER__ */
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_TIMER_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/uart.h b/arch/arm/mach-ambarella/include/plat/uart.h
+new file mode 100644
+index 00000000..7c497549
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/uart.h
+@@ -0,0 +1,179 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/uart.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_UART_H__
++#define __PLAT_AMBARELLA_UART_H__
++
++/* ==========================================================================*/
++#if (CHIP_REV == A8) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define	UART_INSTANCES			4
++#else
++#define	UART_INSTANCES			2
++#endif
++
++/* ==========================================================================*/
++#define UART_OFFSET			0x5000
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define UART1_OFFSET			0x32000
++#else
++#define UART1_OFFSET			0x1F000
++#endif
++#if (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define UART2_OFFSET			0x14000
++#define UART3_OFFSET			0x15000
++#elif (CHIP_REV == A8)
++#define UART2_OFFSET			0x13000
++#define UART3_OFFSET			0x14000
++#endif
++
++#define UART0_BASE			(APB_BASE + UART_OFFSET)
++#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
++#define UART1_BASE			(AHB_BASE + UART1_OFFSET)
++#else
++#define UART1_BASE			(APB_BASE + UART1_OFFSET)
++#endif
++#if (CHIP_REV == A8) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define UART2_BASE			(APB_BASE + UART2_OFFSET)
++#define UART3_BASE			(APB_BASE + UART3_OFFSET)
++#endif
++
++#define UART0_REG(x)			(UART0_BASE + (x))
++#define UART1_REG(x)			(UART1_BASE + (x))
++#if (CHIP_REV == A8) || (CHIP_REV == S2) || (CHIP_REV == S2E)
++#define UART2_REG(x)			(UART2_BASE + (x))
++#define UART3_REG(x)			(UART3_BASE + (x))
++#endif
++/* ==========================================================================*/
++#define UART_RB_OFFSET			0x00
++#define UART_TH_OFFSET			0x00
++#define UART_DLL_OFFSET			0x00
++#define UART_IE_OFFSET			0x04
++#define UART_DLH_OFFSET			0x04
++#define UART_II_OFFSET			0x08
++#define UART_FC_OFFSET			0x08
++#define UART_LC_OFFSET			0x0c
++#define UART_MC_OFFSET			0x10
++#define UART_LS_OFFSET			0x14
++#define UART_MS_OFFSET			0x18
++#define UART_SC_OFFSET			0x1c	/* Byte */
++#define UART_DMAE_OFFSET		0x28
++#define UART_DMAF_OFFSET		0x40	/* DMA fifo */
++#define UART_US_OFFSET			0x7c
++#define UART_TFL_OFFSET			0x80
++#define UART_RFL_OFFSET			0x84
++#define UART_SRR_OFFSET			0x88
++
++/* UART[x]_IE_REG */
++#define UART_IE_PTIME			0x80
++#define UART_IE_ETOI			0x20
++#define UART_IE_EBDI			0x10
++#define UART_IE_EDSSI			0x08
++#define UART_IE_ELSI			0x04
++#define UART_IE_ETBEI			0x02
++#define UART_IE_ERBFI			0x01
++
++/* UART[x]_II_REG */
++#define UART_II_MODEM_STATUS_CHANGED	0x00
++#define UART_II_NO_INT_PENDING		0x01
++#define UART_II_THR_EMPTY		0x02
++#define UART_II_RCV_DATA_AVAIL		0x04
++#define UART_II_RCV_STATUS		0x06
++#define UART_II_CHAR_TIMEOUT		0x0c
++
++/* UART[x]_FC_REG */
++#define UART_FC_RX_ONECHAR		0x00
++#define UART_FC_RX_QUARTER_FULL		0x40
++#define UART_FC_RX_HALF_FULL		0x80
++#define UART_FC_RX_2_TO_FULL		0xc0
++#define UART_FC_TX_EMPTY		0x00
++#define UART_FC_TX_2_IN_FIFO		0x10
++#define UART_FC_TX_QUATER_IN_FIFO	0x20
++#define UART_FC_TX_HALF_IN_FIFO		0x30
++#define UART_FC_XMITR			0x04
++#define UART_FC_RCVRR			0x02
++#define UART_FC_FIFOE			0x01
++
++/* UART[x]_LC_REG */
++#define UART_LC_DLAB			0x80
++#define UART_LC_BRK			0x40
++#define UART_LC_EVEN_PARITY		0x10
++#define UART_LC_ODD_PARITY		0x00
++#define UART_LC_PEN			0x08
++#define UART_LC_STOP_2BIT		0x04
++#define UART_LC_STOP_1BIT		0x00
++#define UART_LC_CLS_8_BITS		0x03
++#define UART_LC_CLS_7_BITS		0x02
++#define UART_LC_CLS_6_BITS		0x01
++#define UART_LC_CLS_5_BITS		0x00
++/*	quick defs */
++#define	UART_LC_8N1			0x03
++#define	UART_LC_7E1			0x0a
++
++/* UART[x]_MC_REG */
++#define UART_MC_SIRE			0x40
++#define UART_MC_AFCE			0x20
++#define UART_MC_LB			0x10
++#define UART_MC_OUT2			0x08
++#define UART_MC_OUT1			0x04
++#define UART_MC_RTS			0x02
++#define UART_MC_DTR			0x01
++
++/* UART[x]_LS_REG */
++#define UART_LS_FERR			0x80
++#define UART_LS_TEMT			0x40
++#define UART_LS_THRE			0x20
++#define UART_LS_BI			0x10
++#define UART_LS_FE			0x08
++#define UART_LS_PE			0x04
++#define UART_LS_OE			0x02
++#define UART_LS_DR			0x01
++
++/* UART[x]_MS_REG */
++#define UART_MS_DCD			0x80
++#define UART_MS_RI			0x40
++#define UART_MS_DSR			0x20
++#define UART_MS_CTS			0x10
++#define UART_MS_DDCD			0x08
++#define UART_MS_TERI			0x04
++#define UART_MS_DDSR			0x02
++#define UART_MS_DCTS			0x01
++
++/* UART[x]_US_REG */
++#define UART_US_RFF			0x10
++#define UART_US_RFNE			0x08
++#define UART_US_TFE			0x04
++#define UART_US_TFNF			0x02
++#define UART_US_BUSY			0x01
++
++/* ==========================================================================*/
++#define UART_FIFO_SIZE			(16)
++
++#define DEFAULT_AMBARELLA_UART_MCR	(0)
++#if (CHIP_REV == A5S)
++#define DEFAULT_AMBARELLA_UART_IER	(UART_IE_ELSI | UART_IE_ERBFI)
++#else
++#define DEFAULT_AMBARELLA_UART_IER	(UART_IE_ELSI | UART_IE_ERBFI | UART_IE_ETOI)
++#endif
++
++#endif /* __PLAT_AMBARELLA_UART_H__ */
++
+diff --git a/arch/arm/mach-ambarella/include/plat/udc.h b/arch/arm/mach-ambarella/include/plat/udc.h
+new file mode 100644
+index 00000000..b28e63ad
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/udc.h
+@@ -0,0 +1,403 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/udc.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_UDC_H__
++#define __PLAT_AMBARELLA_UDC_H__
++
++/* ==========================================================================*/
++#define USBDC_OFFSET			0x6000
++#define USBDC_BASE			(AHB_BASE + USBDC_OFFSET)
++#define USBDC_REG(x)			(USBDC_BASE + (x))
++
++/* ==========================================================================*/
++
++/*----------------------------------------------
++    macros
++----------------------------------------------*/
++#define USB_READ_REG(adr)	(*(volatile unsigned long *)(adr))
++#define USB_WRITE_REG(adr, val)	(*(volatile unsigned long *)(adr)=(val))
++#define USB_SET_REG(adr, val)	(USB_WRITE_REG((adr), (USB_READ_REG(adr) | (val))))
++#define USB_CLR_REG(adr, val)	(USB_WRITE_REG((adr), (USB_READ_REG(adr) & ~(val))))
++
++//-------------------------------------
++// USB RxFIFO and TxFIFO depth (single or multiple)
++//-------------------------------------
++#define USB_RXFIFO_DEPTH_CTRLOUT	(256 << 16)	// shared
++#define USB_RXFIFO_DEPTH_BULKOUT	(256 << 16)	// shared
++#define USB_RXFIFO_DEPTH_INTROUT	(256 << 16)	// shared
++#define USB_TXFIFO_DEPTH_CTRLIN		(64 / 4)	// 16 32-bit
++#define USB_TXFIFO_DEPTH_BULKIN		(1024 / 4)	// 256 32-bit
++#define USB_TXFIFO_DEPTH_INTRIN		(512 / 4)	// 128 32-bit
++#define USB_TXFIFO_DEPTH_ISOIN		((512 * 2) / 4)	// 128 32-bit
++
++#define USB_TXFIFO_DEPTH		(64 / 4 + 4 * 512 / 4)	// 528 32-bit
++#define USB_RXFIFO_DEPTH		(256)			// 256 32-bit
++
++//-------------------------------------
++// USB memory map
++//-------------------------------------
++#define USB_EP_IN_BASE		USBDC_BASE		// IN endpoint specific registers
++#define USB_EP_OUT_BASE		(USBDC_BASE + 0x0200)	// OUT endpoint specific registers
++#define USB_DEV_BASE		(USBDC_BASE + 0x0400)	// device specific registers
++#define USB_UDC_BASE		(USBDC_BASE + 0x0504)	// UDC specific registers, 0x0500 is reserved for control endpoint (RO)
++#define USB_RXFIFO_BASE		(USBDC_BASE + 0x0800)	// RxFIFO
++#define USB_TXFIFO_BASE		(USB_RXFIFO_BASE + USB_RXFIFO_DEPTH)	// TxFIFO
++
++//-------------------------------------
++// USB register address
++//-------------------------------------
++#define	USB_EP_IN_CTRL_REG(n)		(USB_EP_IN_BASE + 0x0000 + 0x0020 * (n))
++#define	USB_EP_IN_STS_REG(n)		(USB_EP_IN_BASE + 0x0004 + 0x0020 * (n))
++#define	USB_EP_IN_BUF_SZ_REG(n)		(USB_EP_IN_BASE + 0x0008 + 0x0020 * (n))
++#define	USB_EP_IN_MAX_PKT_SZ_REG(n)	(USB_EP_IN_BASE + 0x000c + 0x0020 * (n))
++#define	USB_EP_IN_DAT_DESC_PTR_REG(n)	(USB_EP_IN_BASE + 0x0014 + 0x0020 * (n))
++#define USB_EP_IN_WR_CFM_REG		(USB_EP_IN_BASE + 0x001c + 0x0020 * (n))	// for slave-only mode
++
++#define	USB_EP_OUT_CTRL_REG(n)		(USB_EP_OUT_BASE + 0x0000 + 0x0020 * (n))
++#define	USB_EP_OUT_STS_REG(n)		(USB_EP_OUT_BASE + 0x0004 + 0x0020 * (n))
++#define	USB_EP_OUT_PKT_FRM_NUM_REG(n)	(USB_EP_OUT_BASE + 0x0008 + 0x0020 * (n))
++#define	USB_EP_OUT_MAX_PKT_SZ_REG(n) 	(USB_EP_OUT_BASE + 0x000c + 0x0020 * (n))
++#define	USB_EP_OUT_SETUP_BUF_PTR_REG(n) (USB_EP_OUT_BASE + 0x0010 + 0x0020 * (n))
++#define	USB_EP_OUT_DAT_DESC_PTR_REG(n)	(USB_EP_OUT_BASE + 0x0014 + 0x0020 * (n))
++#define USB_EP_OUT_RD_CFM_ZO_REG	(USB_EP_OUT_BASE + 0x001c + 0x0020 * (n))	// for slave-only mode
++
++#define USB_DEV_CFG_REG			(USB_DEV_BASE + 0x0000)
++#define USB_DEV_CTRL_REG		(USB_DEV_BASE + 0x0004)
++#define USB_DEV_STS_REG			(USB_DEV_BASE + 0x0008)
++#define USB_DEV_INTR_REG		(USB_DEV_BASE + 0x000c)
++#define USB_DEV_INTR_MSK_REG		(USB_DEV_BASE + 0x0010)
++#define USB_DEV_EP_INTR_REG		(USB_DEV_BASE + 0x0014)
++#define USB_DEV_EP_INTR_MSK_REG		(USB_DEV_BASE + 0x0018)
++#define USB_DEV_TEST_MODE_REG		(USB_DEV_BASE + 0x001c)
++
++#define USB_UDC_REG(n)			(USB_UDC_BASE + 0x0004 * (n))	// EP0 is reserved for control endpoint
++
++//-------------------------------------
++// USB register fields
++//-------------------------------------
++//-----------------
++// for endpoint specific registers
++//-----------------
++// for USB_EP_IN_CTRL_REG(n) and USB_EP_OUT_CTRL_REG(n)	// default
++#define USB_EP_STALL			0x00000001		// 0 (RW)
++#define USB_EP_FLUSH			0x00000002		// 0 (RW)
++#define USB_EP_SNOOP			0x00000004		// 0 (RW) - for OUT EP only
++#define USB_EP_POLL_DEMAND		0x00000008		// 0 (RW) - for IN EP only
++#define USB_EP_TYPE_CTRL		0x00000000		// 00 (RW)
++#define USB_EP_TYPE_ISO			0x00000010		// 00 (RW)
++#define USB_EP_TYPE_BULK		0x00000020		// 00 (RW)
++#define USB_EP_TYPE_INTR		0x00000030		// 00 (RW)
++#define USB_EP_NAK_STS			0x00000040		// 0 (RO) - set by UDC after SETUP and STALL
++#define USB_EP_SET_NAK			0x00000080		// 0 (WO)
++#define USB_EP_CLR_NAK			0x00000100		// 0 (WO)
++#define USB_EP_RCV_RDY			0x00000200		// 0 (RW)(D) - set by APP when APP is ready for DMA
++														//			   clear by UDC when end of each packet if USB_DEV_DESC_UPD is set
++														//			   clear by UDC when end of payload if USB_DEV_DESC_UPD is clear
++
++// for USB_EP_IN_STS_REG(n) and USB_EP_OUT_STS_REG(n)
++#define USB_EP_OUT_PKT_MSK		0x00000030		// 00 (R/WC) - 01 for OUT and 10 for SETUP - for OUT EP only
++#define USB_EP_OUT_PKT			0x00000010
++#define USB_EP_SETUP_PKT		0x00000020
++#define USB_EP_IN_PKT			0x00000040		// 0 (R/WC) - for IN EP only
++#define USB_EP_BUF_NOT_AVAIL		0x00000080		// 0 (R/WC)(D) - set by UDC when descriptor is not available
++														//	         	 clear by APP when interrupt is serviced
++#define USB_EP_HOST_ERR			0x00000200		// 0 (R/WC) - set by DMA when DMA is error
++#define USB_EP_TRN_DMA_CMPL		0x00000400		// 0 (R/WC)(D) - set by DMA when DMA is completed
++#define USB_EP_RCV_CLR_STALL            0x02000000              // 0 (R/WC) - Received Clear Stall indication
++														//				 clear by APP when interrupt is serviced
++#define USB_EP_RCV_SET_STALL            0x04000000		// 0 (R/WC) - Received Set Stall indication
++#define USB_EP_RX_PKT_SZ		0x007ff800		// bit mask (RW) - receive packet size in RxFIFO (e.g. SETUP=64, BULK=512)
++
++#define USB_EP_TXFIFO_EMPTY		0x08000000		// 0 (R/WC) - TxFIFO is empty after DMA transfer done
++
++// for USB_EP_IN_BUF_SZ_REG(n) and USB_EP_OUT_PKT_FRM_NUM_REG(n)
++#define USB_EP_TXFIFO_DEPTH		0x0000ffff		// bit mask (RW) - for IN EP only
++#define USB_EP_FRM_NUM			0x0000ffff		// bit mask (RW) - for OUT EP only
++
++// for USB_EP_IN_MAX_PKT_SZ_REG(n) and USB_EP_OUT_MAX_PKT_SZ_REG(n)
++#define USB_EP_RXFIFO_DEPTH		0xffff0000		// bit mask (RW) - for OUT EP only
++#define USB_EP_MAX_PKT_SZ		0x0000ffff		// bit mask (RW)
++
++//-----------------
++// for device specific registers
++//-----------------
++// for USB_DEV_CFG_REG
++#define USB_DEV_SPD_HI			0x00000000		// 00 (RW) - PHY CLK = 30 or 60 MHz
++#define USB_DEV_SPD_FU			0x00000001		// 00 (RW) - PHY CLK = 30 or 60 MHz
++#define USB_DEV_SPD_LO			0x00000002		// 00 (RW) - PHY CLK = 6 MHz
++#define USB_DEV_SPD_FU48		0x00000003		// 00 (RW) - PHY CLK = 48 MHz
++
++#define USB_DEV_REMOTE_WAKEUP_EN	0x00000004		// 0 (RW)
++
++#define USB_DEV_BUS_POWER		0x00000000		// 0 (RW)
++#define USB_DEV_SELF_POWER		0x00000008		// 0 (RW)
++
++#define USB_DEV_SYNC_FRM_EN		0x00000010		// 0 (RW)
++
++#define USB_DEV_PHY_16BIT		0x00000000		// 0 (RW)
++#define USB_DEV_PHY_8BIT		0x00000020		// 0 (RW)
++
++#define USB_DEV_UTMI_DIR_UNI		0x00000000		// 0 (RW) - UDC20 reserved to 0
++#define USB_DEV_UTMI_DIR_BI		0x00000040		// 0 (RW)
++
++#define USB_DEV_STS_OUT_NONZERO		0x00000180		// bit mask (RW)
++
++#define USB_DEV_PHY_ERR			0x00000200		// 0 (RW)
++
++#define USB_DEV_SPD_FU_TIMEOUT		0x00001c00		// bit mask (RW)
++#define USB_DEV_SPD_HI_TIMEOUT		0x0000e000		// bit mask (RW)
++
++#define USB_DEV_HALT_ACK		0x00000000		// 0 (RW) - ACK Clear_Feature (ENDPOINT_HALT) of EP0
++#define USB_DEV_HALT_STALL		0x00010000		// 1 (RW) - STALL Clear_Feature (ENDPOINT_HALT) of EP0
++
++#define USB_DEV_CSR_PRG_EN		0x00020000		// 1 (RW) - enable CSR_DONE of USB_DEV_CFG_REG
++
++#define USB_DEV_SET_DESC_STALL		0x00000000		// 0 (RW) - STALL Set_Descriptor
++#define USB_DEV_SET_DESC_ACK		0x00040000		// 1 (RW) - ACK Set_Descriptor
++
++#define USB_DEV_SDR			0x00000000		// 0 (RW)
++#define USB_DEV_DDR			0x00080000		// 1 (RW)
++
++// for USB_DEV_CTRL_REG
++#define USB_DEV_REMOTE_WAKEUP		0x00000001		// 0 (RW)
++#define USB_DEV_RCV_DMA_EN		0x00000004		// 0 (RW)(D)
++#define USB_DEV_TRN_DMA_EN		0x00000008		// 0 (RW)(D)
++
++#define USB_DEV_DESC_UPD_PYL		0x00000000		// 0 (RW)(D)
++#define USB_DEV_DESC_UPD_PKT		0x00000010		// 0 (RW)(D)
++
++#define USB_DEV_LITTLE_ENDN		0x00000000		// 0 (RW)(D)
++#define USB_DEV_BIG_ENDN		0x00000020		// 0 (RW)(D)
++
++#define USB_DEV_PKT_PER_BUF_MD		0x00000000		// 0 (RW)(D) - packet-per-buffer mode
++#define USB_DEV_BUF_FIL_MD		0x00000040		// 0 (RW)(D) - buffer fill mode
++
++#define USB_DEV_THRESH_EN		0x00000080		// 0 (RW)(D) - for OUT EP only
++
++#define USB_DEV_BURST_EN		0x00000100		// 0 (RW)(D)
++
++#define USB_DEV_SLAVE_ONLY_MD		0x00000000		// 0 (RW)(D)
++#define USB_DEV_DMA_MD			0x00000200		// 0 (RW)(D)
++
++#define USB_DEV_SOFT_DISCON		0x00000400		// 0 (RW) - signal UDC20 to disconnect
++#define USB_DEV_TIMER_SCALE_DOWN	0x00000800		// 0 (RW) - for gate-level simulation only
++#define USB_DEV_NAK			0x00001000		// 0 (RW) - device NAK (applied to all EPs)
++#define USB_DEV_CSR_DONE		0x00002000		// 0 (RW) - set to ACK Set_Configuration or Set_Interface if USB_DEV_CSR_PRG_EN
++#define USB_DEV_FLUSH_RXFIFO		0x00004000
++														//		    clear to NAK
++#define USB_DEV_BURST_LEN		0x00070000		// bit mask (RW)
++#define USB_DEV_THRESH_LEN		0x0f000000		// bit mask (RW)
++
++// for USB_DEV_STS_REG
++#define USB_DEV_CFG_NUM			0x0000000f		// bit mask (RO)
++#define USB_DEV_INTF_NUM		0x000000f0		// bit mask (RO)
++#define USB_DEV_ALT_SET			0x00000f00		// bit mask (RO)
++#define USB_DEV_SUSP_STS		0x00001000		// bit mask (RO)
++
++#define USB_DEV_ENUM_SPD		0x00006000		// bit mask (RO)
++#define USB_DEV_ENUM_SPD_HI		0x00000000		// 00 (RO)
++#define USB_DEV_ENUM_SPD_FU		0x00002000		// 00 (RO)
++#define USB_DEV_ENUM_SPD_LO		0x00004000		// 00 (RO)
++#define USB_DEV_ENUM_SPD_FU48		0x00006000		// 00 (RO)
++
++#define USB_DEV_RXFIFO_EMPTY_STS	0x00008000		// bit mask (RO)
++#define USB_DEV_PHY_ERR_STS		0x00010000		// bit mask (RO)
++#define USB_DEV_FRM_NUM			0xfffc0000		// bit mask (RO)
++
++// for USB_DEV_INTR_REG
++#define USB_DEV_SET_CFG			0x00000001		// 0 (R/WC)
++#define USB_DEV_SET_INTF		0x00000002		// 0 (R/WC)
++#define USB_DEV_IDLE_3MS		0x00000004		// 0 (R/WC)
++#define USB_DEV_RESET			0x00000008		// 0 (R/WC)
++#define USB_DEV_SUSP			0x00000010		// 0 (R/WC)
++#define USB_DEV_SOF			0x00000020		// 0 (R/WC)
++#define USB_DEV_ENUM_CMPL		0x00000040		// 0 (R/WC)
++
++// for USB_DEV_INTR_MSK_REG
++#define USB_DEV_MSK_SET_CFG		0x00000001		// 0 (R/WC)
++#define USB_DEV_MSK_SET_INTF		0x00000002		// 0 (R/WC)
++#define USB_DEV_MSK_IDLE_3MS		0x00000004		// 0 (R/WC)
++#define USB_DEV_MSK_RESET		0x00000008		// 0 (R/WC)
++#define USB_DEV_MSK_SUSP		0x00000010		// 0 (R/WC)
++#define USB_DEV_MSK_SOF			0x00000020		// 0 (R/WC)
++#define USB_DEV_MSK_SPD_ENUM_CMPL	0x00000040		// 0 (R/WC)
++
++// for USB_DEV_EP_INTR_REG
++#define USB_DEV_EP0_IN			0x00000001		// 0 (R/WC)
++#define USB_DEV_EP1_IN			0x00000002		// 0 (R/WC)
++#define USB_DEV_EP2_IN			0x00000004		// 0 (R/WC)
++#define USB_DEV_EP3_IN			0x00000008		// 0 (R/WC)
++#define USB_DEV_EP4_IN			0x00000010		// 0 (R/WC)
++#define USB_DEV_EP5_IN			0x00000020		// 0 (R/WC)
++#define USB_DEV_EP6_IN			0x00000040		// 0 (R/WC)
++#define USB_DEV_EP7_IN			0x00000080		// 0 (R/WC)
++#define USB_DEV_EP8_IN			0x00000100		// 0 (R/WC)
++#define USB_DEV_EP9_IN			0x00000200		// 0 (R/WC)
++#define USB_DEV_EP10_IN			0x00000400		// 0 (R/WC)
++#define USB_DEV_EP11_IN			0x00000800		// 0 (R/WC)
++#define USB_DEV_EP12_IN			0x00001000		// 0 (R/WC)
++#define USB_DEV_EP13_IN			0x00002000		// 0 (R/WC)
++#define USB_DEV_EP14_IN			0x00004000		// 0 (R/WC)
++#define USB_DEV_EP15_IN			0x00008000		// 0 (R/WC)
++#define USB_DEV_EP0_OUT			0x00010000		// 0 (R/WC)
++#define USB_DEV_EP1_OUT			0x00020000		// 0 (R/WC)
++#define USB_DEV_EP2_OUT			0x00040000		// 0 (R/WC)
++#define USB_DEV_EP3_OUT			0x00080000		// 0 (R/WC)
++#define USB_DEV_EP4_OUT			0x00100000		// 0 (R/WC)
++#define USB_DEV_EP5_OUT			0x00200000		// 0 (R/WC)
++#define USB_DEV_EP6_OUT			0x00400000		// 0 (R/WC)
++#define USB_DEV_EP7_OUT			0x00800000		// 0 (R/WC)
++#define USB_DEV_EP8_OUT			0x01000000		// 0 (R/WC)
++#define USB_DEV_EP9_OUT			0x02000000		// 0 (R/WC)
++#define USB_DEV_EP10_OUT		0x04000000		// 0 (R/WC)
++#define USB_DEV_EP11_OUT		0x08000000		// 0 (R/WC)
++#define USB_DEV_EP12_OUT		0x10000000		// 0 (R/WC)
++#define USB_DEV_EP13_OUT		0x20000000		// 0 (R/WC)
++#define USB_DEV_EP14_OUT		0x40000000		// 0 (R/WC)
++#define USB_DEV_EP15_OUT		0x80000000		// 0 (R/WC)
++
++// for USB_DEV_EP_INTR_MSK_REG
++#define USB_DEV_MSK_EP0_IN		0x00000001		// 0 (R/WC)
++#define USB_DEV_MSK_EP1_IN		0x00000002		// 0 (R/WC)
++#define USB_DEV_MSK_EP2_IN		0x00000004		// 0 (R/WC)
++#define USB_DEV_MSK_EP3_IN		0x00000008		// 0 (R/WC)
++#define USB_DEV_MSK_EP4_IN		0x00000010		// 0 (R/WC)
++#define USB_DEV_MSK_EP5_IN		0x00000020		// 0 (R/WC)
++#define USB_DEV_MSK_EP6_IN		0x00000040		// 0 (R/WC)
++#define USB_DEV_MSK_EP7_IN		0x00000080		// 0 (R/WC)
++#define USB_DEV_MSK_EP8_IN		0x00000100		// 0 (R/WC)
++#define USB_DEV_MSK_EP9_IN		0x00000200		// 0 (R/WC)
++#define USB_DEV_MSK_EP10_IN		0x00000400		// 0 (R/WC)
++#define USB_DEV_MSK_EP11_IN		0x00000800		// 0 (R/WC)
++#define USB_DEV_MSK_EP12_IN		0x00001000		// 0 (R/WC)
++#define USB_DEV_MSK_EP13_IN		0x00002000		// 0 (R/WC)
++#define USB_DEV_MSK_EP14_IN		0x00004000		// 0 (R/WC)
++#define USB_DEV_MSK_EP15_IN		0x00008000		// 0 (R/WC)
++#define USB_DEV_MSK_EP0_OUT		0x00010000		// 0 (R/WC)
++#define USB_DEV_MSK_EP1_OUT		0x00020000		// 0 (R/WC)
++#define USB_DEV_MSK_EP2_OUT		0x00040000		// 0 (R/WC)
++#define USB_DEV_MSK_EP3_OUT		0x00080000		// 0 (R/WC)
++#define USB_DEV_MSK_EP4_OUT		0x00100000		// 0 (R/WC)
++#define USB_DEV_MSK_EP5_OUT		0x00200000		// 0 (R/WC)
++#define USB_DEV_MSK_EP6_OUT		0x00400000		// 0 (R/WC)
++#define USB_DEV_MSK_EP7_OUT		0x00800000		// 0 (R/WC)
++#define USB_DEV_MSK_EP8_OUT		0x01000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP9_OUT		0x02000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP10_OUT		0x04000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP11_OUT		0x08000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP12_OUT		0x10000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP13_OUT		0x20000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP14_OUT		0x40000000		// 0 (R/WC)
++#define USB_DEV_MSK_EP15_OUT		0x80000000		// 0 (R/WC)
++
++// for USB_DEV_TEST_MODE_REG
++#define USB_DEV_TEST_MD			0x00000001		// 0 (RW)
++
++// for USB_UDC_REG
++#define USB_UDC_EP0_NUM			0x00000000
++#define USB_UDC_EP1_NUM			0x00000001
++#define USB_UDC_EP2_NUM			0x00000002
++#define USB_UDC_EP3_NUM			0x00000003
++#define USB_UDC_EP4_NUM			0x00000004
++#define USB_UDC_EP5_NUM			0x00000005
++#define USB_UDC_EP6_NUM			0x00000006
++#define USB_UDC_EP7_NUM			0x00000007
++#define USB_UDC_EP8_NUM			0x00000008
++#define USB_UDC_EP9_NUM			0x00000009
++#define USB_UDC_EP10_NUM		0x0000000a
++#define USB_UDC_EP11_NUM		0x0000000b
++#define USB_UDC_EP12_NUM		0x0000000c
++#define USB_UDC_EP13_NUM		0x0000000d
++#define USB_UDC_EP14_NUM		0x0000000e
++#define USB_UDC_EP15_NUM		0x0000000f
++
++#define USB_UDC_OUT			0x00000000
++#define USB_UDC_IN			0x00000010
++
++#define USB_UDC_CTRL			0x00000000
++#define USB_UDC_ISO			0x00000020
++#define USB_UDC_BULK			0x00000040
++#define USB_UDC_INTR			0x00000060
++
++#define USB_EP_CTRL_MAX_PKT_SZ		64	// max packet size of control in/out endpoint
++#define USB_EP_BULK_MAX_PKT_SZ_HI	512	// max packet size of bulk in/out endpoint (high speed)
++#define USB_EP_BULK_MAX_PKT_SZ_FU	64	// max packet size of bulk in/out endpoint (full speed)
++#define USB_EP_INTR_MAX_PKT_SZ		64	// max packet size of interrupt in/out endpoint
++#define USB_EP_ISO_MAX_PKT_SZ		512	// max packet size of isochronous in/out endpoint
++
++#define USB_EP_CTRLIN_MAX_PKT_SZ	USB_EP_CTRL_MAX_PKT_SZ
++#define USB_EP_CTRLOUT_MAX_PKT_SZ	USB_EP_CTRL_MAX_PKT_SZ
++#define USB_EP_BULKIN_MAX_PKT_SZ_HI	USB_EP_BULK_MAX_PKT_SZ_HI
++#define USB_EP_BULKOUT_MAX_PKT_SZ_HI	USB_EP_BULK_MAX_PKT_SZ_HI
++#define USB_EP_BULKIN_MAX_PKT_SZ_FU	USB_EP_BULK_MAX_PKT_SZ_FU
++#define USB_EP_BULKOUT_MAX_PKT_SZ_FU	USB_EP_BULK_MAX_PKT_SZ_FU
++#define USB_EP_INTRIN_MAX_PKT_SZ	USB_EP_INTR_MAX_PKT_SZ
++#define USB_EP_INTROUT_MAX_PKT_SZ	USB_EP_INTR_MAX_PKT_SZ
++#define USB_EP_ISOIN_MAX_PKT_SZ		USB_EP_ISO_MAX_PKT_SZ
++#define USB_EP_ISOOUT_MAX_PKT_SZ	USB_EP_ISO_MAX_PKT_SZ
++#define USB_EP_ISOIN_TRANSACTIONS	1
++#define USB_EP_ISOOUT_TRANSACTIONS	1
++
++#define USB_UDC_MAX_PKT_SZ		(0x1fff << 19)
++#define USB_UDC_CTRLIN_MAX_PKT_SZ	(USB_EP_CTRLIN_MAX_PKT_SZ << 19)
++#define USB_UDC_CTRLOUT_MAX_PKT_SZ	(USB_EP_CTRLOUT_MAX_PKT_SZ << 19)
++#define USB_UDC_BULKIN_MAX_PKT_SZ_HI	(USB_EP_BULKIN_MAX_PKT_SZ_HI << 19)
++#define USB_UDC_BULKOUT_MAX_PKT_SZ_HI	(USB_EP_BULKOUT_MAX_PKT_SZ_HI << 19)
++#define USB_UDC_BULKIN_MAX_PKT_SZ_FU	(USB_EP_BULKIN_MAX_PKT_SZ_FU << 19)
++#define USB_UDC_BULKOUT_MAX_PKT_SZ_FU	(USB_EP_BULKOUT_MAX_PKT_SZ_FU << 19)
++#define USB_UDC_INTRIN_MAX_PKT_SZ	(USB_EP_INTRIN_MAX_PKT_SZ << 19)
++#define USB_UDC_INTROUT_MAX_PKT_SZ	(USB_EP_INTROUT_MAX_PKT_SZ << 19)
++#define USB_UDC_ISOIN_MAX_PKT_SZ	(USB_EP_ISOIN_MAX_PKT_SZ << 19)
++#define USB_UDC_ISOOUT_MAX_PKT_SZ	(USB_EP_ISOOUT_MAX_PKT_SZ << 19)
++
++//-------------------------------------
++// DMA status quadlet fields
++//-------------------------------------
++// IN / OUT descriptor specific
++#define USB_DMA_RXTX_BYTES		0x0000ffff		// bit mask
++
++// SETUP descriptor specific
++#define USB_DMA_CFG_STS			0x0fff0000		// bit mask
++#define USB_DMA_CFG_NUM			0x0f000000		// bit mask
++#define USB_DMA_INTF_NUM		0x00f00000		// bit mask
++#define USB_DMA_ALT_SET			0x000f0000		// bitmask
++// ISO OUT descriptor only
++#define USB_DMA_FRM_NUM			0x07ff0000		// bit mask
++// IN / OUT descriptor specific
++#define USB_DMA_LAST			0x08000000		// bit mask
++
++#define USB_DMA_RXTX_STS		0x30000000		// bit mask
++#define USB_DMA_RXTX_SUCC		0x00000000		// 00
++#define USB_DMA_RXTX_DES_ERR		0x10000000		// 01
++#define USB_DMA_RXTX_BUF_ERR		0x30000000		// 11
++
++#define USB_DMA_BUF_STS 		0xc0000000		// bit mask
++#define USB_DMA_BUF_HOST_RDY		0x00000000		// 00
++#define USB_DMA_BUF_DMA_BUSY		0x40000000		// 01
++#define USB_DMA_BUF_DMA_DONE		0x80000000		// 10
++#define	USB_DMA_BUF_HOST_BUSY		0xc0000000		// 11
++
++/* ==========================================================================*/
++
++#endif
++
+diff --git a/arch/arm/mach-ambarella/include/plat/wdt.h b/arch/arm/mach-ambarella/include/plat/wdt.h
+new file mode 100644
+index 00000000..c43703b1
+--- /dev/null
++++ b/arch/arm/mach-ambarella/include/plat/wdt.h
+@@ -0,0 +1,62 @@
++/*
++ * arch/arm/plat-ambarella/include/plat/wdt.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __PLAT_AMBARELLA_WDT_H__
++#define __PLAT_AMBARELLA_WDT_H__
++
++/* ==========================================================================*/
++#define WDOG_OFFSET			0xC000
++#define WDOG_BASE			(APB_BASE + WDOG_OFFSET)
++#define WDOG_REG(x)			(WDOG_BASE + (x))
++
++/* ==========================================================================*/
++#define WDOG_STATUS_OFFSET		0x00
++#define WDOG_RELOAD_OFFSET		0x04
++#define WDOG_RESTART_OFFSET		0x08
++#define WDOG_CONTROL_OFFSET		0x0c
++#define WDOG_TIMEOUT_OFFSET		0x10
++#define WDOG_CLR_TMO_OFFSET		0x14
++#define WDOG_RST_WD_OFFSET		0x18
++
++#define WDOG_STATUS_REG			WDOG_REG(WDOG_STATUS_OFFSET)
++#define WDOG_RELOAD_REG			WDOG_REG(WDOG_RELOAD_OFFSET)
++#define WDOG_RESTART_REG		WDOG_REG(WDOG_RESTART_OFFSET)
++#define WDOG_CONTROL_REG		WDOG_REG(WDOG_CONTROL_OFFSET)
++#define WDOG_TIMEOUT_REG		WDOG_REG(WDOG_TIMEOUT_OFFSET)
++#define WDOG_CLR_TMO_REG		WDOG_REG(WDOG_CLR_TMO_OFFSET)
++#define WDOG_RST_WD_REG			WDOG_REG(WDOG_RST_WD_OFFSET)
++
++#define WDOG_CTR_INT_EN			0x00000004
++#define WDOG_CTR_RST_EN			0x00000002
++#define WDOG_CTR_EN			0x00000001
++
++/* WDOG_RESTART_REG only works with magic 0x4755.
++ * Set this value would transferred the value in
++ * WDOG_RELOAD_REG into WDOG_STATUS_REG and would
++ * not trigger the underflow event. */
++#define WDT_RESTART_VAL			0x4755
++
++/* ==========================================================================*/
++
++#endif /* __PLAT_AMBARELLA_WDT_H__ */
++
+diff --git a/arch/arm/mach-ambarella/init.c b/arch/arm/mach-ambarella/init.c
+new file mode 100644
+index 00000000..10234924
+--- /dev/null
++++ b/arch/arm/mach-ambarella/init.c
+@@ -0,0 +1,484 @@
++/*
++ * arch/arm/plat-ambarella/generic/init.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/proc_fs.h>
++#include <linux/memblock.h>
++#include <linux/export.h>
++#include <linux/clk.h>
++#include <linux/of_fdt.h>
++#include <linux/of_platform.h>
++#include <asm/cacheflush.h>
++#include <asm/system_info.h>
++#include <asm/mach/map.h>
++#include <mach/hardware.h>
++#include <mach/init.h>
++#include <plat/clk.h>
++#include <asm/hardware/cache-l2x0.h>
++
++/* ==========================================================================*/
++u64 ambarella_dmamask = DMA_BIT_MASK(32);
++EXPORT_SYMBOL(ambarella_dmamask);
++
++/* ==========================================================================*/
++enum {
++	AMBARELLA_IO_DESC_AHB_ID = 0,
++	AMBARELLA_IO_DESC_APB_ID,
++	AMBARELLA_IO_DESC_PPM_ID,
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
++	AMBARELLA_IO_DESC_AXI_ID,
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
++	AMBARELLA_IO_DESC_DRAMC_ID,
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT)
++	AMBARELLA_IO_DESC_CRYPT_ID,
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
++	AMBARELLA_IO_DESC_AHB64_ID,
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
++	AMBARELLA_IO_DESC_DBGBUS_ID,
++	AMBARELLA_IO_DESC_DBGFMEM_ID,
++#endif
++	AMBARELLA_IO_DESC_FRAMEBUF_ID,
++	AMBARELLA_IO_DESC_DSP_ID,
++};
++
++struct ambarella_mem_map_desc {
++	char		name[8];
++	struct map_desc	io_desc;
++};
++
++static struct ambarella_mem_map_desc ambarella_io_desc[] = {
++	[AMBARELLA_IO_DESC_AHB_ID] = {
++		.name		= "AHB",
++		.io_desc	= {
++			.virtual	= AHB_BASE,
++			.pfn		= __phys_to_pfn(AHB_PHYS_BASE),
++			.length		= AHB_SIZE,
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++			.type		= MT_DEVICE_NONSHARED,
++#else
++			.type		= MT_DEVICE,
++#endif
++			},
++	},
++	[AMBARELLA_IO_DESC_APB_ID] = {
++		.name		= "APB",
++		.io_desc	= {
++			.virtual	= APB_BASE,
++			.pfn		= __phys_to_pfn(APB_PHYS_BASE),
++			.length		= APB_SIZE,
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++			.type		= MT_DEVICE_NONSHARED,
++#else
++			.type		= MT_DEVICE,
++#endif
++			},
++	},
++	[AMBARELLA_IO_DESC_PPM_ID] = {
++		.name		= "PPM",	/*Private Physical Memory*/
++		.io_desc		= {
++			.virtual	= AHB_BASE - CONFIG_AMBARELLA_PPM_SIZE,
++			.pfn		= __phys_to_pfn(DEFAULT_MEM_START),
++			.length		= CONFIG_AMBARELLA_PPM_SIZE,
++#if defined(CONFIG_AMBARELLA_PPM_UNCACHED)
++			.type		= MT_DEVICE,
++#else
++			.type		= MT_MEMORY,
++#endif
++			},
++	},
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
++	[AMBARELLA_IO_DESC_AXI_ID] = {
++		.name		= "AXI",
++		.io_desc	= {
++			.virtual	= AXI_BASE,
++			.pfn		= __phys_to_pfn(AXI_PHYS_BASE),
++			.length		= AXI_SIZE,
++			.type		= MT_DEVICE,
++			},
++	},
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
++	[AMBARELLA_IO_DESC_DRAMC_ID] = {
++		.name		= "DRAMC",
++		.io_desc	= {
++			.virtual= DRAMC_BASE,
++			.pfn	= __phys_to_pfn(DRAMC_PHYS_BASE),
++			.length	= DRAMC_SIZE,
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++			.type	= MT_DEVICE_NONSHARED,
++#else
++			.type	= MT_DEVICE,
++#endif
++			},
++	},
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT)
++	[AMBARELLA_IO_DESC_CRYPT_ID] = {
++		.name		= "CRYPT",
++		.io_desc	= {
++			.virtual= CRYPT_BASE,
++			.pfn	= __phys_to_pfn(CRYPT_PHYS_BASE),
++			.length	= CRYPT_SIZE,
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++			.type	= MT_DEVICE_NONSHARED,
++#else
++			.type	= MT_DEVICE,
++#endif
++			},
++	},
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
++	[AMBARELLA_IO_DESC_AHB64_ID] = {
++		.name		= "AHB64",
++		.io_desc	= {
++			.virtual= AHB64_BASE,
++			.pfn	= __phys_to_pfn(AHB64_PHYS_BASE),
++			.length	= AHB64_SIZE,
++			.type	= MT_DEVICE,
++			},
++	},
++#endif
++#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
++	[AMBARELLA_IO_DESC_DBGBUS_ID] = {
++		.name		= "DBGBUS",
++		.io_desc	= {
++			.virtual= DBGBUS_BASE,
++			.pfn	= __phys_to_pfn(DBGBUS_PHYS_BASE),
++			.length	= DBGBUS_SIZE,
++			.type	= MT_DEVICE,
++			},
++	},
++	[AMBARELLA_IO_DESC_DBGFMEM_ID] = {
++		.name		= "DBGFMEM",
++		.io_desc	= {
++			.virtual= DBGFMEM_BASE,
++			.pfn	= __phys_to_pfn(DBGFMEM_PHYS_BASE),
++			.length	= DBGFMEM_SIZE,
++			.type	= MT_DEVICE,
++			},
++	},
++#endif
++	[AMBARELLA_IO_DESC_DSP_ID] = {
++		.name		= "IAV",
++		.io_desc	= {
++			.virtual	= 0x00000000,
++			.pfn		= 0x00000000,
++			.length		= 0x00000000,
++			},
++	},
++	[AMBARELLA_IO_DESC_FRAMEBUF_ID] = {
++		.name		= "FRAMEBUF",
++		.io_desc	= {
++			.virtual	= 0x00000000,
++			.pfn		= 0x00000000,
++			.length		= 0x00000000,
++			},
++	},
++};
++
++
++static int __init ambarella_dt_scan_iavmem(unsigned long node,
++			const char *uname,  int depth, void *data)
++{
++	const char *type;
++	__be32 *reg;
++	unsigned long len;
++	struct ambarella_mem_map_desc *iavmem_desc;
++
++	type = of_get_flat_dt_prop(node, "device_type", NULL);
++	if (type == NULL || strcmp(type, "iavmem") != 0)
++		return 0;
++
++	reg = of_get_flat_dt_prop(node, "reg", &len);
++	if (WARN_ON(!reg || (len != 2 * sizeof(unsigned long))))
++		return 0;
++
++	iavmem_desc = &ambarella_io_desc[AMBARELLA_IO_DESC_DSP_ID];
++	iavmem_desc->io_desc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
++	iavmem_desc->io_desc.length = be32_to_cpu(reg[1]);
++
++	pr_info("Ambarella:   IAVMEM = 0x%08x[          ],0x%08x\n",
++			be32_to_cpu(reg[0]), be32_to_cpu(reg[1]));
++
++	return 1;
++}
++
++static int __init ambarella_dt_scan_fbmem(unsigned long node,
++			const char *uname,  int depth, void *data)
++{
++	const char *type;
++	__be32 *reg;
++	unsigned long len;
++	struct ambarella_mem_map_desc *fbmem_desc;
++
++	type = of_get_flat_dt_prop(node, "device_type", NULL);
++	if (type == NULL || strcmp(type, "fbmem") != 0)
++		return 0;
++
++	reg = of_get_flat_dt_prop(node, "reg", &len);
++	if (WARN_ON(!reg || (len != 2 * sizeof(unsigned long))))
++		return 0;
++
++	fbmem_desc = &ambarella_io_desc[AMBARELLA_IO_DESC_FRAMEBUF_ID];
++	fbmem_desc->io_desc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
++	fbmem_desc->io_desc.length = be32_to_cpu(reg[1]);
++
++	pr_info("Ambarella:    FBMEM = 0x%08x[          ],0x%08x\n",
++			be32_to_cpu(reg[0]), be32_to_cpu(reg[1]));
++
++	return 1;
++}
++
++void __init ambarella_map_io(void)
++{
++	u32 i, iop, ios, iov;
++
++	for (i = 0; i < AMBARELLA_IO_DESC_DSP_ID; i++) {
++		iop = __pfn_to_phys(ambarella_io_desc[i].io_desc.pfn);
++		ios = ambarella_io_desc[i].io_desc.length;
++		iov = ambarella_io_desc[i].io_desc.virtual;
++		if (ios > 0) {
++			iotable_init(&(ambarella_io_desc[i].io_desc), 1);
++			pr_info("Ambarella: %8s = 0x%08x[0x%08x],0x%08x %d\n",
++				ambarella_io_desc[i].name, iop, iov, ios,
++				ambarella_io_desc[i].io_desc.type);
++		}
++	}
++
++	/* scan and hold the memory information for IAV */
++	of_scan_flat_dt(ambarella_dt_scan_iavmem, NULL);
++	/* scan and hold the memory information for FRAMEBUFFER */
++	of_scan_flat_dt(ambarella_dt_scan_fbmem, NULL);
++}
++
++/* ==========================================================================*/
++static struct proc_dir_entry *ambarella_proc_dir = NULL;
++
++int __init ambarella_create_proc_dir(void)
++{
++	int ret_val = 0;
++
++	ambarella_proc_dir = proc_mkdir("ambarella", NULL);
++	if (!ambarella_proc_dir)
++		ret_val = -ENOMEM;
++
++	return ret_val;
++}
++
++struct proc_dir_entry *get_ambarella_proc_dir(void)
++{
++	return ambarella_proc_dir;
++}
++EXPORT_SYMBOL(get_ambarella_proc_dir);
++
++
++/* ==========================================================================*/
++void __init ambarella_init_machine(void)
++{
++	int ret_val = 0;
++
++#if defined(CONFIG_PLAT_AMBARELLA_LOWER_ARM_PLL)
++	amba_rct_writel(SCALER_ARM_ASYNC_REG, 0xF);
++#endif
++
++	ret_val = ambarella_create_proc_dir();
++	BUG_ON(ret_val != 0);
++
++	ret_val = ambarella_clk_init();
++	BUG_ON(ret_val != 0);
++
++	ret_val = ambarella_init_fio();
++	BUG_ON(ret_val != 0);
++
++	ret_val = ambarella_init_fb();
++	BUG_ON(ret_val != 0);
++
++	ret_val = ambarella_init_pm();
++	BUG_ON(ret_val != 0);
++
++	ret_val = ambarella_init_audio();
++	BUG_ON(ret_val != 0);
++	l2x0_of_init((1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT)
++			| (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT),  ~0);
++
++	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
++}
++
++void ambarella_restart_machine(char mode, const char *cmd)
++{
++	local_irq_disable();
++	local_fiq_disable();
++	flush_cache_all();
++	amba_rct_writel(SOFT_OR_DLL_RESET_REG, 0x2);
++	amba_rct_writel(SOFT_OR_DLL_RESET_REG, 0x3);
++}
++
++/* ==========================================================================*/
++
++static int __init parse_system_revision(char *p)
++{
++	system_rev = simple_strtoul(p, NULL, 0);
++	return 0;
++}
++early_param("system_rev", parse_system_revision);
++
++u32 ambarella_phys_to_virt(u32 paddr)
++{
++	int					i;
++	u32					phystart;
++	u32					phylength;
++	u32					phyoffset;
++	u32					vstart;
++
++	for (i = 0; i < ARRAY_SIZE(ambarella_io_desc); i++) {
++		phystart = __pfn_to_phys(ambarella_io_desc[i].io_desc.pfn);
++		phylength = ambarella_io_desc[i].io_desc.length;
++		vstart = ambarella_io_desc[i].io_desc.virtual;
++		if ((paddr >= phystart) && (paddr < (phystart + phylength))) {
++			phyoffset = paddr - phystart;
++			return (vstart + phyoffset);
++		}
++	}
++
++	return __amb_raw_phys_to_virt(paddr);
++}
++EXPORT_SYMBOL(ambarella_phys_to_virt);
++
++u32 ambarella_virt_to_phys(u32 vaddr)
++{
++	int					i;
++	u32					phystart;
++	u32					vlength;
++	u32					voffset;
++	u32					vstart;
++
++	for (i = 0; i < ARRAY_SIZE(ambarella_io_desc); i++) {
++		phystart = __pfn_to_phys(ambarella_io_desc[i].io_desc.pfn);
++		vlength = ambarella_io_desc[i].io_desc.length;
++		vstart = ambarella_io_desc[i].io_desc.virtual;
++		if ((vaddr >= vstart) && (vaddr < (vstart + vlength))) {
++			voffset = vaddr - vstart;
++			return (phystart + voffset);
++		}
++	}
++
++	return __amb_raw_virt_to_phys(vaddr);
++}
++EXPORT_SYMBOL(ambarella_virt_to_phys);
++
++u32 get_ambarella_fbmem_phys(void)
++{
++	return __pfn_to_phys(
++		ambarella_io_desc[AMBARELLA_IO_DESC_FRAMEBUF_ID].io_desc.pfn);
++}
++EXPORT_SYMBOL(get_ambarella_fbmem_phys);
++
++u32 get_ambarella_fbmem_size(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_FRAMEBUF_ID].io_desc.length;
++}
++EXPORT_SYMBOL(get_ambarella_fbmem_size);
++
++u32 get_ambarella_iavmem_phys(void)
++{
++	return __pfn_to_phys(
++		ambarella_io_desc[AMBARELLA_IO_DESC_DSP_ID].io_desc.pfn);
++}
++EXPORT_SYMBOL(get_ambarella_iavmem_phys);
++
++u32 get_ambarella_iavmem_size(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_DSP_ID].io_desc.length;
++}
++EXPORT_SYMBOL(get_ambarella_iavmem_size);
++
++u32 get_ambarella_ppm_phys(void)
++{
++	return __pfn_to_phys(
++		ambarella_io_desc[AMBARELLA_IO_DESC_PPM_ID].io_desc.pfn);
++}
++EXPORT_SYMBOL(get_ambarella_ppm_phys);
++
++u32 get_ambarella_ppm_virt(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_PPM_ID].io_desc.virtual;
++}
++EXPORT_SYMBOL(get_ambarella_ppm_virt);
++
++u32 get_ambarella_ppm_size(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_PPM_ID].io_desc.length;
++}
++EXPORT_SYMBOL(get_ambarella_ppm_size);
++
++u32 get_ambarella_ahb_phys(void)
++{
++	return __pfn_to_phys(
++		ambarella_io_desc[AMBARELLA_IO_DESC_AHB_ID].io_desc.pfn);
++}
++EXPORT_SYMBOL(get_ambarella_ahb_phys);
++
++u32 get_ambarella_ahb_virt(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_AHB_ID].io_desc.virtual;
++}
++EXPORT_SYMBOL(get_ambarella_ahb_virt);
++
++u32 get_ambarella_ahb_size(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_AHB_ID].io_desc.length;
++}
++EXPORT_SYMBOL(get_ambarella_ahb_size);
++
++u32 get_ambarella_apb_phys(void)
++{
++	return __pfn_to_phys(
++		ambarella_io_desc[AMBARELLA_IO_DESC_APB_ID].io_desc.pfn);
++}
++EXPORT_SYMBOL(get_ambarella_apb_phys);
++
++u32 get_ambarella_apb_virt(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_APB_ID].io_desc.virtual;
++}
++EXPORT_SYMBOL(get_ambarella_apb_virt);
++
++u32 get_ambarella_apb_size(void)
++{
++	return ambarella_io_desc[AMBARELLA_IO_DESC_APB_ID].io_desc.length;
++}
++EXPORT_SYMBOL(get_ambarella_apb_size);
++
++u32 ambarella_get_poc(void)
++{
++	return amba_rct_readl(SYS_CONFIG_REG);
++}
++EXPORT_SYMBOL(ambarella_get_poc);
++
++
+diff --git a/arch/arm/mach-ambarella/misc/Makefile b/arch/arm/mach-ambarella/misc/Makefile
+new file mode 100644
+index 00000000..69224ee9
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/Makefile
+@@ -0,0 +1,35 @@
++#
++# arch/arm/plat-ambarella/misc/Makefile
++#
++# Author: Anthony Ginger <hfjiang@ambarella.com>
++#
++# Copyright (C) 2004-2011, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++obj-y						+= hwlock.o
++obj-y						+= audio.o
++obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA)	+= gdma.o
++obj-y						+= ambasyncproc.o
++obj-$(CONFIG_AMBARELLA_SUPPORT_AMBENCH)		+= ambench.o
++obj-y						+= ambevent.o
++obj-y						+= ambfb.o
++obj-y						+= ambsyncproc.o
++obj-y						+= event.o
++obj-y						+= iav_helper.o
++obj-$(CONFIG_AMBARELLA_TIMER_HIGHRES)		+= highres_timer.o
++obj-y						+= pmu.o
++
+diff --git a/arch/arm/mach-ambarella/misc/ambasyncproc.c b/arch/arm/mach-ambarella/misc/ambasyncproc.c
+new file mode 100644
+index 00000000..a2d25438
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/ambasyncproc.c
+@@ -0,0 +1,120 @@
++/*
++ * arch/arm/plat-ambarella/misc/ambasyncproc.c
++ *
++ * Author: Zhenwu Xue, <zwxue@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++
++#include <plat/ambasyncproc.h>
++#include <mach/hardware.h>
++
++#define GET_PROC_DATA_FROM_FILEP(filp)	\
++	(struct amb_async_proc_info *)(PDE_DATA(filp->f_path.dentry->d_inode))
++
++static int amb_async_proc_open(struct inode *inode, struct file *filp)
++{
++	struct amb_async_proc_info	*pinfo;
++
++	pinfo = GET_PROC_DATA_FROM_FILEP(filp);
++
++	mutex_lock(&pinfo->op_mutex);
++	pinfo->use_count++;
++	filp->f_op = &pinfo->fops;
++	filp->private_data = pinfo->private_data;
++	mutex_unlock(&pinfo->op_mutex);
++
++	return 0;
++}
++
++static int amb_async_proc_fasync(int fd, struct file * filp, int on)
++{
++	int				retval;
++	struct amb_async_proc_info	*pinfo;
++
++	pinfo = GET_PROC_DATA_FROM_FILEP(filp);
++
++	mutex_lock(&pinfo->op_mutex);
++	retval = fasync_helper(fd, filp, on, &pinfo->fasync_queue);
++	mutex_unlock(&pinfo->op_mutex);
++
++	return retval;
++}
++
++static int amb_async_proc_release(struct inode *inode, struct file *filp)
++{
++	int				retval;
++	struct amb_async_proc_info	*pinfo;
++
++	pinfo = GET_PROC_DATA_FROM_FILEP(filp);
++
++	mutex_lock(&pinfo->op_mutex);
++	retval = fasync_helper(-1, filp, 0, &pinfo->fasync_queue);
++	pinfo->use_count--;
++	mutex_unlock(&pinfo->op_mutex);
++
++	return retval;
++}
++
++int amb_async_proc_create(struct amb_async_proc_info *pinfo)
++{
++	int				retval = 0;
++	struct proc_dir_entry		*entry;
++
++	if (!pinfo) {
++		retval = -EINVAL;
++		goto amb_async_proc_create_exit;
++	}
++
++	pinfo->fops.open = amb_async_proc_open;
++	pinfo->fops.fasync = amb_async_proc_fasync;
++	pinfo->fops.release = amb_async_proc_release;
++	mutex_init(&pinfo->op_mutex);
++	pinfo->use_count = 0;
++	pinfo->fasync_queue = NULL;
++
++	entry = proc_create_data(pinfo->proc_name, S_IRUGO,
++		get_ambarella_proc_dir(), &pinfo->fops, pinfo);
++	if (!entry) {
++		retval = -EINVAL;
++	}
++
++amb_async_proc_create_exit:
++	return retval;
++}
++EXPORT_SYMBOL(amb_async_proc_create);
++
++int amb_async_proc_remove(struct amb_async_proc_info *pinfo)
++{
++	int				retval = 0;
++
++	if (!pinfo) {
++		retval = -EINVAL;
++	} else {
++		remove_proc_entry(pinfo->proc_name, get_ambarella_proc_dir());
++	}
++
++	return retval;
++}
++EXPORT_SYMBOL(amb_async_proc_remove);
++
+diff --git a/arch/arm/mach-ambarella/misc/ambench.c b/arch/arm/mach-ambarella/misc/ambench.c
+new file mode 100644
+index 00000000..e807c3d6
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/ambench.c
+@@ -0,0 +1,198 @@
++/*
++ * arch/arm/plat-ambarella/misc/ambench.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2011, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/io.h>
++#include <linux/cpu.h>
++#include <linux/clk.h>
++
++#include <asm/uaccess.h>
++#include <asm/system_info.h>
++
++#include <mach/hardware.h>
++#include <plat/clk.h>
++
++/* ==========================================================================*/
++#ifdef MODULE_PARAM_PREFIX
++#undef MODULE_PARAM_PREFIX
++#endif
++#define MODULE_PARAM_PREFIX			"ambarella_config."
++
++#define AMBENCH_MAX_CMD_LENGTH			(32)
++
++/* ==========================================================================*/
++typedef void (*ambarella_ambench_fn_t)(void);
++
++struct ambarella_ambench_info {
++	char name[32];
++	ambarella_ambench_fn_t fn;
++};
++
++/* ==========================================================================*/
++static void ambench_apbread(void);
++
++/* ==========================================================================*/
++static const char ambench_proc_name[] = "ambench";
++
++static struct ambarella_ambench_info ambench_list[] = {
++	{"APBRead", ambench_apbread},
++	{"", NULL}
++};
++
++/* ==========================================================================*/
++static int ambarella_ambench_proc_write(struct file *file,
++	const char __user *buffer, size_t count, loff_t *ppos)
++{
++	int retval = 0;
++	char str[AMBENCH_MAX_CMD_LENGTH];
++	int i;
++
++	i = (count < AMBENCH_MAX_CMD_LENGTH) ? count : AMBENCH_MAX_CMD_LENGTH;
++	if (copy_from_user(str, buffer, i)) {
++		pr_err("%s: copy_from_user fail!\n", __func__);
++		retval = -EFAULT;
++		goto ambarella_ambench_proc_write_exit;
++	}
++	str[i - 1] = 0;
++
++	for (i = 0; i < ARRAY_SIZE(ambench_list); i++) {
++		if (ambench_list[i].fn == NULL) {
++			break;
++		}
++		if (strlen(str) == strlen(ambench_list[i].name)
++			&& strcmp(str, ambench_list[i].name) == 0) {
++			ambench_list[i].fn();
++			break;
++		}
++	}
++
++	if (strcmp(str, "all") == 0) {
++		for (i = 0; i < ARRAY_SIZE(ambench_list); i++) {
++			if (ambench_list[i].fn == NULL) {
++				break;
++			}
++			ambench_list[i].fn();
++		}
++	}
++
++	if (!retval)
++		retval = count;
++
++ambarella_ambench_proc_write_exit:
++	return retval;
++}
++
++static int ambarella_ambench_proc_show(struct seq_file *m, void *v)
++{
++	int retlen = 0;
++	int i;
++
++	retlen = seq_printf(m, "\nPossible Benchmark:\n");
++	for (i = 0; i < ARRAY_SIZE(ambench_list); i++) {
++		if (ambench_list[i].fn == NULL) {
++			break;
++		}
++		retlen += seq_printf(m, "\t%s\n", ambench_list[i].name);
++	}
++
++	return retlen;
++}
++
++static int ambarella_ambench_proc_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, ambarella_ambench_proc_show, PDE_DATA(inode));
++}
++
++static const struct file_operations proc_ambench_fops = {
++	.open = ambarella_ambench_proc_open,
++	.read = seq_read,
++	.llseek = seq_lseek,
++	.write = ambarella_ambench_proc_write,
++};
++
++/* ==========================================================================*/
++static int __init ambarella_init_ambench(void)
++{
++	int retval = 0;
++
++	proc_create_data(ambench_proc_name, (S_IRUGO | S_IWUSR),
++		get_ambarella_proc_dir(), &proc_ambench_fops, NULL);
++
++	return retval;
++}
++late_initcall(ambarella_init_ambench);
++
++/* ==========================================================================*/
++#define APBREAD_RELOAD_NUM			(0x10000000)
++static void ambench_apbread(void)
++{
++	u64					raw_counter = 0;
++	u64					amba_counter = 0;
++	unsigned long				flags;
++
++	disable_nonboot_cpus();
++	local_irq_save(flags);
++
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
++	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
++	amba_writel(TIMER1_RELOAD_REG, 0x0);
++	amba_writel(TIMER1_MATCH1_REG, 0x0);
++	amba_writel(TIMER1_MATCH2_REG, 0x0);
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);
++
++	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
++	do {
++		raw_counter++;
++	} while(__raw_readl((const volatile void *)TIMER1_STATUS_REG));
++
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
++	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
++	amba_writel(TIMER1_RELOAD_REG, 0x0);
++	amba_writel(TIMER1_MATCH1_REG, 0x0);
++	amba_writel(TIMER1_MATCH2_REG, 0x0);
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);
++
++	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
++	do {
++		amba_counter++;
++	} while(amba_readl(TIMER1_STATUS_REG));
++	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
++
++	local_irq_restore(flags);
++	enable_nonboot_cpus();
++
++	raw_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
++	do_div(raw_counter, APBREAD_RELOAD_NUM);
++	amba_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
++	do_div(amba_counter, APBREAD_RELOAD_NUM);
++	pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n",
++		cpu_architecture(), raw_counter);
++	pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n",
++		cpu_architecture(), amba_counter);
++}
++
+diff --git a/arch/arm/mach-ambarella/misc/ambevent.c b/arch/arm/mach-ambarella/misc/ambevent.c
+new file mode 100644
+index 00000000..5ba91a74
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/ambevent.c
+@@ -0,0 +1,111 @@
++/*
++ * arch/arm/plat-ambarella/misc/ambevent.c
++ *
++ * Author: Zhenwu Xue, <zwxue@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/export.h>
++#include <linux/errno.h>
++#include <linux/bootmem.h>
++#include <linux/platform_device.h>
++#include <plat/ambevent.h>
++
++int amb_event_pool_init(struct amb_event_pool *pool)
++{
++	if (!pool)
++		return -EINVAL;
++
++	memset(pool, 0, sizeof(struct amb_event_pool));
++	mutex_init(&pool->op_mutex);
++	return 0;
++}
++EXPORT_SYMBOL(amb_event_pool_init);
++
++int amb_event_pool_affuse(struct amb_event_pool *pool,
++	struct amb_event event)
++{
++	if (!pool)
++		return -EINVAL;
++
++	if (event.type == AMB_EV_NONE)
++		return 0;
++
++	mutex_lock(&pool->op_mutex);
++	pool->ev_sno++;
++	pool->events[pool->ev_index].sno = pool->ev_sno;
++	pool->events[pool->ev_index].time_code = 0;		//FIX ME
++	pool->events[pool->ev_index].type = event.type;
++	memcpy(pool->events[pool->ev_index].data, event.data, sizeof(event.data));
++	pool->ev_index++;
++	mutex_unlock(&pool->op_mutex);
++
++	return 0;
++}
++EXPORT_SYMBOL(amb_event_pool_affuse);
++
++int amb_event_pool_query_index(struct amb_event_pool *pool)
++{
++	unsigned char			index;
++
++	if (!pool)
++		return -EINVAL;
++
++	mutex_lock(&pool->op_mutex);
++	index = pool->ev_index - 1;
++	mutex_unlock(&pool->op_mutex);
++
++	return (int)index;
++}
++EXPORT_SYMBOL(amb_event_pool_query_index);
++
++int amb_event_pool_query_event(struct amb_event_pool *pool,
++	struct amb_event *event, unsigned char index)
++{
++	int				retval = 0;
++
++	if (!pool || !event)
++		return -EINVAL;
++
++	mutex_lock(&pool->op_mutex);
++
++	if (pool->events[index].type == AMB_EV_NONE) {
++		retval = -EAGAIN;
++		goto amb_event_pool_query_event_exit;
++	}
++
++	if (index == pool->ev_index) {
++		retval = -EAGAIN;
++		goto amb_event_pool_query_event_exit;
++	}
++
++	*event = pool->events[index];
++
++amb_event_pool_query_event_exit:
++	mutex_unlock(&pool->op_mutex);
++	return retval;
++}
++EXPORT_SYMBOL(amb_event_pool_query_event);
++
++int amb_event_report_uevent(struct kobject *kobj, enum kobject_action action,
++		       char *envp_ext[])
++{
++	return kobject_uevent_env(kobj, action, envp_ext);
++}
++EXPORT_SYMBOL(amb_event_report_uevent);
++
+diff --git a/arch/arm/mach-ambarella/misc/ambfb.c b/arch/arm/mach-ambarella/misc/ambfb.c
+new file mode 100644
+index 00000000..4683653f
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/ambfb.c
+@@ -0,0 +1,223 @@
++/*
++ * arch/arm/plat-ambarella/video/ambfb.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/bootmem.h>
++#include <linux/delay.h>
++#include <linux/irq.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/page.h>
++#include <asm/io.h>
++#include <asm/setup.h>
++
++#include <asm/mach/map.h>
++
++#include <linux/fb.h>
++
++#include <mach/hardware.h>
++#include <plat/fb.h>
++
++/* ==========================================================================*/
++static struct ambarella_platform_fb ambarella_platform_fb0 = {
++	.screen_var		= {
++		.xres		= 720,
++		.yres		= 480,
++		.xres_virtual	= 720,
++		.yres_virtual	= 480,
++		.xoffset	= 0,
++		.yoffset	= 0,
++		.bits_per_pixel = 8,
++		.red		= {.offset = 0, .length = 8, .msb_right = 0},
++		.green		= {.offset = 0, .length = 8, .msb_right = 0},
++		.blue		= {.offset = 0, .length = 8, .msb_right = 0},
++		.activate	= FB_ACTIVATE_NOW,
++		.height		= -1,
++		.width		= -1,
++		.pixclock	= 36101,
++		.left_margin	= 24,
++		.right_margin	= 96,
++		.upper_margin	= 10,
++		.lower_margin	= 32,
++		.hsync_len	= 40,
++		.vsync_len	= 3,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++	.screen_fix		= {
++		.id		= "Ambarella FB",
++		.type		= FB_TYPE_PACKED_PIXELS,
++		.visual		= FB_VISUAL_PSEUDOCOLOR,
++		.xpanstep	= 1,
++		.ypanstep	= 1,
++		.ywrapstep	= 1,
++		.accel		= FB_ACCEL_NONE,
++		.line_length	= 0,
++		.smem_start	= 0,
++		.smem_len	= 0,
++	},
++	.dsp_status		= AMBA_DSP_UNKNOWN_MODE,
++	.fb_status		= AMBFB_UNKNOWN_MODE,
++	.color_format		= AMBFB_COLOR_CLUT_8BPP,
++	.conversion_buf		= {
++		.available	= 0,
++		.ping_buf	= NULL,
++		.ping_buf_size	= 0,
++		.pong_buf	= NULL,
++		.pong_buf_size	= 0,
++		},
++	.use_prealloc		= 0,
++	.prealloc_line_length	= 0,
++
++	.pan_display		= NULL,
++	.setcmap		= NULL,
++	.check_var		= NULL,
++	.set_par		= NULL,
++	.set_blank		= NULL,
++
++	.proc_fb_info		= NULL,
++	.proc_file		= NULL,
++};
++
++static struct ambarella_platform_fb ambarella_platform_fb1 = {
++	.screen_var		= {
++		.xres		= 720,
++		.yres		= 480,
++		.xres_virtual	= 720,
++		.yres_virtual	= 480,
++		.xoffset	= 0,
++		.yoffset	= 0,
++		.bits_per_pixel = 8,
++		.red		= {.offset = 0, .length = 8, .msb_right = 0},
++		.green		= {.offset = 0, .length = 8, .msb_right = 0},
++		.blue		= {.offset = 0, .length = 8, .msb_right = 0},
++		.activate	= FB_ACTIVATE_NOW,
++		.height		= -1,
++		.width		= -1,
++		.pixclock	= 36101,
++		.left_margin	= 24,
++		.right_margin	= 96,
++		.upper_margin	= 10,
++		.lower_margin	= 32,
++		.hsync_len	= 40,
++		.vsync_len	= 3,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++	.screen_fix		= {
++		.id		= "Ambarella FB",
++		.type		= FB_TYPE_PACKED_PIXELS,
++		.visual		= FB_VISUAL_PSEUDOCOLOR,
++		.xpanstep	= 1,
++		.ypanstep	= 1,
++		.ywrapstep	= 1,
++		.accel		= FB_ACCEL_NONE,
++		.line_length	= 0,
++		.smem_start	= 0,
++		.smem_len	= 0,
++	},
++	.dsp_status		= AMBA_DSP_UNKNOWN_MODE,
++	.fb_status		= AMBFB_UNKNOWN_MODE,
++	.color_format		= AMBFB_COLOR_CLUT_8BPP,
++	.conversion_buf		= {
++		.available	= 0,
++		.ping_buf	= NULL,
++		.ping_buf_size	= 0,
++		.pong_buf	= NULL,
++		.pong_buf_size	= 0,
++		},
++	.use_prealloc		= 0,
++	.prealloc_line_length	= 0,
++
++	.pan_display		= NULL,
++	.setcmap		= NULL,
++	.check_var		= NULL,
++	.set_par		= NULL,
++	.set_blank		= NULL,
++
++	.proc_fb_info		= NULL,
++	.proc_file		= NULL,
++};
++
++struct ambarella_platform_fb *ambfb_data_ptr[] = {
++	&ambarella_platform_fb0,
++	&ambarella_platform_fb1,
++};
++EXPORT_SYMBOL(ambfb_data_ptr);
++
++int ambarella_fb_get_platform_info(u32 fb_id,
++	struct ambarella_platform_fb *platform_info)
++{
++	struct ambarella_platform_fb *ambfb_data;
++
++	if (fb_id > ARRAY_SIZE(ambfb_data_ptr))
++		return -EPERM;
++
++	ambfb_data = ambfb_data_ptr[fb_id];
++
++	mutex_lock(&ambfb_data->lock);
++	memcpy(platform_info, ambfb_data, sizeof(struct ambarella_platform_fb));
++	mutex_unlock(&ambfb_data->lock);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_fb_get_platform_info);
++
++int ambarella_fb_set_iav_info(u32 fb_id, struct ambarella_fb_iav_info *iav)
++{
++	struct ambarella_platform_fb *ambfb_data;
++
++	if (fb_id > ARRAY_SIZE(ambfb_data_ptr))
++		return -EPERM;
++
++	ambfb_data = ambfb_data_ptr[fb_id];
++
++	mutex_lock(&ambfb_data->lock);
++	ambfb_data->screen_var = iav->screen_var;
++	ambfb_data->screen_fix = iav->screen_fix;
++	ambfb_data->pan_display = iav->pan_display;
++	ambfb_data->setcmap = iav->setcmap;
++	ambfb_data->check_var = iav->check_var;
++	ambfb_data->set_par = iav->set_par;
++	ambfb_data->set_blank = iav->set_blank;
++	ambfb_data->dsp_status = iav->dsp_status;
++	mutex_unlock(&ambfb_data->lock);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_fb_set_iav_info);
++
++int __init ambarella_init_fb(void)
++{
++	struct ambarella_platform_fb *ambfb_data;
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(ambfb_data_ptr); i++) {
++		ambfb_data = ambfb_data_ptr[i];
++		mutex_init(&ambfb_data->lock);
++		init_waitqueue_head(&ambfb_data->proc_wait);
++	}
++
++	return 0;
++}
++
+diff --git a/arch/arm/mach-ambarella/misc/ambsyncproc.c b/arch/arm/mach-ambarella/misc/ambsyncproc.c
+new file mode 100644
+index 00000000..3358e94f
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/ambsyncproc.c
+@@ -0,0 +1,233 @@
++/*
++ * arch/arm/plat-ambarella/misc/sync_proc.c
++ *
++ * Author: Anthony Ginger, <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/idr.h>
++#include <linux/proc_fs.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++#include <linux/export.h>
++
++#include <asm/uaccess.h>
++#include <asm/page.h>
++#include <asm/atomic.h>
++
++#include <plat/ambsyncproc.h>
++
++int ambsync_proc_hinit(struct ambsync_proc_hinfo *hinfo)
++{
++	hinfo->maxid = AMBA_SYNC_PROC_MAX_ID;
++	init_waitqueue_head(&hinfo->sync_proc_head);
++	atomic_set(&hinfo->sync_proc_flag, 0);
++	idr_init(&hinfo->sync_proc_idr);
++	mutex_init(&hinfo->sync_proc_lock);
++	hinfo->sync_read_proc = NULL;
++
++	return 0;
++}
++EXPORT_SYMBOL(ambsync_proc_hinit);
++
++int ambsync_proc_open(struct inode *inode, struct file *file)
++{
++	int retval = 0;
++	struct ambsync_proc_pinfo *pinfo = file->private_data;
++	struct ambsync_proc_hinfo *hinfo;
++	int id;
++
++	hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
++	if (!hinfo) {
++		retval = -EPERM;
++		goto ambsync_proc_open_exit;
++	}
++	if (hinfo->maxid > AMBA_SYNC_PROC_MAX_ID) {
++		retval = -EPERM;
++		goto ambsync_proc_open_exit;
++	}
++
++	if (pinfo) {
++		retval = -EPERM;
++		goto ambsync_proc_open_exit;
++	}
++	pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL);
++	if (!pinfo) {
++		retval = -ENOMEM;
++		goto ambsync_proc_open_exit;
++	}
++	memset(pinfo, 0, sizeof(*pinfo));
++
++	mutex_lock(&hinfo->sync_proc_lock);
++	id = idr_alloc(&hinfo->sync_proc_idr, pinfo, 0, 0, GFP_KERNEL);
++	mutex_unlock(&hinfo->sync_proc_lock);
++	if (id < 0) {
++		retval = id;
++		goto ambsync_proc_open_kfree_p;
++	}
++	if (id > 31) {
++		retval = -ENOMEM;
++		goto ambsync_proc_open_remove_id;
++	}
++
++	if (!(pinfo->page = (char*) __get_free_page(GFP_KERNEL))) {
++		retval = -ENOMEM;
++		goto ambsync_proc_open_remove_id;
++	}
++	pinfo->id = id;
++	pinfo->mask = (0x01 << id);
++
++	file->private_data = pinfo;
++	file->f_version = 0;
++	file->f_mode &= ~FMODE_PWRITE;
++
++	goto ambsync_proc_open_exit;
++
++ambsync_proc_open_remove_id:
++	mutex_lock(&hinfo->sync_proc_lock);
++	idr_remove(&hinfo->sync_proc_idr, id);
++	mutex_unlock(&hinfo->sync_proc_lock);
++
++ambsync_proc_open_kfree_p:
++	kfree(pinfo);
++
++ambsync_proc_open_exit:
++	return retval;
++}
++EXPORT_SYMBOL(ambsync_proc_open);
++
++int ambsync_proc_release(struct inode *inode, struct file *file)
++{
++	int retval = 0;
++	struct ambsync_proc_pinfo *pinfo = file->private_data;
++	struct ambsync_proc_hinfo *hinfo;
++
++	hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
++	if (!hinfo) {
++		retval = -EPERM;
++		goto ambsync_proc_release_exit;
++	}
++
++	if (!pinfo) {
++		retval = -ENOMEM;
++		goto ambsync_proc_release_exit;
++	}
++
++	mutex_lock(&hinfo->sync_proc_lock);
++	idr_remove(&hinfo->sync_proc_idr, pinfo->id);
++	mutex_unlock(&hinfo->sync_proc_lock);
++
++	free_page((unsigned long)pinfo->page);
++	kfree(pinfo);
++	file->private_data = NULL;
++
++ambsync_proc_release_exit:
++	return retval;
++}
++EXPORT_SYMBOL(ambsync_proc_release);
++
++/* Note: ignore ppos*/
++ssize_t ambsync_proc_read(struct file *file, char __user *buf,
++	size_t size, loff_t *ppos)
++{
++	int retval = 0;
++	struct ambsync_proc_pinfo *pinfo = file->private_data;
++	struct ambsync_proc_hinfo *hinfo;
++	struct inode *inode = file->f_path.dentry->d_inode;
++	char *start;
++	int len;
++	size_t count;
++
++	hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
++	if (!hinfo) {
++		retval = -EPERM;
++		goto ambsync_proc_read_exit;
++	}
++	if (!hinfo->sync_read_proc) {
++		retval = -EPERM;
++		goto ambsync_proc_read_exit;
++	}
++
++	if (!pinfo) {
++		retval = -ENOMEM;
++		goto ambsync_proc_read_exit;
++	}
++
++	count = min_t(size_t, AMBA_SYNC_PROC_PAGE_SIZE, size);
++	start = pinfo->page;
++	len = 0;
++	while (1) {
++		wait_event_interruptible_timeout(hinfo->sync_proc_head,
++			(atomic_read(&hinfo->sync_proc_flag) & pinfo->mask), hinfo->tmo);
++		atomic_clear_mask(pinfo->mask,
++			(unsigned long *)&hinfo->sync_proc_flag);
++
++		len = hinfo->sync_read_proc(start, hinfo->sync_read_data);
++		if (len < count) {
++			start += len;
++			count -= len;
++		} else if (len == count) {
++			start += len;
++			count -= len;
++			break;
++		} else {
++			break;
++		}
++	}
++	len = start - pinfo->page;
++	if (len == 0) {
++		retval = -EFAULT;
++	} else {
++		if (copy_to_user(buf, pinfo->page, len)) {
++			retval = -EFAULT;
++		} else {
++			retval = len;
++		}
++	}
++
++ambsync_proc_read_exit:
++	return retval;
++}
++EXPORT_SYMBOL(ambsync_proc_read);
++
++ssize_t ambsync_proc_write(struct file *file, const char __user *buf,
++	size_t size, loff_t *ppos)
++{
++	int retval = 0;
++	struct ambsync_proc_hinfo *hinfo;
++	struct inode *inode = file->f_path.dentry->d_inode;
++
++	hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
++	if (!hinfo) {
++		retval = -EPERM;
++		goto ambsync_proc_write_exit;
++	}
++
++	atomic_set(&hinfo->sync_proc_flag, 0xFFFFFFFF);
++	wake_up_all(&hinfo->sync_proc_head);
++
++	retval = size;
++
++ambsync_proc_write_exit:
++	return retval;
++}
++EXPORT_SYMBOL(ambsync_proc_write);
+diff --git a/arch/arm/mach-ambarella/misc/audio.c b/arch/arm/mach-ambarella/misc/audio.c
+new file mode 100644
+index 00000000..d9645ec8
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/audio.c
+@@ -0,0 +1,105 @@
++/*
++ * arch/arm/plat-ambarella/generic/audio.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/export.h>
++#include <linux/notifier.h>
++#include <plat/audio.h>
++
++/* ==========================================================================*/
++static struct srcu_notifier_head audio_notifier_list;
++static struct notifier_block audio_notify;
++static struct ambarella_i2s_interface audio_i2s_intf;
++
++struct ambarella_i2s_interface get_audio_i2s_interface(void)
++{
++	return audio_i2s_intf;
++}
++EXPORT_SYMBOL(get_audio_i2s_interface);
++
++static int audio_notify_transition(struct notifier_block *nb,
++		unsigned long val, void *data)
++{
++	switch(val) {
++	case AUDIO_NOTIFY_INIT:
++		audio_i2s_intf.state = AUDIO_NOTIFY_INIT;
++		memcpy(&audio_i2s_intf, data,
++			sizeof(struct ambarella_i2s_interface));
++		break;
++
++	case AUDIO_NOTIFY_SETHWPARAMS:
++		audio_i2s_intf.state = AUDIO_NOTIFY_SETHWPARAMS;
++		memcpy(&audio_i2s_intf, data,
++			sizeof(struct ambarella_i2s_interface));
++		break;
++
++	case AUDIO_NOTIFY_REMOVE:
++		memset(&audio_i2s_intf, 0,
++			sizeof(struct ambarella_i2s_interface));
++		audio_i2s_intf.state = AUDIO_NOTIFY_REMOVE;
++		break;
++	default:
++		audio_i2s_intf.state = AUDIO_NOTIFY_UNKNOWN;
++		break;
++	}
++
++	return 0;
++}
++
++void ambarella_audio_notify_transition (
++	struct ambarella_i2s_interface *data, unsigned int type)
++{
++	srcu_notifier_call_chain(&audio_notifier_list, type, data);
++}
++EXPORT_SYMBOL(ambarella_audio_notify_transition);
++
++int ambarella_audio_register_notifier(struct notifier_block *nb)
++{
++	return srcu_notifier_chain_register( &audio_notifier_list, nb);
++}
++EXPORT_SYMBOL(ambarella_audio_register_notifier);
++
++
++int ambarella_audio_unregister_notifier(struct notifier_block *nb)
++{
++	return srcu_notifier_chain_unregister(&audio_notifier_list, nb);
++}
++EXPORT_SYMBOL(ambarella_audio_unregister_notifier);
++
++
++int __init ambarella_init_audio(void)
++{
++	int retval = 0;
++
++	srcu_init_notifier_head(&audio_notifier_list);
++
++	memset(&audio_i2s_intf, 0, sizeof(struct ambarella_i2s_interface));
++	audio_i2s_intf.state = AUDIO_NOTIFY_UNKNOWN;
++
++	audio_notify.notifier_call = audio_notify_transition;
++	retval = ambarella_audio_register_notifier(&audio_notify);
++
++	return retval;
++}
++
+diff --git a/arch/arm/mach-ambarella/misc/event.c b/arch/arm/mach-ambarella/misc/event.c
+new file mode 100644
+index 00000000..e986ca43
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/event.c
+@@ -0,0 +1,73 @@
++/*
++ * arch/arm/plat-ambarella/misc/event.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/export.h>
++
++#include <mach/hardware.h>
++#include <plat/event.h>
++
++/* ==========================================================================*/
++static BLOCKING_NOTIFIER_HEAD(blocking_event_list);
++static RAW_NOTIFIER_HEAD(raw_event_list);
++
++/* ==========================================================================*/
++int ambarella_register_event_notifier(void *nb)
++{
++	return blocking_notifier_chain_register(&blocking_event_list, nb);
++}
++EXPORT_SYMBOL(ambarella_register_event_notifier);
++
++int ambarella_unregister_event_notifier(void *nb)
++{
++	return blocking_notifier_chain_unregister(&blocking_event_list, nb);
++}
++EXPORT_SYMBOL(ambarella_unregister_event_notifier);
++
++int ambarella_set_event(unsigned long val, void *v)
++{
++	return blocking_notifier_call_chain(&blocking_event_list, val, v);
++}
++EXPORT_SYMBOL(ambarella_set_event);
++
++int ambarella_register_raw_event_notifier(void *nb)
++{
++	return raw_notifier_chain_register(&raw_event_list, nb);
++}
++EXPORT_SYMBOL(ambarella_register_raw_event_notifier);
++
++int ambarella_unregister_raw_event_notifier(void *nb)
++{
++	return raw_notifier_chain_unregister(&raw_event_list, nb);
++}
++EXPORT_SYMBOL(ambarella_unregister_raw_event_notifier);
++
++int ambarella_set_raw_event(unsigned long val, void *v)
++{
++	return raw_notifier_call_chain(&raw_event_list, val, v);
++}
++EXPORT_SYMBOL(ambarella_set_raw_event);
++
+diff --git a/arch/arm/mach-ambarella/misc/gdma.c b/arch/arm/mach-ambarella/misc/gdma.c
+new file mode 100644
+index 00000000..81c0bc67
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/gdma.c
+@@ -0,0 +1,348 @@
++/*
++ * arch/arm/plat-ambarella/generic/gdma.c
++ *
++ * Author: Louis Sun <lysun@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <mach/hardware.h>
++#include <mach/init.h>
++#include <plat/iav_helper.h>
++#include <plat/gdma.h>
++
++#define TRANSFER_2D_WIDTH		(1 << 12 )		/* 4096 */
++#define MAX_TRANSFER_2D_HEIGHT		(1 << 11 )		/* 2048 */
++#define MAX_TRANSFER_SIZE_2D_UNIT	(TRANSFER_2D_WIDTH * MAX_TRANSFER_2D_HEIGHT)	/* 8MB */
++
++#define TRANSFER_1D_WIDTH		TRANSFER_2D_WIDTH
++#define MAX_TRANSFER_SIZE_1D_UNIT	TRANSFER_1D_WIDTH
++
++/* transfer 6 big blocks (although maximum is 8), because we may do another 1 small block and 1 line. total 8 Ops */
++#define MAX_TRANSFER_SIZE_ONCE		(MAX_TRANSFER_SIZE_2D_UNIT * 6)	/* 48 MB */
++#define MAX_OPS				8
++
++static struct completion	transfer_completion;
++static struct mutex		transfer_mutex;
++
++
++/* handle 8MB at one time */
++static inline int transfer_big_unit(u8 *dest_addr, u8 *src_addr, u32 size)
++{
++	int row_count;
++	if (size > MAX_TRANSFER_SIZE_2D_UNIT) {
++		printk("transfer_unit size %d bigger than %d \n",
++			size, MAX_TRANSFER_SIZE_2D_UNIT);
++		return -1;
++	}
++
++	row_count = size / TRANSFER_2D_WIDTH;
++
++	/* copy rows by 2D copy */
++	if (row_count > 0) {
++		amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
++		amba_writel(GDMA_SRC_1_PITCH_REG, TRANSFER_2D_WIDTH);
++		amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
++		amba_writel(GDMA_DST_PITCH_REG, TRANSFER_2D_WIDTH);
++		amba_writel(GDMA_WIDTH_REG, TRANSFER_2D_WIDTH - 1);
++		amba_writel(GDMA_HEIGHT_REG, row_count - 1);
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++		amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
++		amba_writel(GDMA_ALPHA_REG, 0);
++		amba_writel(GDMA_CLUT_BASE_REG, 0);
++#endif
++
++		/* start 2D copy */
++		amba_writel(GDMA_OPCODE_REG, 1);
++	}
++	return 0;
++
++}
++
++/* use 1D copy to copy max  4KB each time */
++static inline int transfer_small_unit(u8 *dest_addr, u8 *src_addr, u32 size)
++{
++	if (size > TRANSFER_1D_WIDTH) {
++		printk("transfer_unit size %d bigger than %d \n",
++			size, TRANSFER_1D_WIDTH);
++		return -1;
++	}
++
++	/* linear copy */
++	amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
++	amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
++	amba_writel(GDMA_WIDTH_REG, size - 1);
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++	amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
++	amba_writel(GDMA_ALPHA_REG, 0);
++	amba_writel(GDMA_CLUT_BASE_REG, 0);
++#endif
++
++	/* start linear copy */
++	amba_writel(GDMA_OPCODE_REG, 0);
++
++	return 0;
++}
++
++
++
++/* this is async function, just fill dma registers and let it run*/
++static inline int transfer_once(u8 *dest_addr, u8 *src_addr, u32 size)
++{
++	//total pending count must be no bigger than 8
++	int big_count;
++	int rows_count;
++	int i;
++	u32 transferred_bytes = 0;
++	int remain_bytes ;
++
++	if (size > MAX_TRANSFER_SIZE_ONCE)  {
++		printk(" size too big %d for transfer once \n", size);
++		return -1;
++	}
++
++	big_count = size/MAX_TRANSFER_SIZE_2D_UNIT;
++	//big pages (each is 8MB)
++	for (i = big_count ; i > 0; i--) {
++		transfer_big_unit(dest_addr + transferred_bytes,
++						src_addr  + transferred_bytes,
++						MAX_TRANSFER_SIZE_2D_UNIT);
++		transferred_bytes += MAX_TRANSFER_SIZE_2D_UNIT;
++	}
++	remain_bytes =  size - transferred_bytes;
++
++
++	//transfer rows (align to TRANSFER_2D_WIDTH)
++	rows_count = remain_bytes / TRANSFER_2D_WIDTH;
++	if (rows_count > 0) {
++		transfer_big_unit(dest_addr + transferred_bytes,
++							src_addr  + transferred_bytes,
++							TRANSFER_2D_WIDTH * rows_count);
++		transferred_bytes += TRANSFER_2D_WIDTH * rows_count;
++		remain_bytes =  size - transferred_bytes;
++	}
++
++	if (remain_bytes > 0) {
++		transfer_small_unit(dest_addr + transferred_bytes,
++						src_addr  + transferred_bytes, remain_bytes);
++	}
++
++	return 0;
++}
++
++/* this is synchronous function, will wait till transfer finishes */
++int dma_memcpy(u8 *dest_addr, u8 *src_addr, u32 size)
++{
++	int remain_size = size;
++	int transferred_size = 0;
++	int current_transfer_size;
++
++	if (size <= 0) {
++		return -1;
++	}
++
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++	if (size & 0x1) {
++		printk("Size must be even !\n");
++		return -1;
++	}
++#endif
++
++	mutex_lock(&transfer_mutex);
++
++	ambcache_clean_range((void *)ambarella_phys_to_virt((u32)src_addr), size);
++
++	while (remain_size > 0)	{
++		if (remain_size > MAX_TRANSFER_SIZE_ONCE) {
++			remain_size -= MAX_TRANSFER_SIZE_ONCE;
++			current_transfer_size = MAX_TRANSFER_SIZE_ONCE;
++		} else {
++			current_transfer_size = remain_size;
++			remain_size = 0;
++		}
++
++		transfer_once(dest_addr + transferred_size,
++			src_addr + transferred_size, current_transfer_size);
++		wait_for_completion(&transfer_completion);
++		transferred_size += current_transfer_size;
++	}
++
++	ambcache_inv_range((void *)ambarella_phys_to_virt((u32)dest_addr), size);
++
++	mutex_unlock(&transfer_mutex);
++
++	return 0;
++}
++EXPORT_SYMBOL(dma_memcpy);
++
++static inline int transfer_pitch_unit(u8 *dest_addr, u8 *src_addr,u16 src_pitch, u16 dest_pitch, u16 width, u16 height)
++{
++
++	if (height <= 0) {
++		return -1;
++	}
++
++	/* copy rows by 2D copy */
++	while (height > MAX_TRANSFER_2D_HEIGHT) {
++		amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
++		amba_writel(GDMA_SRC_1_PITCH_REG, src_pitch);
++		amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
++		amba_writel(GDMA_DST_PITCH_REG, dest_pitch);
++		amba_writel(GDMA_WIDTH_REG, width - 1);
++		amba_writel(GDMA_HEIGHT_REG, MAX_TRANSFER_2D_HEIGHT - 1);
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++		amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
++		amba_writel(GDMA_ALPHA_REG, 0);
++		amba_writel(GDMA_CLUT_BASE_REG, 0);
++#endif
++
++		/* start 2D copy */
++		amba_writel(GDMA_OPCODE_REG, 1);
++		height = height - MAX_TRANSFER_2D_HEIGHT;
++		src_addr = src_addr + src_pitch * MAX_TRANSFER_2D_HEIGHT;
++		dest_addr = dest_addr + dest_pitch * MAX_TRANSFER_2D_HEIGHT;
++	}
++
++		amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
++		amba_writel(GDMA_SRC_1_PITCH_REG, src_pitch);
++		amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
++		amba_writel(GDMA_DST_PITCH_REG, dest_pitch);
++		amba_writel(GDMA_WIDTH_REG, width - 1);
++		amba_writel(GDMA_HEIGHT_REG, height - 1);
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++		amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
++		amba_writel(GDMA_ALPHA_REG, 0);
++		amba_writel(GDMA_CLUT_BASE_REG, 0);
++#endif
++
++		/* start 2D copy */
++		amba_writel(GDMA_OPCODE_REG, 1);
++
++	return 0;
++
++}
++
++/* this is synchronous function, will wait till transfer finishes  width =< 4096 */
++int dma_pitch_memcpy(struct gdma_param *params)
++{
++	int size = params->src_pitch * params->height;
++
++	if (size <= 0 || params->src_pitch <= 0 || params->dest_pitch <= 0
++		|| params->width > TRANSFER_2D_WIDTH) {
++		printk(" invalid value \n");
++		return -1;
++	}
++
++#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
++	if (size & 0x1) {
++		printk("Size must be even !\n");
++		return -1;
++	}
++#endif
++
++	mutex_lock(&transfer_mutex);
++	if (!params->src_non_cached) {
++		ambcache_clean_range((void *)params->src_virt_addr, size);
++	}
++	transfer_pitch_unit((u8 *)params->dest_addr, (u8 *)params->src_addr,
++		params->src_pitch, params->dest_pitch, params->width, params->height);
++
++	wait_for_completion(&transfer_completion);
++
++	if (!params->dest_non_cached) {
++		ambcache_inv_range((void *)params->dest_virt_addr, size);
++	}
++	mutex_unlock(&transfer_mutex);
++
++	return 0;
++}
++
++EXPORT_SYMBOL(dma_pitch_memcpy);
++
++static irqreturn_t gdma_interrupt(int irq, void *dev_id)
++{
++	int pending_ops;
++	pending_ops = amba_readl(GDMA_PENDING_OPS_REG);
++
++	if (pending_ops == 0) {
++		/* if no following transfer */
++		complete(&transfer_completion);
++	} else {
++
++	}
++	return IRQ_HANDLED;
++}
++
++static int hw_init(void)
++{
++	int	errorCode;
++	/* request irq, no device id, no irq sharing */
++	errorCode = request_irq(GDMA_IRQ, gdma_interrupt,
++	IRQF_TRIGGER_RISING, "gdma", 0);
++
++	if (errorCode) {
++		printk("gdma irq request failed \n");
++		return -1;
++	}
++
++	return 0;
++}
++
++/* wait till transmit completes */
++static void wait_transmit_complete(void)
++{
++	int pending_ops;
++	pending_ops = amba_readl(GDMA_PENDING_OPS_REG);
++
++	while(pending_ops!= 0) {
++		mdelay(10);
++	}
++}
++
++static int __init gdma_init(void)
++{
++	/* hardware and irq init */
++	if (hw_init() != 0)
++		return -1;
++	/* init completion */
++	init_completion(&transfer_completion);
++	mutex_init(&transfer_mutex);
++
++	return 0;
++}
++
++static void __exit gdma_exit(void)
++{
++	wait_transmit_complete();
++}
++
++MODULE_AUTHOR("Louis Sun <lysun@ambarella.com>");
++MODULE_DESCRIPTION("GDMA driver on Ambarella A5S / S2");
++MODULE_LICENSE("GPL v2");
++MODULE_VERSION("1.0");
++
++module_init(gdma_init);
++module_exit(gdma_exit);
++
+diff --git a/arch/arm/mach-ambarella/misc/highres_timer.c b/arch/arm/mach-ambarella/misc/highres_timer.c
+new file mode 100644
+index 00000000..2225d61e
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/highres_timer.c
+@@ -0,0 +1,51 @@
++/*
++ * arch/arm/plat-ambarella/misc/highres_timer.c
++ *
++ * Author: Louis Sun <lysun@ambarella.com>
++ *
++ * Copyright (C) 2004-2011, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/hrtimer.h>
++#include <linux/ktime.h>
++
++int highres_timer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
++{
++	return hrtimer_start(timer, tim, mode);
++}
++EXPORT_SYMBOL(highres_timer_start);
++
++void highres_timer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode)
++{
++	hrtimer_init(timer, clock_id, mode);
++}
++EXPORT_SYMBOL(highres_timer_init);
++
++int highres_timer_cancel(struct hrtimer *timer)
++{
++	return hrtimer_cancel(timer);
++}
++EXPORT_SYMBOL(highres_timer_cancel);
++
++MODULE_AUTHOR("Louis Sun <lysun@ambarella.com>");
++MODULE_DESCRIPTION("high resolution timer wrapper");
++MODULE_LICENSE("GPL v2");
++MODULE_VERSION("1.0");
++
+diff --git a/arch/arm/mach-ambarella/misc/hwlock.c b/arch/arm/mach-ambarella/misc/hwlock.c
+new file mode 100644
+index 00000000..21824f2d
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/hwlock.c
+@@ -0,0 +1,35 @@
++/*
++ * arch/arm/plat-ambarella/generic/reglock.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++
++/* ==========================================================================*/
++DEFINE_SPINLOCK(ambarella_global_hw_lock);
++unsigned long ambarella_global_hw_flags;
++
++/* ==========================================================================*/
++EXPORT_SYMBOL(ambarella_global_hw_lock);
++EXPORT_SYMBOL(ambarella_global_hw_flags);
++
+diff --git a/arch/arm/mach-ambarella/misc/iav_helper.c b/arch/arm/mach-ambarella/misc/iav_helper.c
+new file mode 100644
+index 00000000..09d9bbc4
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/iav_helper.c
+@@ -0,0 +1,110 @@
++/*
++ * arch/arm/plat-ambarella/misc/service.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <plat/iav_helper.h>
++#include <mach/init.h>
++#include <asm/cacheflush.h>
++
++
++/*===========================================================================*/
++
++static LIST_HEAD(ambarella_svc_list);
++
++int ambarella_register_service(struct ambarella_service *amb_svc)
++{
++	struct ambarella_service *svc;
++
++	if (!amb_svc || !amb_svc->func)
++		return -EINVAL;
++
++	list_for_each_entry(svc, &ambarella_svc_list, node) {
++		if (svc->service == amb_svc->service) {
++			pr_err("%s: service (%d) is already existed\n",
++					__func__, amb_svc->service);
++			return -EEXIST;
++		}
++	}
++
++	list_add_tail(&amb_svc->node, &ambarella_svc_list);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_register_service);
++
++int ambarella_unregister_service(struct ambarella_service *amb_svc)
++{
++	struct ambarella_service *svc;
++
++	if (!amb_svc)
++		return -EINVAL;
++
++	list_for_each_entry(svc, &ambarella_svc_list, node) {
++		if (svc->service == amb_svc->service) {
++			list_del(&svc->node);
++			break;
++		}
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(ambarella_unregister_service);
++
++int ambarella_request_service(int service, void *arg, void *result)
++{
++	struct ambarella_service *svc;
++	int found = 0;
++
++	list_for_each_entry(svc, &ambarella_svc_list, node) {
++		if (svc->service == service) {
++			found = 1;
++			break;
++		}
++	}
++
++	if (found == 0) {
++		pr_err("%s: no such service (%d)\n", __func__, service);
++		return -ENODEV;
++	}
++
++	return svc->func(arg, result);
++}
++EXPORT_SYMBOL(ambarella_request_service);
++
++/*===========================================================================*/
++
++void ambcache_clean_range(void *addr, unsigned int size)
++{
++	__sync_cache_range_w(addr, size);
++}
++EXPORT_SYMBOL(ambcache_clean_range);
++
++void ambcache_inv_range(void *addr, unsigned int size)
++{
++	__sync_cache_range_r(addr, size);
++}
++
++EXPORT_SYMBOL(ambcache_inv_range);
++
++
+diff --git a/arch/arm/mach-ambarella/misc/pmu.c b/arch/arm/mach-ambarella/misc/pmu.c
+new file mode 100644
+index 00000000..341b4409
+--- /dev/null
++++ b/arch/arm/mach-ambarella/misc/pmu.c
+@@ -0,0 +1,76 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++
++#include <asm/pmu.h>
++
++#include <plat/irq.h>
++
++/* ==========================================================================*/
++#if defined(CONFIG_AMBARELLA_PMUSERENR_EN)
++static void pmu_set_userspace_access(void *en)
++{
++	int val = 0;
++	/* Read PMUSERENR Register */
++	asm volatile("mrc p15, 0, %0, c9, c14, 0" : : "r" (val));
++	val &= ~0x1;
++	val |= (int)en;
++	/* Write PMUSERENR Register */
++	asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (val));
++}
++#endif
++
++/* ==========================================================================*/
++#if defined(PMU_IRQ)
++/*
++ * PMU Interrupt is not connected to A5S/A7L/A8/S2,
++ * the counters are still available, and some profiling tools,
++ * such as 'perf' can live with that and collect statistics.
++ *
++ * So we provide PMU_IRQ setup here for all chips.
++ */
++static struct resource ambarella_pmu_resource[] = {
++	DEFINE_RES_IRQ(PMU_IRQ)
++};
++
++static struct platform_device ambarella_pmu = {
++	.name		= "arm-pmu",
++	.id		= -1,
++	.num_resources	= ARRAY_SIZE(ambarella_pmu_resource),
++	.resource	= ambarella_pmu_resource,
++};
++#endif
++
++/* ==========================================================================*/
++static int __init ambarella_pmu_init(void)
++{
++	int ret_val = 0;
++#if defined(PMU_IRQ)
++	ret_val = platform_device_register(&ambarella_pmu);
++#endif
++#if defined(CONFIG_AMBARELLA_PMUSERENR_EN)
++	pr_info("Enable PMUSERENR on all cores ... ");
++	ret_val = on_each_cpu(pmu_set_userspace_access, (void*)1, 1);
++	pr_info("done\n");
++#endif
++	return ret_val;
++}
++arch_initcall(ambarella_pmu_init);
++
+diff --git a/arch/arm/mach-ambarella/pm.c b/arch/arm/mach-ambarella/pm.c
+new file mode 100644
+index 00000000..13c22ddd
+--- /dev/null
++++ b/arch/arm/mach-ambarella/pm.c
+@@ -0,0 +1,347 @@
++/*
++ * arch/arm/plat-ambarella/generic/pm.c
++ * Power Management Routines
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/suspend.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/cpu.h>
++#include <linux/power_supply.h>
++#include <linux/of.h>
++#include <asm/cacheflush.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/suspend.h>
++#include <mach/hardware.h>
++#include <mach/init.h>
++#include <plat/drctl.h>
++#include <plat/rtc.h>
++#include <plat/fio.h>
++
++#define SREF_MAGIC_PATTERN		0x43525230
++#define SREF_CPU_JUMP_ADDR		0x000f1000
++
++static int dram_reset_ctrl = -1;
++static int gpio_notify_mcu = -1;
++static int hibernate_gpio_notify_mcu = -1;
++extern int ambarella_suspend_trigger_signal[];
++
++u32 gpio_regbase[] = {GPIO0_BASE, GPIO1_BASE, GPIO2_BASE, GPIO3_BASE,
++	GPIO4_BASE, GPIO5_BASE, GPIO6_BASE};
++
++static unsigned long ambarella_gpio_setup(int);
++/* ==========================================================================*/
++void ambarella_pm_gpiomux(int gpio)
++{
++	u32 bank, offset;
++
++	bank = PINID_TO_BANK(gpio);
++	offset = PINID_TO_OFFSET(gpio);
++
++#if (IOMUX_SUPPORT > 0)
++	/* configure the pin as GPIO mode */
++	amba_clrbitsl(IOMUX_REG(IOMUX_REG_OFFSET(bank, 0)), 0x1 << offset);
++	amba_clrbitsl(IOMUX_REG(IOMUX_REG_OFFSET(bank, 1)), 0x1 << offset);
++	amba_clrbitsl(IOMUX_REG(IOMUX_REG_OFFSET(bank, 2)), 0x1 << offset);
++	amba_writel(IOMUX_REG(IOMUX_CTRL_SET_OFFSET), 0x1);
++	amba_writel(IOMUX_REG(IOMUX_CTRL_SET_OFFSET), 0x0);
++#endif
++
++}
++void ambarella_pm_gpio_output(int gpio, int value)
++{
++	u32 bank, offset;
++
++	bank = PINID_TO_BANK(gpio);
++	offset = PINID_TO_OFFSET(gpio);
++
++	amba_writel(gpio_regbase[bank] + GPIO_ENABLE_OFFSET, 0xffffffff);
++	amba_clrbitsl(gpio_regbase[bank] + GPIO_AFSEL_OFFSET, 0x1 << offset);
++	amba_setbitsl(gpio_regbase[bank] + GPIO_MASK_OFFSET, 0x1 << offset);
++	amba_setbitsl(gpio_regbase[bank] + GPIO_DIR_OFFSET, 0x1 << offset);
++
++	if (!!value)
++		amba_setbitsl(gpio_regbase[bank] + GPIO_DATA_OFFSET, 0x1 << offset);
++	else
++		amba_clrbitsl(gpio_regbase[bank] + GPIO_DATA_OFFSET, 0x1 << offset);
++}
++
++void ambarella_pm_gpio_input(int gpio, int *value)
++{
++	u32 bank, offset;
++
++	bank = PINID_TO_BANK(gpio);
++	offset = PINID_TO_OFFSET(gpio);
++
++	amba_writel(gpio_regbase[bank] + GPIO_ENABLE_OFFSET, 0xffffffff);
++	amba_clrbitsl(gpio_regbase[bank] + GPIO_AFSEL_OFFSET, 0x1 << offset);
++	amba_setbitsl(gpio_regbase[bank] + GPIO_MASK_OFFSET, 0x1 << offset);
++	amba_clrbitsl(gpio_regbase[bank] + GPIO_DIR_OFFSET, 0x1 << offset);
++
++	*value = !!(amba_readl(gpio_regbase[bank] + GPIO_DATA_OFFSET) & 0x1 << offset);
++}
++
++/* ==========================================================================*/
++void ambarella_power_off(void)
++{
++	if (!ambarella_gpio_setup(hibernate_gpio_notify_mcu))
++		return;
++
++	ambarella_pm_gpio_output(hibernate_gpio_notify_mcu, 1);
++	mdelay(100);
++	ambarella_pm_gpio_output(hibernate_gpio_notify_mcu, 0);
++
++	amba_rct_setbitsl(ANA_PWR_REG, ANA_PWR_POWER_DOWN);
++}
++
++void ambarella_power_off_prepare(void)
++{
++
++}
++
++/* ==========================================================================*/
++static void ambarella_disconnect_dram_reset(void)
++{
++
++	if (dram_reset_ctrl == -1)
++		return;
++
++	ambarella_pm_gpiomux(dram_reset_ctrl);
++
++	ambarella_pm_gpio_output(dram_reset_ctrl, 0);
++}
++
++static unsigned long ambarella_gpio_setup(int gpio)
++{
++	unsigned long gpio_info;
++	u32 bank, offset;
++
++	if (gpio == -1)
++		return 0;
++
++	bank = PINID_TO_BANK(gpio);
++	offset = PINID_TO_OFFSET(gpio);
++
++	gpio_info = gpio_regbase[bank] | offset;
++
++	/* Mux GPIO output mode */
++	ambarella_pm_gpio_output(gpio, !ambarella_suspend_trigger_signal[0]);
++	ambarella_pm_gpiomux(gpio);
++
++	return gpio_info;
++}
++
++static void ambarella_set_cpu_jump(int cpu, void *jump_fn)
++{
++	u32 addr_phys;
++	u32 *addr_virt;
++
++	/* must keep consistent with self_refresh.c in bst. */
++	addr_phys = get_ambarella_ppm_phys() + SREF_CPU_JUMP_ADDR;
++	addr_virt = (u32 *)ambarella_phys_to_virt(addr_phys);
++	*addr_virt++ = SREF_MAGIC_PATTERN;
++	*addr_virt = virt_to_phys(jump_fn);
++
++	__cpuc_flush_dcache_area(addr_virt, sizeof(u32) * 2);
++	outer_clean_range(addr_phys, addr_phys + sizeof(u32) * 2);
++}
++
++static int ambarella_cpu_do_idle(unsigned long unused)
++{
++	cpu_do_idle();
++	return 0;
++}
++
++static int ambarella_pm_enter_standby(void)
++{
++	cpu_suspend(0, ambarella_cpu_do_idle);
++	return 0;
++}
++
++static void ambarella_pm_rtc_flush(void)
++{
++	unsigned int alarm;
++	unsigned int time;
++
++	alarm = amba_readl(RTC_REG(RTC_ALAT_OFFSET));
++	amba_writel(RTC_REG(RTC_PWC_ALAT_OFFSET), alarm);
++	time  = amba_readl(RTC_REG(RTC_CURT_OFFSET));
++	amba_writel(RTC_REG(RTC_PWC_CURT_OFFSET), time);
++}
++
++static unsigned long ambarella_pm_pwc_trigger(void)
++{
++	/* ensure the power for DRAM keeps on when power off PWC */
++	amba_writel(RTC_REG(RTC_PWC_ENP3_OFFSET), 0x1);
++	amba_writel(RTC_REG(RTC_POS0_OFFSET), 0x10);
++	amba_writel(RTC_REG(RTC_POS1_OFFSET), 0x10);
++	amba_writel(RTC_REG(RTC_POS2_OFFSET), 0x10);
++	amba_writel(RTC_REG(RTC_POS3_OFFSET), 0x10);
++	amba_setbitsl(RTC_REG(RTC_PWC_SET_STATUS_OFFSET), 0x04);
++
++	ambarella_pm_rtc_flush();
++
++	amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x1);
++	mdelay(3);
++	amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x0);
++
++	return 0;
++}
++static void ambarella_pm_pwc_resume(void)
++{
++	/* ensure to power off all powers when power off PWC */
++	amba_writel(RTC_REG(RTC_PWC_ENP3_OFFSET), 0x0);
++	amba_clrbitsl(RTC_REG(RTC_PWC_SET_STATUS_OFFSET), 0x04);
++
++	ambarella_pm_rtc_flush();
++
++	amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x1);
++	while(amba_readl(RTC_REG(RTC_PWC_REG_STA_OFFSET)) & 0x04);
++	amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x0);
++
++}
++
++static unsigned long ambarella_pm_io_trigger(void)
++{
++	/* FIXME: flush internel rtc on chips, even though it is disabled. Because
++	 * it has no unexpected effect on system */
++	ambarella_pm_rtc_flush();
++
++	return ambarella_gpio_setup(gpio_notify_mcu);
++}
++
++static void ambarella_pm_io_resume(void)
++{
++	ambarella_pm_rtc_flush();
++}
++
++static int ambarella_pm_enter_mem(void)
++{
++	unsigned long arg = 0;
++#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
++	void *ambarella_suspend_exec = NULL;
++#endif
++
++	ambarella_disconnect_dram_reset();
++
++	if (gpio_notify_mcu == -1)
++		arg = ambarella_pm_pwc_trigger();
++	else
++		arg = ambarella_pm_io_trigger();
++
++	ambarella_set_cpu_jump(0, ambarella_cpu_resume);
++
++#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
++	ambarella_suspend_exec = ambarella_fio_push(ambarella_optimize_suspend,
++			ambarella_optimize_suspend_sz);
++#endif
++	outer_flush_all();
++	outer_disable();
++
++#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
++	cpu_suspend(arg, ambarella_suspend_exec);
++#else
++	cpu_suspend(0, ambarella_finish_suspend);
++#endif
++
++	outer_resume();
++
++	if (gpio_notify_mcu == -1)
++		ambarella_pm_pwc_resume();
++	else
++		ambarella_pm_io_resume();
++
++	return 0;
++}
++
++static int ambarella_pm_suspend_enter(suspend_state_t state)
++{
++	int rval = 0;
++
++	switch (state) {
++	case PM_SUSPEND_STANDBY:
++		rval = ambarella_pm_enter_standby();
++		break;
++	case PM_SUSPEND_MEM:
++		rval = ambarella_pm_enter_mem();
++		break;
++	case PM_SUSPEND_ON:
++	default:
++		break;
++	}
++
++	return rval;
++}
++
++static int ambarella_pm_suspend_valid(suspend_state_t state)
++{
++	int valid;
++
++	switch (state) {
++	case PM_SUSPEND_ON:
++	case PM_SUSPEND_STANDBY:
++	case PM_SUSPEND_MEM:
++		valid = 1;
++		break;
++	default:
++		valid = 0;
++		break;
++	}
++
++	pr_debug("%s: state[%d]=%d\n", __func__, state, valid);
++
++	return valid;
++}
++
++static struct platform_suspend_ops ambarella_pm_suspend_ops = {
++	.valid		= ambarella_pm_suspend_valid,
++	.enter		= ambarella_pm_suspend_enter,
++};
++
++/* ==========================================================================*/
++int __init ambarella_init_pm(void)
++{
++	pm_power_off = ambarella_power_off;
++	pm_power_off_prepare = ambarella_power_off_prepare;
++
++	suspend_set_ops(&ambarella_pm_suspend_ops);
++
++	of_property_read_u32(of_chosen, "ambarella,dram-reset-ctrl", &dram_reset_ctrl);
++	of_property_read_u32(of_chosen, "ambarella,gpio-notify-mcu", &gpio_notify_mcu);
++	of_property_read_u32(of_chosen, "ambarella,hibernate-gpio-notify-mcu", &hibernate_gpio_notify_mcu);
++	ambarella_suspend_trigger_signal[0] = !!of_find_property(of_chosen,
++			"ambarella,gpio-trigger-high", NULL);
++
++	WARN(dram_reset_ctrl >= GPIO_MAX_LINES, "Invalid DRAM RESET GPIO: %d\n", dram_reset_ctrl);
++	WARN(gpio_notify_mcu >= GPIO_MAX_LINES, "Invalid MCU NOTIFY GPIO: %d\n", gpio_notify_mcu);
++
++	pr_info("Ambarella power management: Wed Aug 10 2016 %s\n",
++			(gpio_notify_mcu == -1) ? "": ambarella_suspend_trigger_signal[0] ? "[positive edge]":"[negative edge]");
++
++	return 0;
++}
++
+diff --git a/arch/arm/mach-ambarella/sleep.S b/arch/arm/mach-ambarella/sleep.S
+new file mode 100644
+index 00000000..b799c780
+--- /dev/null
++++ b/arch/arm/mach-ambarella/sleep.S
+@@ -0,0 +1,207 @@
++/*
++ * arch/arm/mach-ambarella/sleep.S
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2014-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/cache.h>
++#include <mach/hardware.h>
++#include <plat/drctl.h>
++#include <plat/rct.h>
++#include <plat/uart.h>
++
++	.text
++
++ENTRY(ambarella_finish_suspend)
++	isb
++	dsb
++	mov r0, #0
++	ldr	r1, =(DRAMC_BASE + DRAM_DDRC_OFFSET)
++	ldr	r2, =ANA_PWR_REG
++
++	teq	r0, r0
++	bl _ambarella_finish_suspend
++	teq	pc,	r0
++	bl _ambarella_finish_suspend
++
++ENDPROC(ambarella_finish_suspend)
++
++	/* _ambarella_finish_suspend will be called twice. first is to makesure the
++	 * instructions loading in the I-Cache, and the second is to disconnect cpu
++	 * with dram, enter self refresh, and power down PWC.
++	 */
++ENTRY(_ambarella_finish_suspend)
++	ldrne	r3, [r1, #DDRC_CTL_OFFSET]
++	bicne	r3, r3, #0x1
++	strne	r3, [r1, #DDRC_CTL_OFFSET]
++	movne	r3, #0x80000000
++	strne	r3, [r1, #DDRC_SELF_REF_OFFSET]
++
++	movne	r3, #ANA_PWR_POWER_DOWN
++	strne	r3, [r2]
++	moveq	pc, lr
++	b		.
++
++ENDPROC(_ambarella_finish_suspend)
++
++ENTRY(ambarella_optimize_suspend)
++	dsb
++	isb
++
++	mov	r1, #0
++	cmp	r0, r1
++	beq	suspend_with_pwc
++
++	mov	r1, r0
++	mov	r2, #0x1f
++	bic	r0, r2			/* r0 gpio bank base */
++	and	r1, r2			/* r1 gpio offset */
++
++	ldr	r2, ambarella_suspend_trigger_signal
++	lsl	r2, r1
++	str	r2, [r0, #0]
++
++	/* delay 100ms: 0x249F00 is about 0x250000 */
++	mov	r3, #0x250000
++
++	mov	r4,	#RCT_BUS_BASE
++	orr	r4, #RCT_OFFSET
++	orr	r4,	#RCT_TIMER_OFFSET
++	ldr	r5,	[r4]
++	add	r5, r5, r3
++rct_time_loop:
++	ldr	r6,	[r4]
++	cmp	r5, r6
++	bhi	rct_time_loop
++
++	ldr	r2, ambarella_suspend_trigger_signal
++	eor r2, r2, #1
++	lsl	r2, r1
++	str	r2, [r0, #0]
++
++	b	self_refresh
++
++suspend_with_pwc:
++	mov	r0,	#RCT_BUS_BASE
++	orr	r0, #RCT_OFFSET
++	orr	r0, #ANA_PWR_OFFSET
++
++	/* Generate the PD signal */
++	mov	r1, #ANA_PWR_POWER_DOWN
++	str	r1, [r0]
++
++self_refresh:
++	/* CPU use the delay interval between power-down signal PD
++	   and PWC_RSTOB to execute the following code */
++
++	mov	r0, #DRAMC_BASE
++	orr	r0, r0, #DRAM_DDRC_OFFSET
++
++	ldr	r1, [r0, #DDRC_CTL_OFFSET]
++	bic	r1, r1, #0x1
++	str	r1, [r0, #DDRC_CTL_OFFSET]
++	mov	r1, #0x80000000
++	str	r1, [r0, #DDRC_SELF_REF_OFFSET]
++1:
++	ldr	r1, [r0, #DDRC_SELF_REF_OFFSET]
++	tst	r1, #0x10000000
++	beq	1b
++
++	/* Wait for PWC_RSTOB signal to power down cpu */
++	b	.
++
++ENDPROC(ambarella_optimize_suspend)
++
++.globl ambarella_suspend_trigger_signal
++ambarella_suspend_trigger_signal:
++	.word	0x00000000
++
++ENTRY(ambarella_optimize_suspend_sz)
++	.word 	. - ambarella_optimize_suspend
++
++#if (CHIP_REV == S3)
++#define	IOMUX_UART0_PIN_CFG	0x00000030
++#else
++#define	IOMUX_UART0_PIN_CFG	0x00000180
++#endif
++
++ENTRY(ambarella_cpu_resume)
++	/*
++	 * init UART(115200, 8N1) to avoid deadloop in printk.
++	 * MMU is not enabled yet, so we use physical address here.
++	 */
++	ldr	r0, =RCT_PHYS_BASE
++	mov	r1, #0x1
++	str	r1, [r0, #CG_UART_OFFSET]
++
++	ldr	r0, =(APB_PHYS_BASE + UART_OFFSET)
++	mov	r1, #0x1
++	str	r1, [r0, #UART_SRR_OFFSET]
++	mov	r1, #0x0
++	str	r1, [r0, #UART_SRR_OFFSET]
++	mov	r1, #0x80
++	str	r1, [r0, #UART_LC_OFFSET]
++	ldr	r1, =(REF_CLK_FREQ/16/115200)
++	str	r1, [r0, #UART_DLL_OFFSET]
++	mov	r1, #0x00
++	str	r1, [r0, #UART_DLH_OFFSET]
++	mov	r1, #0x03
++	str	r1, [r0, #UART_LC_OFFSET]
++
++	/* configure Tx/Rx pin as hw mode, it's chip specific. */
++#if (IOMUX_SUPPORT > 0)
++	/* gpio39/40 are used for UART0_rx/tx */
++	ldr	r0, =(APB_PHYS_BASE + IOMUX_OFFSET)
++	/* read-modify-write */
++	ldr	r1, [r0, #IOMUX_REG1_0_OFFSET]
++	orr	r1, r1, #IOMUX_UART0_PIN_CFG
++	str	r1, [r0, #IOMUX_REG1_0_OFFSET]
++	/* read-modify-write */
++	ldr	r1, [r0, #IOMUX_REG1_1_OFFSET]
++	bic	r1, r1, #IOMUX_UART0_PIN_CFG
++	str	r1, [r0, #IOMUX_REG1_1_OFFSET]
++	/* read-modify-write */
++	ldr	r1, [r0, #IOMUX_REG1_2_OFFSET]
++	bic	r1, r1, #IOMUX_UART0_PIN_CFG
++	str	r1, [r0, #IOMUX_REG1_2_OFFSET]
++	ldr	r1, =0x00000001
++	str	r1, [r0, #IOMUX_CTRL_SET_OFFSET]
++	ldr	r1, =0x00000000
++	str	r1, [r0, #IOMUX_CTRL_SET_OFFSET]
++#else
++	/* gpio14/15 are used for UART0_tx/rx */
++	ldr	r0, =(APB_PHYS_BASE + GPIO0_OFFSET)
++	ldr	r1, [r0, #GPIO_AFSEL_OFFSET]
++	orr	r1, #0x0000c000
++	str	r1, [r0, #GPIO_AFSEL_OFFSET]
++
++#if (CHIP_REV == S2E)
++	ldr	r0, =RCT_PHYS_BASE
++	mov r1, #UART_CLK_SRC_IDSP
++	str	r1, [r0, #UART_CLK_SRC_SEL_OFFSET]
++#endif
++
++#endif
++	/* jump to generic resume */
++	b	cpu_resume
++ENDPROC(ambarella_cpu_resume)
++
+diff --git a/arch/arm/mach-ambarella/smp/Makefile b/arch/arm/mach-ambarella/smp/Makefile
+new file mode 100644
+index 00000000..6bf90022
+--- /dev/null
++++ b/arch/arm/mach-ambarella/smp/Makefile
+@@ -0,0 +1,24 @@
++#
++# arch/arm/plat-ambarella/smp/Makefile
++#
++# Author: Anthony Ginger <hfjiang@ambarella.com>
++#
++# Copyright (C) 2004-2011, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++obj-$(CONFIG_SMP)				+= smp.o headsmp.o
++
+diff --git a/arch/arm/mach-ambarella/smp/headsmp.S b/arch/arm/mach-ambarella/smp/headsmp.S
+new file mode 100644
+index 00000000..a10d926c
+--- /dev/null
++++ b/arch/arm/mach-ambarella/smp/headsmp.S
+@@ -0,0 +1,55 @@
++/*
++ * arch/arm/plat-ambarella/smp/headsmp.S
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/linkage.h>
++#include <linux/init.h>
++
++	__CPUINIT
++
++/*
++ * ambarella specific entry point for secondary CPUs.  This provides
++ * a "holding pen" into which all secondary cores are held until we're
++ * ready for them to initialise.
++ */
++ENTRY(ambarella_secondary_startup)
++	mrc	p15, 0, r0, c0, c0, 5
++	and	r0, r0, #0x00ffffff
++	adr	r4, 1f
++	ldmia	r4, {r5, r6}
++	sub	r4, r4, r5
++	add	r6, r6, r4
++pen:	ldr	r7, [r6]
++	cmp	r7, r0
++	bne	pen
++
++	/*
++	 * we've been released from the holding pen: secondary_stack
++	 * should now contain the SVC stack for this core
++	 */
++	b	secondary_startup
++ENDPROC(ambarella_secondary_startup)
++
++	.align 2
++1:	.long	.
++	.long	pen_release
++
+diff --git a/arch/arm/mach-ambarella/smp/smp.c b/arch/arm/mach-ambarella/smp/smp.c
+new file mode 100644
+index 00000000..138bd802
+--- /dev/null
++++ b/arch/arm/mach-ambarella/smp/smp.c
+@@ -0,0 +1,266 @@
++/*
++ * arch/arm/plat-ambarella/smp/smp.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/jiffies.h>
++#include <linux/smp.h>
++#include <linux/io.h>
++#include <linux/bootmem.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++
++#include <asm/cacheflush.h>
++#include <asm/smp_plat.h>
++#include <asm/smp_scu.h>
++#include <mach/hardware.h>
++#include <mach/common.h>
++#include <mach/init.h>
++
++static void __iomem *scu_base = __io(AMBARELLA_VA_SCU_BASE);
++static DEFINE_SPINLOCK(boot_lock);
++
++static u32 *cpux_jump_virt = NULL;
++extern void ambarella_secondary_startup(void);
++extern void ambvic_smp_softirq_init(void);
++
++
++/* Write pen_release in a way that is guaranteed to be visible to all
++ * observers, irrespective of whether they're taking part in coherency
++ * or not.  This is necessary for the hotplug code to work reliably. */
++static void write_pen_release(int val)
++{
++	pen_release = val;
++	smp_wmb();
++	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
++	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
++}
++
++static void write_cpux_jump_addr(unsigned int cpu, int addr)
++{
++	cpux_jump_virt[cpu] = addr;
++	smp_wmb();
++	__cpuc_flush_dcache_area(
++		&cpux_jump_virt[cpu], sizeof(cpux_jump_virt[cpu]));
++	outer_clean_range(ambarella_virt_to_phys((u32)&cpux_jump_virt[cpu]),
++			ambarella_virt_to_phys((u32)&cpux_jump_virt[cpu] + 1));
++}
++
++/* running on CPU1 */
++static void __cpuinit ambarella_smp_secondary_init(unsigned int cpu)
++{
++	/* let the primary processor know we're out of the
++	 * pen, then head off into the C entry point */
++	write_pen_release(-1);
++
++	/* Synchronise with the boot thread. */
++	spin_lock(&boot_lock);
++	spin_unlock(&boot_lock);
++}
++/* running on CPU0 */
++static int __cpuinit ambarella_smp_boot_secondary(unsigned int cpu,
++	struct task_struct *idle)
++{
++	unsigned long timeout;
++	unsigned long phys_cpu = cpu_logical_map(cpu);
++
++	BUG_ON(cpux_jump_virt == NULL);
++
++	scu_enable(scu_base);
++
++	/* Set synchronisation state between this boot processor
++	 * and the secondary one */
++	spin_lock(&boot_lock);
++
++	/* The secondary processor is waiting to be released from
++	 * the holding pen - release it, then wait for it to flag
++	 * that it has been released by resetting pen_release.
++	 *
++	 * Note that "pen_release" is the hardware CPU ID, whereas
++	 * "cpu" is Linux's internal ID. */
++	write_pen_release(phys_cpu);
++
++	write_cpux_jump_addr(cpu, virt_to_phys(ambarella_secondary_startup));
++
++#ifdef CONFIG_PLAT_AMBARELLA_SUPPORT_VIC
++	/* IPI interrupt on CPU1 may be unmasked, so this init is necessary */
++	ambvic_smp_softirq_init();
++#endif
++
++	/* Send the secondary CPU a soft interrupt, thereby causing
++	 * the boot monitor to read the system wide flags register,
++	 * and branch to the address found there. */
++	timeout = jiffies + (1 * HZ);
++	while (time_before(jiffies, timeout)) {
++		smp_rmb();
++
++		arch_send_wakeup_ipi_mask(cpumask_of(cpu));
++
++		if (pen_release == -1)
++			break;
++
++		udelay(10);
++	}
++
++	spin_unlock(&boot_lock);
++
++	return pen_release != -1 ? -ENOSYS : 0;
++}
++
++/* running on CPU0 */
++static void __init ambarella_smp_init_cpus(void)
++{
++	int i;
++	unsigned int ncores;
++
++	ncores = scu_get_core_count(scu_base);
++	if (ncores > nr_cpu_ids) {
++		pr_warning("SMP: cores(%u) greater than maximum(%u), clipping\n",
++			ncores, nr_cpu_ids);
++		ncores = nr_cpu_ids;
++	}
++
++	for (i = 0; i < ncores; i++)
++		set_cpu_possible(i, true);
++}
++
++/* running on CPU0 */
++static void __init ambarella_smp_prepare_cpus(unsigned int max_cpus)
++{
++	u32 cpux_jump, start_limit, end_limit;
++	int i, rval;
++
++	rval = of_property_read_u32(of_chosen, "ambarella,cpux_jump", &cpux_jump);
++	if (rval < 0) {
++		pr_err("No jump address for secondary cpu!\n");
++		return;
++	}
++
++	start_limit = get_ambarella_ppm_phys();
++	end_limit = get_ambarella_ppm_phys() + get_ambarella_ppm_size();
++	if (cpux_jump < start_limit || cpux_jump > end_limit) {
++		pr_err("Invalid secondary cpu jump address, 0x%08x!\n", cpux_jump);
++		return;
++	}
++
++	cpux_jump_virt = (u32 *)ambarella_phys_to_virt(cpux_jump);
++
++	for (i = 0; i < max_cpus; i++)
++		set_cpu_present(i, true);
++
++	scu_enable(scu_base);
++
++	for (i = 1; i < max_cpus; i++)
++		write_cpux_jump_addr(i, virt_to_phys(ambarella_secondary_startup));
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++static inline void cpu_enter_lowpower(void)
++{
++	unsigned int v;
++
++	flush_cache_all();
++	asm volatile(
++	"	mrc	p15, 0, %0, c1, c0, 1\n"
++	"	bic	%0, %0, #(1 << 6)\n"
++	"	bic	%0, %0, #(1 << 0)\n"
++	"	mcr	p15, 0, %0, c1, c0, 1\n"
++	"	mrc	p15, 0, %0, c1, c0, 0\n"
++	"	bic	%0, %0, #(1 << 2)\n"
++	"	mcr	p15, 0, %0, c1, c0, 0\n"
++		: "=&r" (v)
++		: "r" (0)
++		: "cc");
++}
++
++static inline void cpu_leave_lowpower(void)
++{
++	unsigned int v;
++
++	asm volatile(
++	"	mrc	p15, 0, %0, c1, c0, 0\n"
++	"	orr	%0, %0, #(1 << 2)\n"
++	"	mcr	p15, 0, %0, c1, c0, 0\n"
++	"	mrc	p15, 0, %0, c1, c0, 1\n"
++	"	orr	%0, %0, #(1 << 6)\n"
++	"	orr	%0, %0, #(1 << 0)\n"
++	"	mcr	p15, 0, %0, c1, c0, 1\n"
++		: "=&r" (v)
++		:
++		: "cc");
++}
++
++static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
++{
++	for (;;) {
++		wfi();
++
++		if (pen_release == cpu_logical_map(cpu)) {
++			/* OK, proper wakeup, we're done */
++			break;
++		}
++
++		/* Getting here, means that we have come out of WFI without
++		 * having been woken up - this shouldn't happen
++		 *
++		 * Just note it happening - when we're woken, we can report
++		 * its occurrence. */
++		(*spurious)++;
++	}
++}
++
++/* running on CPU1 */
++static void ambarella_smp_cpu_die(unsigned int cpu)
++{
++	int spurious = 0;
++
++	cpu_enter_lowpower();
++
++	platform_do_lowpower(cpu, &spurious);
++
++	cpu_leave_lowpower();
++
++	if (spurious)
++		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
++}
++
++/* running on CPU1 */
++static int ambarella_smp_cpu_disable(unsigned int cpu)
++{
++	return cpu == 0 ? -EPERM : 0;
++}
++#endif
++
++struct smp_operations ambarella_smp_ops __initdata = {
++	.smp_init_cpus		= ambarella_smp_init_cpus,
++	.smp_prepare_cpus	= ambarella_smp_prepare_cpus,
++	.smp_boot_secondary	= ambarella_smp_boot_secondary,
++	.smp_secondary_init	= ambarella_smp_secondary_init,
++#ifdef CONFIG_HOTPLUG_CPU
++	.cpu_disable		= ambarella_smp_cpu_disable,
++	.cpu_die		= ambarella_smp_cpu_die,
++#endif
++};
++
+diff --git a/arch/arm/mach-ambarella/soc/Makefile b/arch/arm/mach-ambarella/soc/Makefile
+new file mode 100644
+index 00000000..0e32c6fb
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/Makefile
+@@ -0,0 +1,30 @@
++#
++# arch/arm/mach-ambarella/soc/Makefile
++#
++# Author: Cao Rongrong <rrcao@ambarella.com>
++#
++# Copyright (C) 2012-2016, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++obj-$(CONFIG_PLAT_AMBARELLA_A5S)			+= a5s.o
++obj-$(CONFIG_PLAT_AMBARELLA_A7L)			+= a7l.o
++obj-$(CONFIG_PLAT_AMBARELLA_S2_CORTEX)			+= s2-cortex.o
++obj-$(CONFIG_PLAT_AMBARELLA_S2E)			+= s2e.o
++obj-$(CONFIG_PLAT_AMBARELLA_S2L)			+= s2l.o
++obj-$(CONFIG_PLAT_AMBARELLA_S3)				+= s3.o
++obj-$(CONFIG_PLAT_AMBARELLA_S3L)			+= s3l.o
++
+diff --git a/arch/arm/mach-ambarella/soc/a5s.c b/arch/arm/mach-ambarella/soc/a5s.c
+new file mode 100644
+index 00000000..5a8673ff
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/a5s.c
+@@ -0,0 +1,56 @@
++/*
++ * arch/arm/mach-ambarella/init-coconut.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/irqchip.h>
++#include <linux/of_platform.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/input.h>
++
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/system_info.h>
++#include <mach/hardware.h>
++#include <mach/init.h>
++
++static const char * const a5s_dt_board_compat[] = {
++	"ambarella,a5s",
++	NULL,
++};
++
++DT_MACHINE_START(A5S_DT, "Ambarella A5S (Flattened Device Tree)")
++	.restart_mode	= 's',
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++	.dt_compat	= a5s_dt_board_compat,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/soc/a7l.c b/arch/arm/mach-ambarella/soc/a7l.c
+new file mode 100644
+index 00000000..cbde2926
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/a7l.c
+@@ -0,0 +1,53 @@
++/*
++ * arch/arm/mach-ambarella/init-durian.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/irqchip.h>
++
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/system_info.h>
++
++#include <mach/hardware.h>
++#include <mach/init.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++
++#include <linux/input.h>
++
++/* ==========================================================================*/
++MACHINE_START(A7L_DT, "Durian")
++	.atag_offset	= 0x100,
++	.restart_mode	= 's',
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/soc/s2-cortex.c b/arch/arm/mach-ambarella/soc/s2-cortex.c
+new file mode 100644
+index 00000000..833fb5a3
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/s2-cortex.c
+@@ -0,0 +1,62 @@
++/*
++ * arch/arm/mach-ambarella/init-ginkgo.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/clk.h>
++#include <linux/of_platform.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <linux/irqchip.h>
++#include <linux/irqchip/arm-gic.h>
++#include <asm/gpio.h>
++#include <asm/system_info.h>
++
++#include <mach/hardware.h>
++#include <mach/init.h>
++#include <mach/common.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++
++
++static const char * const s2_dt_board_compat[] = {
++	"ambarella,s2",
++	NULL,
++};
++
++DT_MACHINE_START(S2_DT, "Ambarella S2 (Flattened Device Tree)")
++	.restart_mode	= 's',
++	.smp		= smp_ops(ambarella_smp_ops),
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++	.dt_compat	= s2_dt_board_compat,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/soc/s2e.c b/arch/arm/mach-ambarella/soc/s2e.c
+new file mode 100644
+index 00000000..cefd147b
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/s2e.c
+@@ -0,0 +1,48 @@
++/*
++ * arch/arm/mach-ambarella/soc/s2e.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/irqchip.h>
++#include <asm/mach/arch.h>
++#include <mach/init.h>
++#include <mach/common.h>
++
++static const char * const s2e_dt_board_compat[] = {
++	"ambarella,s2e",
++	NULL,
++};
++
++DT_MACHINE_START(S2E_DT, "Ambarella S2E (Flattened Device Tree)")
++	.restart_mode	= 's',
++	.smp		= smp_ops(ambarella_smp_ops),
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++	.dt_compat	= s2e_dt_board_compat,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/soc/s2l.c b/arch/arm/mach-ambarella/soc/s2l.c
+new file mode 100644
+index 00000000..3525c040
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/s2l.c
+@@ -0,0 +1,46 @@
++/*
++ * arch/arm/mach-ambarella/init-ixora.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2013, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/irqchip.h>
++#include <asm/mach/arch.h>
++#include <mach/init.h>
++
++static const char * const s2l_dt_board_compat[] = {
++	"ambarella,s2l",
++	NULL,
++};
++
++DT_MACHINE_START(S2L_DT, "Ambarella S2L (Flattened Device Tree)")
++	.restart_mode	= 's',
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++	.dt_compat	= s2l_dt_board_compat,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/soc/s3.c b/arch/arm/mach-ambarella/soc/s3.c
+new file mode 100644
+index 00000000..d2b7daa4
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/s3.c
+@@ -0,0 +1,48 @@
++/*
++ * arch/arm/mach-ambarella/soc/s3.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/irqchip.h>
++#include <asm/mach/arch.h>
++#include <mach/init.h>
++#include <mach/common.h>
++
++static const char * const s3_dt_board_compat[] = {
++	"ambarella,s3",
++	NULL,
++};
++
++DT_MACHINE_START(S3_DT, "Ambarella S3 (Flattened Device Tree)")
++	.restart_mode	= 's',
++	.smp		= smp_ops(ambarella_smp_ops),
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++	.dt_compat	= s3_dt_board_compat,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/soc/s3l.c b/arch/arm/mach-ambarella/soc/s3l.c
+new file mode 100644
+index 00000000..0cf97229
+--- /dev/null
++++ b/arch/arm/mach-ambarella/soc/s3l.c
+@@ -0,0 +1,46 @@
++/*
++ * arch/arm/mach-ambarella/init-ixora.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/irqchip.h>
++#include <asm/mach/arch.h>
++#include <mach/init.h>
++
++static const char * const s3l_dt_board_compat[] = {
++	"ambarella,s3l",
++	NULL,
++};
++
++DT_MACHINE_START(S3L_DT, "Ambarella S3L (Flattened Device Tree)")
++	.restart_mode	= 's',
++	.map_io		= ambarella_map_io,
++	.init_early	= ambarella_init_early,
++	.init_irq	= irqchip_init,
++	.init_time	= ambarella_timer_init,
++	.init_machine	= ambarella_init_machine,
++	.restart	= ambarella_restart_machine,
++	.dt_compat	= s3l_dt_board_compat,
++MACHINE_END
++
+diff --git a/arch/arm/mach-ambarella/timer.c b/arch/arm/mach-ambarella/timer.c
+new file mode 100644
+index 00000000..167c9f74
+--- /dev/null
++++ b/arch/arm/mach-ambarella/timer.c
+@@ -0,0 +1,622 @@
++/*
++ * arch/arm/plat-ambarella/generic/timer.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2012, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Default clock is from APB.
++ */
++
++#include <linux/semaphore.h>
++#include <linux/interrupt.h>
++#include <linux/clockchips.h>
++#include <linux/clk.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <asm/mach/time.h>
++#include <asm/smp_twd.h>
++#include <asm/sched_clock.h>
++#include <asm/localtimer.h>
++#include <plat/timer.h>
++#include <plat/event.h>
++
++static void __iomem *ce_base = NULL;
++static void __iomem *ce_ctrl_reg = NULL;
++static u32 ce_ctrl_offset = -1;
++
++static void __iomem *cs_base = NULL;
++static void __iomem *cs_ctrl_reg = NULL;
++static u32 cs_ctrl_offset = -1;
++
++#define AMBARELLA_TIMER_FREQ		clk_get_rate(clk_get(NULL, "gclk_apb"))
++#define AMBARELLA_TIMER_RATING		(300)
++
++static struct clock_event_device ambarella_clkevt;
++static struct clocksource ambarella_clksrc;
++static u32 ambarella_read_sched_clock(void);
++
++/* ==========================================================================*/
++struct amb_timer_pm_reg {
++	u32 clk_rate;
++	u32 ctrl_reg;
++	u32 status_reg;
++	u32 reload_reg;
++	u32 match1_reg;
++	u32 match2_reg;
++};
++
++static struct amb_timer_pm_reg amb_timer_ce_pm;
++static struct amb_timer_pm_reg amb_timer_cs_pm;
++
++static void ambarella_timer_suspend(u32 is_ce)
++{
++	struct amb_timer_pm_reg *amb_timer_pm;
++	void __iomem *regbase;
++	void __iomem *ctrl_reg;
++	u32 ctrl_offset;
++
++	amb_timer_pm = is_ce ? &amb_timer_ce_pm : &amb_timer_cs_pm;
++	regbase = is_ce ? ce_base : cs_base;
++	ctrl_reg = is_ce ? ce_ctrl_reg : cs_ctrl_reg;
++	ctrl_offset = is_ce ? ce_ctrl_offset : cs_ctrl_offset;
++
++	amb_timer_pm->clk_rate = AMBARELLA_TIMER_FREQ;
++	amb_timer_pm->ctrl_reg = (amba_readl(ctrl_reg) >> ctrl_offset) & 0xf;
++	amb_timer_pm->status_reg = amba_readl(regbase + TIMER_STATUS_OFFSET);
++	amb_timer_pm->reload_reg = amba_readl(regbase + TIMER_RELOAD_OFFSET);
++	amb_timer_pm->match1_reg = amba_readl(regbase + TIMER_MATCH1_OFFSET);
++	amb_timer_pm->match2_reg = amba_readl(regbase + TIMER_MATCH2_OFFSET);
++
++	amba_clrbitsl(ctrl_reg, 0xf << ctrl_offset);
++}
++
++static void ambarella_timer_resume(u32 is_ce)
++{
++	struct clock_event_device *clkevt = &ambarella_clkevt;
++	struct clocksource *clksrc = &ambarella_clksrc;
++	struct amb_timer_pm_reg *amb_timer_pm;
++	void __iomem *regbase;
++	void __iomem *ctrl_reg;
++	u32 ctrl_offset, clk_rate;
++
++	amb_timer_pm = is_ce ? &amb_timer_ce_pm : &amb_timer_cs_pm;
++	regbase = is_ce ? ce_base : cs_base;
++	ctrl_reg = is_ce ? ce_ctrl_reg : cs_ctrl_reg;
++	ctrl_offset = is_ce ? ce_ctrl_offset : cs_ctrl_offset;
++
++	amba_clrbitsl(ctrl_reg, 0xf << ctrl_offset);
++
++	amba_writel(regbase + TIMER_STATUS_OFFSET, amb_timer_pm->status_reg);
++	amba_writel(regbase + TIMER_RELOAD_OFFSET, amb_timer_pm->reload_reg);
++	amba_writel(regbase + TIMER_MATCH1_OFFSET, amb_timer_pm->match1_reg);
++	amba_writel(regbase + TIMER_MATCH2_OFFSET, amb_timer_pm->match2_reg);
++
++	clk_rate = AMBARELLA_TIMER_FREQ;
++	if (amb_timer_pm->clk_rate == clk_rate)
++		goto resume_exit;
++
++	amb_timer_pm->clk_rate = clk_rate;
++
++	if (is_ce) {
++		clockevents_update_freq(clkevt, clk_rate);
++	} else {
++		clocksource_change_rating(clksrc, 0);
++		__clocksource_updatefreq_hz(clksrc, clk_rate);
++		clocksource_change_rating(clksrc, AMBARELLA_TIMER_RATING);
++	}
++
++resume_exit:
++	amba_setbitsl(ctrl_reg, amb_timer_pm->ctrl_reg << ctrl_offset);
++}
++
++
++/* ==========================================================================*/
++static inline void ambarella_ce_timer_disable(void __iomem *ctrl_reg, u32 offs)
++{
++	amba_clrbitsl(ctrl_reg, TIMER_CTRL_EN << offs);
++}
++
++static inline void ambarella_ce_timer_enable(void __iomem *ctrl_reg, u32 offs)
++{
++	amba_setbitsl(ctrl_reg, TIMER_CTRL_EN << offs);
++}
++
++static inline void ambarella_ce_timer_misc(void __iomem *ctrl_reg, u32 offs)
++{
++	amba_setbitsl(ctrl_reg, TIMER_CTRL_OF << offs);
++	amba_clrbitsl(ctrl_reg, TIMER_CTRL_CSL << offs);
++}
++
++static inline void ambarella_ce_timer_set_periodic
++		(void __iomem *base_reg, void __iomem *ctrl_reg, u32 offs)
++{
++	u32 cnt = AMBARELLA_TIMER_FREQ / HZ;
++
++	amba_writel(base_reg + TIMER_STATUS_OFFSET, cnt);
++	amba_writel(base_reg + TIMER_RELOAD_OFFSET, cnt);
++	amba_writel(base_reg + TIMER_MATCH1_OFFSET, 0x0);
++	amba_writel(base_reg + TIMER_MATCH2_OFFSET, 0x0);
++
++	ambarella_ce_timer_misc(ctrl_reg, offs);
++}
++
++static inline void ambarella_ce_timer_set_oneshot
++		(void __iomem *base_reg, void __iomem *ctrl_reg, u32 offs)
++{
++	amba_writel(base_reg + TIMER_STATUS_OFFSET, 0x0);
++	amba_writel(base_reg + TIMER_RELOAD_OFFSET, 0xffffffff);
++	amba_writel(base_reg + TIMER_MATCH1_OFFSET, 0x0);
++	amba_writel(base_reg + TIMER_MATCH2_OFFSET, 0x0);
++
++	ambarella_ce_timer_misc(ctrl_reg, offs);
++}
++
++static void inline ambarella_ce_set_mode(
++		void __iomem *base_reg, void __iomem *ctrl_reg, u32 ctrl_offset,
++		enum clock_event_mode mode, struct clock_event_device *clkevt)
++{
++	switch (mode) {
++	case CLOCK_EVT_MODE_PERIODIC:
++		ambarella_ce_timer_disable(ctrl_reg, ctrl_offset);
++		ambarella_ce_timer_set_periodic(base_reg, ctrl_reg, ctrl_offset);
++		ambarella_ce_timer_enable(ctrl_reg, ctrl_offset);
++		break;
++	case CLOCK_EVT_MODE_ONESHOT:
++		ambarella_ce_timer_disable(ctrl_reg, ctrl_offset);
++		ambarella_ce_timer_set_oneshot(base_reg, ctrl_reg, ctrl_offset);
++		ambarella_ce_timer_enable(ctrl_reg, ctrl_offset);
++		break;
++	case CLOCK_EVT_MODE_UNUSED:
++	case CLOCK_EVT_MODE_SHUTDOWN:
++		ambarella_ce_timer_disable(ctrl_reg, ctrl_offset);
++		break;
++	case CLOCK_EVT_MODE_RESUME:
++		break;
++	}
++	pr_debug("%s:%d\n", __func__, mode);
++}
++
++static void inline ambarella_ce_set_next_event(void __iomem *base_reg,
++		unsigned long delta, struct clock_event_device *clkevt)
++{
++	amba_writel(base_reg + TIMER_STATUS_OFFSET, delta);
++}
++
++/* ==========================================================================*/
++
++static void ambarella_global_ce_set_mode(enum clock_event_mode mode,
++	struct clock_event_device *clkevt)
++{
++	ambarella_ce_set_mode(ce_base, ce_ctrl_reg, ce_ctrl_offset, mode, clkevt);
++}
++
++static int ambarella_global_ce_set_next_event(unsigned long delta,
++	struct clock_event_device *clkevt)
++{
++	ambarella_ce_set_next_event(ce_base, delta, clkevt);
++	return 0;
++}
++
++static void ambarella_global_ce_suspend(struct clock_event_device *dev)
++{
++	ambarella_timer_suspend(1);
++}
++
++static void ambarella_global_ce_resume(struct clock_event_device *dev)
++{
++	ambarella_timer_resume(1);
++}
++
++static struct clock_event_device ambarella_clkevt = {
++	.name		= "ambarella-clkevt",
++	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++	.rating		= AMBARELLA_TIMER_RATING,
++	.set_next_event	= ambarella_global_ce_set_next_event,
++	.set_mode	= ambarella_global_ce_set_mode,
++	.mode		= CLOCK_EVT_MODE_UNUSED,
++	.suspend	= ambarella_global_ce_suspend,
++	.resume		= ambarella_global_ce_resume,
++};
++
++static irqreturn_t ambarella_global_ce_interrupt(int irq, void *dev_id)
++{
++	struct clock_event_device *clkevt = &ambarella_clkevt;
++
++	clkevt->event_handler(clkevt);
++	return IRQ_HANDLED;
++}
++
++static struct irqaction ambarella_ce_timer_irq = {
++	.name		= "ambarella-ce-timer",
++	.flags		= IRQF_TIMER | IRQF_TRIGGER_RISING,
++	.handler	= ambarella_global_ce_interrupt,
++};
++
++/* ==========================================================================*/
++static inline void ambarella_cs_timer_init(void)
++{
++	amba_clrbitsl(cs_ctrl_reg, TIMER_CTRL_EN << cs_ctrl_offset);
++	amba_clrbitsl(cs_ctrl_reg, TIMER_CTRL_OF << cs_ctrl_offset);
++	amba_clrbitsl(cs_ctrl_reg, TIMER_CTRL_CSL << cs_ctrl_offset);
++	amba_writel(cs_base + TIMER_STATUS_OFFSET, 0xffffffff);
++	amba_writel(cs_base + TIMER_RELOAD_OFFSET, 0xffffffff);
++	amba_writel(cs_base + TIMER_MATCH1_OFFSET, 0x0);
++	amba_writel(cs_base + TIMER_MATCH2_OFFSET, 0x0);
++	amba_setbitsl(cs_ctrl_reg, TIMER_CTRL_EN << cs_ctrl_offset);
++}
++
++static cycle_t ambarella_cs_timer_read(struct clocksource *cs)
++{
++	return (-(u32)amba_readl(cs_base + TIMER_STATUS_OFFSET));
++}
++
++static void ambarella_cs_timer_suspend(struct clocksource *dev)
++{
++	ambarella_timer_suspend(0);
++}
++
++static void ambarella_cs_timer_resume(struct clocksource *dev)
++{
++	ambarella_timer_resume(0);
++}
++
++static struct clocksource ambarella_clksrc = {
++	.name		= "ambarella-cs-timer",
++	.rating		= AMBARELLA_TIMER_RATING,
++	.read		= ambarella_cs_timer_read,
++	.mask		= CLOCKSOURCE_MASK(32),
++	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
++	.suspend	= ambarella_cs_timer_suspend,
++	.resume		= ambarella_cs_timer_resume,
++};
++
++static u32 notrace ambarella_read_sched_clock(void)
++{
++	return (-(u32)amba_readl(cs_base + TIMER_STATUS_OFFSET));
++}
++
++/* ==========================================================================*/
++/*define a event struct to update timer*/
++struct ambarella_timer_notifier {
++	struct notifier_block 		system_event;
++	struct semaphore		system_event_sem;
++} amba_timer_notifier;
++
++static int ambarella_timer_system_event(struct notifier_block *nb,
++	unsigned long val, void *data)
++{
++	unsigned long flags;
++
++	switch (val) {
++	case AMBA_EVENT_PRE_CPUFREQ:
++		down(&(amba_timer_notifier.system_event_sem));
++		break;
++
++	case AMBA_EVENT_POST_CPUFREQ:
++		local_irq_save(flags);
++		clockevents_update_freq(&ambarella_clkevt, AMBARELLA_TIMER_FREQ);
++
++		clocksource_change_rating(&ambarella_clksrc, 0);
++		__clocksource_updatefreq_hz(&ambarella_clksrc, AMBARELLA_TIMER_FREQ);
++		clocksource_change_rating(&ambarella_clksrc, AMBARELLA_TIMER_RATING);
++		local_irq_restore(flags);
++		up(&(amba_timer_notifier.system_event_sem));
++		break;
++
++	default:
++		break;
++	}
++
++	return NOTIFY_OK;
++}
++/* ==========================================================================*/
++static const struct of_device_id clock_event_match[] __initconst = {
++	{ .compatible = "ambarella,clock-event" },
++	{ },
++};
++
++static const struct of_device_id clock_source_match[] __initconst = {
++	{ .compatible = "ambarella,clock-source" },
++	{ },
++};
++
++static void __init ambarella_clockevent_init(void)
++{
++	struct device_node *np;
++	struct clock_event_device *clkevt;
++	int rval, irq;
++
++	np = of_find_matching_node(NULL, clock_event_match);
++	if (!np) {
++		pr_err("Can't find clock event node\n");
++		return;
++	}
++
++	ce_base = of_iomap(np, 0);
++	if (!ce_base) {
++		pr_err("%s: Failed to map event base\n", __func__);
++		return;
++	}
++
++	ce_ctrl_reg = of_iomap(np, 1);
++	if (!ce_ctrl_reg) {
++		pr_err("%s: Failed to map timer-ctrl base\n", __func__);
++		return;
++	}
++
++	irq = irq_of_parse_and_map(np, 0);
++	if (irq <= 0) {
++		pr_err("%s: Can't get irq\n", __func__);
++		return;
++	}
++
++	rval = of_property_read_u32(np, "ctrl-offset", &ce_ctrl_offset);
++	if (rval < 0) {
++		pr_err("%s: Can't get ctrl offset\n", __func__);
++		return;
++	}
++
++	of_node_put(np);
++
++	clkevt = &ambarella_clkevt;
++	clkevt->cpumask = cpumask_of(0);
++	clkevt->irq = irq;
++
++	rval = setup_irq(clkevt->irq, &ambarella_ce_timer_irq);
++	if (rval) {
++		printk(KERN_ERR "Failed to register timer IRQ: %d\n", rval);
++		BUG();
++	}
++
++	clockevents_config_and_register(clkevt, AMBARELLA_TIMER_FREQ, 1, 0xffffffff);
++}
++
++static void __init ambarella_clocksource_init(void)
++{
++	struct device_node *np;
++	struct clocksource *clksrc;
++	int rval;
++
++	np = of_find_matching_node(NULL, clock_source_match);
++	if (!np) {
++		pr_err("Can't find clock source node\n");
++		return;
++	}
++
++	cs_base = of_iomap(np, 0);
++	if (!cs_base) {
++		pr_err("%s: Failed to map source base\n", __func__);
++		return;
++	}
++
++	cs_ctrl_reg = of_iomap(np, 1);
++	if (!cs_ctrl_reg) {
++		pr_err("%s: Failed to map timer-ctrl base\n", __func__);
++		return;
++	}
++
++	rval = of_property_read_u32(np, "ctrl-offset", &cs_ctrl_offset);
++	if (rval < 0) {
++		pr_err("%s: Can't get ctrl offset\n", __func__);
++		return;
++	}
++
++	of_node_put(np);
++
++	clksrc = &ambarella_clksrc;
++
++	ambarella_cs_timer_init();
++
++	clocksource_register_hz(clksrc, AMBARELLA_TIMER_FREQ);
++
++	pr_debug("%s: mult = %u, shift = %u\n",
++		clksrc->name, clksrc->mult, clksrc->shift);
++
++	setup_sched_clock(ambarella_read_sched_clock, 32, AMBARELLA_TIMER_FREQ);
++
++	/*add notifier to update the timer when the cpu frequency is changed*/
++	sema_init(&amba_timer_notifier.system_event_sem, 1);
++	amba_timer_notifier.system_event.notifier_call = ambarella_timer_system_event;
++	ambarella_register_event_notifier(&amba_timer_notifier.system_event);
++}
++
++#ifdef CONFIG_HAVE_ARM_TWD
++static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, AMBARELLA_VA_PT_WD_BASE, IRQ_LOCALTIMER);
++
++static void __init ambarella_smp_twd_init(void)
++{
++	int err = twd_local_timer_register(&twd_local_timer);
++	if (err)
++		pr_err("twd_local_timer_register failed %d\n", err);
++}
++#endif
++
++#ifdef CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS
++
++struct ambarella_local_clkevt {
++	struct clock_event_device *evt;
++	void __iomem *base;
++	void __iomem *ctrl_reg;
++	u32 ctrl_offset;
++	char name[16];
++};
++
++static DEFINE_PER_CPU(struct ambarella_local_clkevt, percpu_clkevt);
++
++static void __iomem *local_clkevt_base[NR_CPUS];
++static void __iomem *local_clkevt_ctrl_reg[NR_CPUS];
++static int local_clkevt_irq[NR_CPUS];
++static u32 local_clkevt_ctrl_offset[NR_CPUS];
++static struct irqaction local_clkevt_irqaction[NR_CPUS];
++
++/* ==========================================================================*/
++
++static void ambarella_local_ce_set_mode(enum clock_event_mode mode,
++	struct clock_event_device *clkevt)
++{
++	struct ambarella_local_clkevt *local_clkevt;
++	void __iomem *base_reg;
++	void __iomem *ctrl_reg;
++	u32 ctrl_offset;
++
++	local_clkevt = this_cpu_ptr(&percpu_clkevt);
++	base_reg = local_clkevt->base;
++	ctrl_reg = local_clkevt->ctrl_reg;
++	ctrl_offset = local_clkevt->ctrl_offset;
++
++	ambarella_ce_set_mode(base_reg, ctrl_reg, ctrl_offset, mode, clkevt);
++}
++
++
++static int ambarella_local_ce_set_next_event(unsigned long delta,
++	struct clock_event_device *clkevt)
++{
++	struct ambarella_local_clkevt *local_clkevt;
++
++	local_clkevt = this_cpu_ptr(&percpu_clkevt);
++	ambarella_ce_set_next_event(local_clkevt->base, delta, clkevt);
++
++	return 0;
++}
++
++static irqreturn_t ambarella_local_ce_interrupt(int irq, void *dev_id)
++{
++	struct clock_event_device *clkevt = dev_id;
++
++	clkevt->event_handler(clkevt);
++	return IRQ_HANDLED;
++}
++
++static int __cpuinit ambarella_local_timer_setup(struct clock_event_device *evt)
++{
++	struct ambarella_local_clkevt *local_clkevt;
++	unsigned int cpu = smp_processor_id();
++	int rval;
++
++	local_clkevt = this_cpu_ptr(&percpu_clkevt);
++	local_clkevt->evt = evt;
++	local_clkevt->base = local_clkevt_base[cpu];
++	local_clkevt->ctrl_reg = local_clkevt_ctrl_reg[cpu];
++	local_clkevt->ctrl_offset = local_clkevt_ctrl_offset[cpu];
++	sprintf(local_clkevt->name, "local_clkevt%d", cpu);
++
++	evt->name = local_clkevt->name;
++	evt->cpumask = cpumask_of(cpu);
++	evt->set_next_event = ambarella_local_ce_set_next_event;
++	evt->set_mode = ambarella_local_ce_set_mode;
++	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
++	evt->rating = AMBARELLA_TIMER_RATING + 30;
++
++	clockevents_config_and_register(evt, AMBARELLA_TIMER_FREQ, 1, 0xffffffff);
++
++	evt->irq = local_clkevt_irq[cpu];
++	local_clkevt_irqaction[cpu].name = local_clkevt->name;
++	local_clkevt_irqaction[cpu].flags =
++		IRQF_TIMER | IRQF_TRIGGER_RISING | IRQF_NOBALANCING;
++	local_clkevt_irqaction[cpu].handler = ambarella_local_ce_interrupt;
++	local_clkevt_irqaction[cpu].dev_id = evt;
++
++	irq_set_affinity(evt->irq, cpumask_of(cpu));
++	rval = setup_irq(evt->irq, &local_clkevt_irqaction[cpu]);
++	if (rval) {
++		printk(KERN_ERR "Failed to register local timer IRQ: %d\n", rval);
++		BUG();
++	}
++
++	return 0;
++}
++
++
++static void ambarella_local_timer_stop(struct clock_event_device *evt)
++{
++	unsigned int cpu = smp_processor_id();
++
++	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
++	remove_irq(evt->irq, &local_clkevt_irqaction[cpu]);
++}
++
++static struct local_timer_ops ambarella_local_timer_ops __cpuinitdata = {
++	.setup	= ambarella_local_timer_setup,
++	.stop	= ambarella_local_timer_stop,
++};
++
++/* ==========================================================================*/
++static const struct of_device_id local_clkevt_match[] __initconst = {
++	{ .compatible = "ambarella,local-clock-event" },
++	{ },
++};
++
++static void __init ambarella_local_clockevent_init(void)
++{
++	struct device_node *np;
++	int i, rval;
++
++	np = of_find_matching_node(NULL, local_clkevt_match);
++	if (!np) {
++		pr_err("Can't find local clock event node\n");
++		return;
++	}
++
++	for (i = 0; i < NR_CPUS; i++) {
++		local_clkevt_base[i] = of_iomap(np, i * 2);
++		if (!local_clkevt_base[i]) {
++			pr_err("%s: Failed to map event base[%d]\n", __func__, i);
++			return;
++		}
++
++		local_clkevt_ctrl_reg[i] = of_iomap(np, i * 2 + 1);
++		if (!local_clkevt_ctrl_reg[i]) {
++			pr_err("%s: Failed to map event base[%d]\n", __func__, i);
++			return;
++		}
++
++		local_clkevt_irq[i] = irq_of_parse_and_map(np, i);
++		if (local_clkevt_irq[i] <= 0) {
++			pr_err("%s: Can't get irq\n", __func__);
++			return;
++		}
++	}
++
++	rval = of_property_read_u32_array(np, "ctrl-offset",
++				local_clkevt_ctrl_offset, NR_CPUS);
++	if (rval < 0) {
++		pr_err("%s: Can't get local ctrl offset\n", __func__);
++		return;
++	}
++
++	of_node_put(np);
++
++	local_timer_register(&ambarella_local_timer_ops);
++}
++
++#endif
++
++
++void __init ambarella_timer_init(void)
++{
++	ambarella_clockevent_init();
++	ambarella_clocksource_init();
++
++#ifdef CONFIG_HAVE_ARM_TWD
++	ambarella_smp_twd_init();
++#endif
++#ifdef CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS
++	ambarella_local_clockevent_init();
++#endif
++}
++
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+index c6926eae..1e1df25d 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -878,6 +878,63 @@ config CACHE_PL310
+ 	  This option enables optimisations for the PL310 cache
+ 	  controller.
+ 
++config CACHE_PL310_EARLY_BRESP
++	bool "Enable early write response (BRESP) optmisation"
++	depends on CACHE_PL310
++	default n
++	help
++	  The AXI protocol specifies that the write response can only be
++	  sent back to an AXI master when the last write data has been
++	  accepted. This optimization enables the L2CC (L2C-310) to send
++	  the write response of certain write transactions as soon as the
++	  store buffer accepts the write address
++
++config CACHE_PL310_PREFETCH_OFFSET
++	int "Prefetch offset"
++	range 0 31
++	depends on CACHE_PL310
++	default 0
++	help
++	  When prefetch is enabled, if one of the slave ports receives
++	  a cacheable read transaction, a cache lookup is performed on
++	  the subsequent cache line. Bits [4:0] of the Prefetch Control
++	  Register provide the address of the subsequent cache line.
++	  If a miss occurs, the cache line is fetched from L3, and
++	  allocated to the L2 cache.
++
++config CACHE_PL310_FULL_LINE_OF_ZERO
++	bool "Enable write full line of zero optimisation"
++	depends on CACHE_PL310
++	default n
++	help
++	  When the L2CC (L2C-310) AXI slave ports receive a write
++	  transaction with AWUSERSx[10], it indicates that the write
++	  actually targets a whole cache line and that all data of
++	  this cache line must be reset to zero. The Cortex-A9 processor
++	  is likely to use this feature when a CPU is executing a memset
++	  routine to initialise a particular memory area.
++
++	  When the L2CC (L2C-310) receives such a write transaction it
++	  ignores the AXI attributes attached to the transaction, size,
++	  length, data, and strobes for example, because the whole cache
++	  line must be reset.
++
++config CACHE_PL310_DOUBLE_LINEFILL
++	bool "Enable double linefill optimisation"
++	depends on CACHE_PL310
++	default n
++	help
++	  The L2C-310 cache line length is 32-byte. Therefore, by default,
++	  on each L2 cache miss, L2C-310 issues 32-byte linefills,
++	  4 x 64-bit read bursts, to the L3 memory system. L2C-310 can issue
++	  64-byte linefills, 8 x 64-bit read bursts, on an L2 cache miss.
++
++	  When the L2C-310 is waiting for the data from L3, it performs a
++	  lookup on the second cache line targeted by the 64-byte linefill.
++	  If it misses, data corresponding to the second cache line are
++	  allocated to the L2 cache.  If it hits, data corresponding to the
++	  second cache line are discarded.
++
+ config CACHE_TAUROS2
+ 	bool "Enable the Tauros2 L2 cache controller"
+ 	depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
+@@ -909,7 +966,7 @@ config ARM_L1_CACHE_SHIFT
+ config ARM_DMA_MEM_BUFFERABLE
+ 	bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
+ 	depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
+-		     MACH_REALVIEW_PB11MP)
++		     MACH_REALVIEW_PB11MP || PLAT_AMBARELLA)
+ 	default y if CPU_V6 || CPU_V6K || CPU_V7
+ 	help
+ 	  Historically, the kernel has used strongly ordered mappings to
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index 1fe0bf5c..a8e039cf 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -971,6 +971,14 @@ static int __init alignment_init(void)
+ 		set_cr(cr_alignment);
+ 		ai_usermode = safe_usermode(ai_usermode, false);
+ 	}
++#if defined(CONFIG_PLAT_AMBARELLA_A5S)
++	cr_alignment |= CR_A;
++	cr_no_alignment |= CR_A;
++	cr_alignment &= ~CR_U;
++	cr_no_alignment &= ~CR_U;
++	set_cr(cr_alignment);
++	ai_usermode = UM_FIXUP;
++#endif
+ #endif
+ 
+ 	hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
+diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
+index c465faca..4bd092cf 100644
+--- a/arch/arm/mm/cache-l2x0.c
++++ b/arch/arm/mm/cache-l2x0.c
+@@ -34,6 +34,7 @@ static DEFINE_RAW_SPINLOCK(l2x0_lock);
+ static u32 l2x0_way_mask;	/* Bitmask of active ways */
+ static u32 l2x0_size;
+ static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
++static const char *l2x0_type = NULL;
+ 
+ /* Aurora don't have the cache ID register available, so we have to
+  * pass it though the device tree */
+@@ -133,6 +134,10 @@ static void l2x0_cache_sync(void)
+ 	unsigned long flags;
+ 
+ 	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
+ 	cache_sync();
+ 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ }
+@@ -152,6 +157,10 @@ static void l2x0_flush_all(void)
+ 
+ 	/* clean all ways */
+ 	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
+ 	__l2x0_flush_all();
+ 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ }
+@@ -162,6 +171,10 @@ static void l2x0_clean_all(void)
+ 
+ 	/* clean all ways */
+ 	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
+ 	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
+ 	cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
+ 	cache_sync();
+@@ -188,6 +201,10 @@ static void l2x0_inv_range(unsigned long start, unsigned long end)
+ 	unsigned long flags;
+ 
+ 	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
+ 	if (start & (CACHE_LINE_SIZE - 1)) {
+ 		start &= ~(CACHE_LINE_SIZE - 1);
+ 		debug_writel(0x03);
+@@ -232,6 +249,10 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
+ 	}
+ 
+ 	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
+ 	start &= ~(CACHE_LINE_SIZE - 1);
+ 	while (start < end) {
+ 		unsigned long blk_end = start + min(end - start, 4096UL);
+@@ -262,6 +283,10 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
+ 	}
+ 
+ 	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
+ 	start &= ~(CACHE_LINE_SIZE - 1);
+ 	while (start < end) {
+ 		unsigned long blk_end = start + min(end - start, 4096UL);
+@@ -283,6 +308,25 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
+ 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ }
+ 
++static void l2x0_enable(void)
++{
++	unsigned long flags;
++
++	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	if (readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN) {
++		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++		return;
++	}
++
++	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
++	cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
++	cache_sync();
++	writel_relaxed(1, l2x0_base + L2X0_CTRL);
++	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++
++	printk(KERN_DEBUG "%s cache controller enabled\n", l2x0_type);
++}
++
+ static void l2x0_disable(void)
+ {
+ 	unsigned long flags;
+@@ -294,6 +338,18 @@ static void l2x0_disable(void)
+ 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ }
+ 
++static int l2x0_is_enabled(void)
++{
++	unsigned long flags;
++	u32 status;
++
++	raw_spin_lock_irqsave(&l2x0_lock, flags);
++	status = readl_relaxed(l2x0_base + L2X0_CTRL);
++	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
++
++	return (status & L2X0_CTRL_EN);
++}
++
+ static void l2x0_unlock(u32 cache_id)
+ {
+ 	int lockregs;
+@@ -320,14 +376,14 @@ static void l2x0_unlock(u32 cache_id)
+ 	}
+ }
+ 
+-void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
++void l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+ {
+ 	u32 aux;
+ 	u32 cache_id;
+ 	u32 way_size = 0;
+ 	int ways;
+ 	int way_size_shift = L2X0_WAY_SIZE_SHIFT;
+-	const char *type;
++//	const char *type;
+ 
+ 	l2x0_base = base;
+ 	if (cache_id_part_number_from_dt)
+@@ -346,7 +402,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+ 			ways = 16;
+ 		else
+ 			ways = 8;
+-		type = "L310";
++		l2x0_type = "L310";
+ #ifdef CONFIG_PL310_ERRATA_753970
+ 		/* Unmapped register. */
+ 		sync_reg_offset = L2X0_DUMMY_REG;
+@@ -356,7 +412,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+ 		break;
+ 	case L2X0_CACHE_ID_PART_L210:
+ 		ways = (aux >> 13) & 0xf;
+-		type = "L210";
++		l2x0_type = "L210";
+ 		break;
+ 
+ 	case AURORA_CACHE_ID:
+@@ -364,12 +420,12 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+ 		ways = (aux >> 13) & 0xf;
+ 		ways = 2 << ((ways + 1) >> 2);
+ 		way_size_shift = AURORA_WAY_SIZE_SHIFT;
+-		type = "Aurora";
++		l2x0_type = "Aurora";
+ 		break;
+ 	default:
+ 		/* Assume unknown chips have 8 ways */
+ 		ways = 8;
+-		type = "L2x0 series";
++		l2x0_type = "L2x0 series";
+ 		break;
+ 	}
+ 
+@@ -414,10 +470,13 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+ 		outer_cache.sync = l2x0_cache_sync;
+ 		outer_cache.flush_all = l2x0_flush_all;
+ 		outer_cache.inv_all = l2x0_inv_all;
++		outer_cache.clean_all = l2x0_clean_all;
+ 		outer_cache.disable = l2x0_disable;
++		outer_cache.enable = l2x0_enable;
++		outer_cache.is_enabled = l2x0_is_enabled;
+ 	}
+ 
+-	printk(KERN_INFO "%s cache controller enabled\n", type);
++	printk(KERN_INFO "%s cache controller enabled\n", l2x0_type);
+ 	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
+ 			ways, cache_id, aux, l2x0_size);
+ }
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index 4c7d5cdd..5cc87612 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -418,7 +418,9 @@ static void __init build_mem_type_table(void)
+ 			 * (Uncached Normal memory)
+ 			 */
+ 			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_TEX(1);
++#if !defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+ 			mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(1);
++#endif
+ 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_BUFFERABLE;
+ 		} else if (cpu_is_xsc3()) {
+ 			/*
+diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
+index 4562ebf8..2fde3b21 100644
+--- a/arch/arm/mm/proc-v7.S
++++ b/arch/arm/mm/proc-v7.S
+@@ -324,6 +324,12 @@ __v7_setup:
+ 	mcrlt	p15, 0, r10, c15, c0, 1		@ write diagnostic register
+ 1:
+ #endif
++	mrc	p15, 0, r10, c1, c0, 1		@ read aux control register
++	orr	r10, r10, #(1 << 2)		@ set Dside prefetch to 1
++#ifdef CONFIG_CACHE_PL310
++	orr	r10, r10, #(1 << 1)		@ set Prefetch hint to 1
++#endif
++	mcr	p15, 0, r10, c1, c0, 1		@ write aux control register
+ 
+ 3:	mov	r10, #0
+ 	mcr	p15, 0, r10, c7, c5, 0		@ I+BTB cache invalidate
+diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
+index a10297da..6c84ce0a 100644
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -232,6 +232,7 @@ micro9m			MACH_MICRO9M		MICRO9M			1169
+ bug			MACH_BUG		BUG			1179
+ at91sam9263ek		MACH_AT91SAM9263EK	AT91SAM9263EK		1202
+ em7210			MACH_EM7210		EM7210			1212
++ambarella		MACH_AMBARELLA		AMBARELLA		1223
+ vpac270			MACH_VPAC270		VPAC270			1227
+ treo680			MACH_TREO680		TREO680			1230
+ zylonite		MACH_ZYLONITE		ZYLONITE		1233
+@@ -491,6 +492,8 @@ smdkc210		MACH_SMDKC210		SMDKC210		2838
+ t5325			MACH_T5325		T5325			2846
+ income			MACH_INCOME		INCOME			2849
+ goni			MACH_GONI		GONI			2862
++coconut			MACH_COCONUT		COCONUT			2872
++durian			MACH_DURIAN		DURIAN			2873
+ bv07			MACH_BV07		BV07			2882
+ openrd_ultimate		MACH_OPENRD_ULTIMATE	OPENRD_ULTIMATE		2884
+ devixp			MACH_DEVIXP		DEVIXP			2885
+@@ -522,6 +525,7 @@ torbreck		MACH_TORBRECK		TORBRECK		3090
+ prima2_evb		MACH_PRIMA2_EVB		PRIMA2_EVB		3103
+ paz00			MACH_PAZ00		PAZ00			3128
+ acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129
++elephant		MACH_ELEPHANT		ELEPHANT		3180
+ ag5evm			MACH_AG5EVM		AG5EVM			3189
+ ics_if_voip		MACH_ICS_IF_VOIP	ICS_IF_VOIP		3206
+ wlf_cragg_6410		MACH_WLF_CRAGG_6410	WLF_CRAGG_6410		3207
+@@ -619,6 +623,8 @@ th_link_eth		MACH_TH_LINK_ETH	TH_LINK_ETH		4156
+ tn_muninn		MACH_TN_MUNINN		TN_MUNINN		4157
+ rampage			MACH_RAMPAGE		RAMPAGE			4158
+ visstrim_mv10		MACH_VISSTRIM_MV10	VISSTRIM_MV10		4159
++hyacinth_0		MACH_HYACINTH_0		HYACINTH_0		4221
++hyacinth_1		MACH_HYACINTH_1		HYACINTH_1		4222
+ mx28_wilma		MACH_MX28_WILMA		MX28_WILMA		4164
+ msm8625_ffa		MACH_MSM8625_FFA	MSM8625_FFA		4166
+ vpu101			MACH_VPU101		VPU101			4167
+@@ -1007,3 +1013,6 @@ eco5_bx2		MACH_ECO5_BX2		ECO5_BX2		4572
+ eukrea_cpuimx28sd	MACH_EUKREA_CPUIMX28SD	EUKREA_CPUIMX28SD	4573
+ domotab			MACH_DOMOTAB		DOMOTAB			4574
+ pfla03			MACH_PFLA03		PFLA03			4575
++ixora			MACH_IXORA		IXORA			4603
++juglans			MACH_JUGLANS		JUGLANS			4604
++ambs2e			MACH_AMBS2E		AMBS2E			5009
+\ No newline at end of file
+diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
+index 8a029505..2f1c3c26 100644
+--- a/arch/blackfin/include/asm/ftrace.h
++++ b/arch/blackfin/include/asm/ftrace.h
+@@ -66,16 +66,7 @@ extern inline void *return_address(unsigned int level)
+ 
+ #endif /* CONFIG_FRAME_POINTER */
+ 
+-#define HAVE_ARCH_CALLER_ADDR
+-
+-/* inline function or macro may lead to unexpected result */
+-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+-#define CALLER_ADDR1 ((unsigned long)return_address(1))
+-#define CALLER_ADDR2 ((unsigned long)return_address(2))
+-#define CALLER_ADDR3 ((unsigned long)return_address(3))
+-#define CALLER_ADDR4 ((unsigned long)return_address(4))
+-#define CALLER_ADDR5 ((unsigned long)return_address(5))
+-#define CALLER_ADDR6 ((unsigned long)return_address(6))
++#define ftrace_return_address(n) return_address(n)
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
+index 72c0fafa..544ed8ef 100644
+--- a/arch/parisc/include/asm/ftrace.h
++++ b/arch/parisc/include/asm/ftrace.h
+@@ -24,15 +24,7 @@ extern void return_to_handler(void);
+ 
+ extern unsigned long return_address(unsigned int);
+ 
+-#define HAVE_ARCH_CALLER_ADDR
+-
+-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+-#define CALLER_ADDR1 return_address(1)
+-#define CALLER_ADDR2 return_address(2)
+-#define CALLER_ADDR3 return_address(3)
+-#define CALLER_ADDR4 return_address(4)
+-#define CALLER_ADDR5 return_address(5)
+-#define CALLER_ADDR6 return_address(6)
++#define ftrace_return_address(n) return_address(n)
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
+index 13e99664..e79fb6eb 100644
+--- a/arch/sh/include/asm/ftrace.h
++++ b/arch/sh/include/asm/ftrace.h
+@@ -40,15 +40,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
+ /* arch/sh/kernel/return_address.c */
+ extern void *return_address(unsigned int);
+ 
+-#define HAVE_ARCH_CALLER_ADDR
+-
+-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+-#define CALLER_ADDR1 ((unsigned long)return_address(1))
+-#define CALLER_ADDR2 ((unsigned long)return_address(2))
+-#define CALLER_ADDR3 ((unsigned long)return_address(3))
+-#define CALLER_ADDR4 ((unsigned long)return_address(4))
+-#define CALLER_ADDR5 ((unsigned long)return_address(5))
+-#define CALLER_ADDR6 ((unsigned long)return_address(6))
++#define ftrace_return_address(n) return_address(n)
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
+index 2b086a6a..c1656c85 100644
+--- a/arch/xtensa/Kconfig
++++ b/arch/xtensa/Kconfig
+@@ -17,6 +17,7 @@ config XTENSA
+ 	select CLONE_BACKWARDS
+ 	select IRQ_DOMAIN
+ 	select HAVE_OPROFILE
++	select HAVE_FUNCTION_TRACER
+ 	help
+ 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
+ 	  primarily for embedded systems.  These processors are both
+diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
+index ad8952e8..6868f2ca 100644
+--- a/arch/xtensa/boot/lib/Makefile
++++ b/arch/xtensa/boot/lib/Makefile
+@@ -7,6 +7,13 @@ zlib	:= inffast.c inflate.c inftrees.c
+ lib-y	+= $(zlib:.c=.o) zmem.o
+ 
+ ccflags-y	:= -Ilib/zlib_inflate
++ifdef CONFIG_FUNCTION_TRACER
++CFLAGS_REMOVE_inflate.o = -pg
++CFLAGS_REMOVE_zmem.o = -pg
++CFLAGS_REMOVE_inftrees.o = -pg
++CFLAGS_REMOVE_inffast.o = -pg
++endif
++
+ 
+ quiet_cmd_copy_zlib = COPY    $@
+       cmd_copy_zlib = cat $< > $@
+diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h
+index 36dc7a68..6c6d9a9f 100644
+--- a/arch/xtensa/include/asm/ftrace.h
++++ b/arch/xtensa/include/asm/ftrace.h
+@@ -12,22 +12,29 @@
+ 
+ #include <asm/processor.h>
+ 
+-#define HAVE_ARCH_CALLER_ADDR
+-#define CALLER_ADDR0 ({ unsigned long a0, a1; \
++#ifndef __ASSEMBLY__
++#define ftrace_return_address0 ({ unsigned long a0, a1; \
+ 		__asm__ __volatile__ ( \
+ 			"mov %0, a0\n" \
+ 			"mov %1, a1\n" \
+-			: "=r"(a0), "=r"(a1) : : ); \
++			: "=r"(a0), "=r"(a1)); \
+ 		MAKE_PC_FROM_RA(a0, a1); })
++
+ #ifdef CONFIG_FRAME_POINTER
+ extern unsigned long return_address(unsigned level);
+-#define CALLER_ADDR1 return_address(1)
+-#define CALLER_ADDR2 return_address(2)
+-#define CALLER_ADDR3 return_address(3)
+-#else
+-#define CALLER_ADDR1 (0)
+-#define CALLER_ADDR2 (0)
+-#define CALLER_ADDR3 (0)
++#define ftrace_return_address(n) return_address(n)
+ #endif
++#endif /* __ASSEMBLY__ */
++
++#ifdef CONFIG_FUNCTION_TRACER
++
++#define MCOUNT_ADDR ((unsigned long)(_mcount))
++#define MCOUNT_INSN_SIZE 3
++
++#ifndef __ASSEMBLY__
++extern void _mcount(void);
++#define mcount _mcount
++#endif /* __ASSEMBLY__ */
++#endif /* CONFIG_FUNCTION_TRACER */
+ 
+ #endif /* _XTENSA_FTRACE_H */
+diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
+index 1e7fc87a..f90265ec 100644
+--- a/arch/xtensa/kernel/Makefile
++++ b/arch/xtensa/kernel/Makefile
+@@ -11,6 +11,7 @@ obj-y := align.o coprocessor.o entry.o irq.o pci-dma.o platform.o process.o \
+ obj-$(CONFIG_KGDB) += xtensa-stub.o
+ obj-$(CONFIG_PCI) += pci.o
+ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
++obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
+ 
+ AFLAGS_head.o += -mtext-section-literals
+ 
+diff --git a/arch/xtensa/kernel/mcount.S b/arch/xtensa/kernel/mcount.S
+new file mode 100644
+index 00000000..0eeda2e4
+--- /dev/null
++++ b/arch/xtensa/kernel/mcount.S
+@@ -0,0 +1,50 @@
++/*
++ * arch/xtensa/kernel/mcount.S
++ *
++ * Xtensa specific mcount support
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2013 Tensilica Inc.
++ */
++
++#include <linux/linkage.h>
++#include <asm/ftrace.h>
++
++/*
++ * Entry condition:
++ *
++ *   a2:	a0 of the caller
++ */
++
++ENTRY(_mcount)
++
++	entry	a1, 16
++
++	movi	a4, ftrace_trace_function
++	l32i	a4, a4, 0
++	movi	a3, ftrace_stub
++	bne	a3, a4, 1f
++	retw
++
++1: 	xor	a7, a2, a1
++	movi	a3, 0x3fffffff
++	and	a7, a7, a3
++	xor	a7, a7, a1
++
++	xor	a6, a0, a1
++	and	a6, a6, a3
++	xor	a6, a6, a1
++	addi	a6, a6, -MCOUNT_INSN_SIZE
++	callx4	a4
++
++	retw
++
++ENDPROC(_mcount)
++
++ENTRY(ftrace_stub)
++	entry	a1, 16
++	retw
++ENDPROC(ftrace_stub)
+diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
+index 42c53c87..d8507f81 100644
+--- a/arch/xtensa/kernel/xtensa_ksyms.c
++++ b/arch/xtensa/kernel/xtensa_ksyms.c
+@@ -124,3 +124,7 @@ extern long common_exception_return;
+ extern long _spill_registers;
+ EXPORT_SYMBOL(common_exception_return);
+ EXPORT_SYMBOL(_spill_registers);
++
++#ifdef CONFIG_FUNCTION_TRACER
++EXPORT_SYMBOL(_mcount);
++#endif
+diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig
+index 75a54e1a..2dfa35ae 100644
+--- a/block/partitions/Kconfig
++++ b/block/partitions/Kconfig
+@@ -249,3 +249,11 @@ config SYSV68_PARTITION
+ 	  partition table format used by Motorola Delta machines (using
+ 	  sysv68).
+ 	  Otherwise, say N.
++
++config AMBPTB_PARTITION
++	bool "Ambarella partition table support" if PARTITION_ADVANCED
++	default y if ARCH_AMBARELLA
++	help
++	  Say Y here if you would like to be able to read the MMC/SD
++	  partition table format used by Amboot.
++	  Otherwise, say N.
+diff --git a/block/partitions/Makefile b/block/partitions/Makefile
+index 03af8eac..7ea7ecd4 100644
+--- a/block/partitions/Makefile
++++ b/block/partitions/Makefile
+@@ -18,3 +18,5 @@ obj-$(CONFIG_IBM_PARTITION) += ibm.o
+ obj-$(CONFIG_EFI_PARTITION) += efi.o
+ obj-$(CONFIG_KARMA_PARTITION) += karma.o
+ obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o
++obj-$(CONFIG_AMBPTB_PARTITION) += ambptb.o
++
+diff --git a/block/partitions/ambptb.c b/block/partitions/ambptb.c
+new file mode 100644
+index 00000000..528482a5
+--- /dev/null
++++ b/block/partitions/ambptb.c
+@@ -0,0 +1,117 @@
++/*
++ *  fs/partitions/ambptb.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include "check.h"
++#include "ambptb.h"
++#include <plat/ptb.h>
++#include <linux/of.h>
++
++//#define ambptb_prt
++
++#ifdef ambptb_prt
++#define ambptb_prt printk
++#else
++#define ambptb_prt(format, arg...) do {} while (0)
++#endif
++
++int ambptb_partition(struct parsed_partitions *state)
++{
++	int i, val, slot = 1;
++	unsigned char *data;
++	Sector sect;
++	u32 sect_size, sect_offset, sect_address, ptb_address;
++	flpart_meta_t *ptb_meta;
++	char ptb_tmp[1 + BDEVNAME_SIZE + 1];
++	int result = 0;
++	struct device_node * np;
++
++	sect_size = bdev_logical_block_size(state->bdev);
++	sect_offset = (sizeof(ptb_header_t) + sizeof(flpart_table_t)) % sect_size;
++
++	np = of_find_node_with_property(NULL, "amb,ptb_address");
++	if(!np)
++		return -1;
++
++	val = of_property_read_u32(np, "amb,ptb_address", &ptb_address);
++	if(val < 0)
++		return -1;
++
++	sect_address = (ptb_address * sect_size + sizeof(ptb_header_t) + sizeof(flpart_table_t)) / sect_size;
++	data = read_part_sector(state, sect_address, &sect);
++	if (!data) {
++		result = -1;
++		goto ambptb_partition_exit;
++	}
++
++	ptb_meta = (flpart_meta_t *)(data + sect_offset);
++	ambptb_prt("%s: magic[0x%08X]\n", __func__, ptb_meta->magic);
++	if (ptb_meta->magic == PTB_META_MAGIC3) {
++		for (i = 0; i < PART_MAX; i++) {
++			if (slot >= state->limit)
++				break;
++
++			if (((ptb_meta->part_info[i].dev & PART_DEV_EMMC) ==
++				PART_DEV_EMMC) &&
++				(ptb_meta->part_info[i].nblk)) {
++				state->parts[slot].from =
++					ptb_meta->part_info[i].sblk;
++				state->parts[slot].size =
++					ptb_meta->part_info[i].nblk;
++				snprintf(ptb_tmp, sizeof(ptb_tmp), " %s",
++					ptb_meta->part_info[i].name);
++				strlcat(state->pp_buf, ptb_tmp, PAGE_SIZE);
++				ambptb_prt("%s: %s [p%d]\n", __func__,
++					ptb_meta->part_info[i].name, slot);
++				slot++;
++			}
++		}
++		strlcat(state->pp_buf, "\n", PAGE_SIZE);
++		result = 1;
++	} else if ((ptb_meta->magic == PTB_META_MAGIC) ||
++		(ptb_meta->magic == PTB_META_MAGIC2)) {
++		for (i = 0; i < PART_MAX; i++) {
++			if (slot >= state->limit)
++				break;
++			if ((ptb_meta->part_info[i].dev == BOOT_DEV_SM) &&
++				(ptb_meta->part_info[i].nblk)) {
++				state->parts[slot].from =
++					ptb_meta->part_info[i].sblk;
++				state->parts[slot].size =
++					ptb_meta->part_info[i].nblk;
++				snprintf(ptb_tmp, sizeof(ptb_tmp), " %s",
++					ptb_meta->part_info[i].name);
++				strlcat(state->pp_buf, ptb_tmp, PAGE_SIZE);
++				ambptb_prt("%s: %s [p%d]\n", __func__,
++					ptb_meta->part_info[i].name, slot);
++				slot++;
++			}
++		}
++		strlcat(state->pp_buf, "\n", PAGE_SIZE);
++		result = 1;
++	}
++	put_dev_sector(sect);
++
++ambptb_partition_exit:
++	return result;
++}
++
+diff --git a/block/partitions/ambptb.h b/block/partitions/ambptb.h
+new file mode 100644
+index 00000000..90d19577
+--- /dev/null
++++ b/block/partitions/ambptb.h
+@@ -0,0 +1,25 @@
++/*
++ *  fs/partitions/ambptb.h
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2010, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++int ambptb_partition(struct parsed_partitions *state);
++
+diff --git a/block/partitions/check.c b/block/partitions/check.c
+index 19ba207e..1a13b19c 100644
+--- a/block/partitions/check.c
++++ b/block/partitions/check.c
+@@ -34,6 +34,7 @@
+ #include "efi.h"
+ #include "karma.h"
+ #include "sysv68.h"
++#include "ambptb.h"
+ 
+ int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
+ 
+@@ -103,6 +104,9 @@ static int (*check_part[])(struct parsed_partitions *) = {
+ #endif
+ #ifdef CONFIG_SYSV68_PARTITION
+ 	sysv68_partition,
++#endif
++#ifdef CONFIG_AMBPTB_PARTITION
++	ambptb_partition,
+ #endif
+ 	NULL
+ };
+diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
+index a79e7e9a..a49a9be4 100644
+--- a/crypto/blkcipher.c
++++ b/crypto/blkcipher.c
+@@ -34,6 +34,8 @@ enum {
+ 	BLKCIPHER_WALK_SLOW = 1 << 1,
+ 	BLKCIPHER_WALK_COPY = 1 << 2,
+ 	BLKCIPHER_WALK_DIFF = 1 << 3,
++	AMBA_CIPHER_COPY = 1 << 4,
++	// add for amba crypto interrupt mode -- cddiao <cddiao@ambarella.com>
+ };
+ 
+ static int blkcipher_walk_next(struct blkcipher_desc *desc,
+diff --git a/crypto/des_generic.c b/crypto/des_generic.c
+index 3ec60713..1bdfab31 100644
+--- a/crypto/des_generic.c
++++ b/crypto/des_generic.c
+@@ -367,7 +367,7 @@ static const u32 pc2[1024] = {
+ 
+ /* S-box lookup tables */
+ 
+-static const u32 S1[64] = {
++static const u32 S_1[64] = {
+ 	0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 	0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 	0x00000400, 0x01010400, 0x01010404, 0x00000400,
+@@ -386,7 +386,7 @@ static const u32 S1[64] = {
+ 	0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+ 
+-static const u32 S2[64] = {
++static const u32 S_2[64] = {
+ 	0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 	0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 	0x80000020, 0x80108020, 0x80108000, 0x80000000,
+@@ -405,7 +405,7 @@ static const u32 S2[64] = {
+ 	0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+ 
+-static const u32 S3[64] = {
++static const u32 S_3[64] = {
+ 	0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 	0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 	0x00020008, 0x08000008, 0x08000008, 0x00020000,
+@@ -424,7 +424,7 @@ static const u32 S3[64] = {
+ 	0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+ 
+-static const u32 S4[64] = {
++static const u32 S_4[64] = {
+ 	0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 	0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 	0x00000000, 0x00802000, 0x00802000, 0x00802081,
+@@ -443,7 +443,7 @@ static const u32 S4[64] = {
+ 	0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+ 
+-static const u32 S5[64] = {
++static const u32 S_5[64] = {
+ 	0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 	0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 	0x40080100, 0x00080000, 0x02000100, 0x40080100,
+@@ -462,7 +462,7 @@ static const u32 S5[64] = {
+ 	0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+ 
+-static const u32 S6[64] = {
++static const u32 S_6[64] = {
+ 	0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 	0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 	0x20004000, 0x00404010, 0x00400000, 0x20000010,
+@@ -481,7 +481,7 @@ static const u32 S6[64] = {
+ 	0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+ 
+-static const u32 S7[64] = {
++static const u32 S_7[64] = {
+ 	0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 	0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 	0x04200802, 0x00200000, 0x00000000, 0x04000002,
+@@ -500,7 +500,7 @@ static const u32 S7[64] = {
+ 	0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+ 
+-static const u32 S8[64] = {
++static const u32 S_8[64] = {
+ 	0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 	0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 	0x00040040, 0x10040000, 0x10041040, 0x00041000,
+@@ -591,14 +591,14 @@ static const u32 S8[64] = {
+ 	B = K[0];			A = K[1];	K += d;	\
+ 	B ^= R;				A ^= R;			\
+ 	B &= 0x3f3f3f3f;		ROR(A, 4);		\
+-	L ^= S8[0xff & B];		A &= 0x3f3f3f3f;	\
+-	L ^= S6[0xff & (B >> 8)];	B >>= 16;		\
+-	L ^= S7[0xff & A];					\
+-	L ^= S5[0xff & (A >> 8)];	A >>= 16;		\
+-	L ^= S4[0xff & B];					\
+-	L ^= S2[0xff & (B >> 8)];				\
+-	L ^= S3[0xff & A];					\
+-	L ^= S1[0xff & (A >> 8)];
++	L ^= S_8[0xff & B];		A &= 0x3f3f3f3f;	\
++	L ^= S_6[0xff & (B >> 8)];	B >>= 16;		\
++	L ^= S_7[0xff & A];					\
++	L ^= S_5[0xff & (A >> 8)];	A >>= 16;		\
++	L ^= S_4[0xff & B];					\
++	L ^= S_2[0xff & (B >> 8)];				\
++	L ^= S_3[0xff & A];					\
++	L ^= S_1[0xff & (A >> 8)];
+ 
+ /*
+  * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index 10b14d45..dea026c9 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -36,6 +36,14 @@
+ #define _AHCI_H
+ 
+ #include <linux/clk.h>
++
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++#undef writel
++#undef readl
++#define writel(v, p)		amba_writel(p, v)
++#define readl(p)		amba_readl(p)
++#endif
++
+ #include <linux/libata.h>
+ 
+ /* Enclosure Management Control */
+diff --git a/drivers/base/Makefile b/drivers/base/Makefile
+index 4e22ce3e..9b10139b 100644
+--- a/drivers/base/Makefile
++++ b/drivers/base/Makefile
+@@ -1,7 +1,7 @@
+ # Makefile for the Linux device tree
+ 
+ obj-y			:= core.o bus.o dd.o syscore.o \
+-			   driver.o class.o platform.o \
++			   driver.o class.o platform.o ambbus.o ambpriv.o \
+ 			   cpu.o firmware.o init.o map.o devres.o \
+ 			   attribute_container.o transport_class.o \
+ 			   topology.o
+diff --git a/drivers/base/ambbus.c b/drivers/base/ambbus.c
+new file mode 100644
+index 00000000..6866d986
+--- /dev/null
++++ b/drivers/base/ambbus.c
+@@ -0,0 +1,180 @@
++/*
++ * AMB bus.
++ */
++
++#include <linux/device.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/dma-mapping.h>
++#include <linux/ambbus.h>
++
++static struct device amb_bus = {
++	.init_name	= "ambbus"
++};
++
++struct amb_dev {
++	struct device dev;
++	struct device *next;
++};
++
++#define to_amb_dev(x) container_of((x), struct amb_dev, dev)
++
++static int amb_bus_match(struct device *dev, struct device_driver *driver)
++{
++	struct amb_driver *amb_driver = to_amb_driver(driver);
++
++	if (dev->platform_data == amb_driver) {
++		if (!amb_driver->match || amb_driver->match(dev))
++			return 1;
++		dev->platform_data = NULL;
++	}
++	return 0;
++}
++
++static int amb_bus_probe(struct device *dev)
++{
++	struct amb_driver *amb_driver = dev->platform_data;
++
++	if (amb_driver->probe)
++		return amb_driver->probe(dev);
++
++	return 0;
++}
++
++static int amb_bus_remove(struct device *dev)
++{
++	struct amb_driver *amb_driver = dev->platform_data;
++
++	if (amb_driver->remove)
++		return amb_driver->remove(dev);
++
++	return 0;
++}
++
++static void amb_bus_shutdown(struct device *dev)
++{
++	struct amb_driver *amb_driver = dev->platform_data;
++
++	if (amb_driver->shutdown)
++		amb_driver->shutdown(dev);
++}
++
++static int amb_bus_suspend(struct device *dev, pm_message_t state)
++{
++	struct amb_driver *amb_driver = dev->platform_data;
++
++	if (amb_driver->suspend)
++		return amb_driver->suspend(dev, state);
++
++	return 0;
++}
++
++static int amb_bus_resume(struct device *dev)
++{
++	struct amb_driver *amb_driver = dev->platform_data;
++
++	if (amb_driver->resume)
++		return amb_driver->resume(dev);
++
++	return 0;
++}
++
++static struct bus_type amb_bus_type = {
++	.name		= "ambbus",
++	.match		= amb_bus_match,
++	.probe		= amb_bus_probe,
++	.remove		= amb_bus_remove,
++	.shutdown	= amb_bus_shutdown,
++	.suspend	= amb_bus_suspend,
++	.resume		= amb_bus_resume
++};
++
++static void amb_dev_release(struct device *dev)
++{
++	kfree(to_amb_dev(dev));
++}
++
++void amb_unregister_driver(struct amb_driver *amb_driver)
++{
++	struct device *dev = amb_driver->devices;
++
++	while (dev) {
++		struct device *tmp = to_amb_dev(dev)->next;
++		device_unregister(dev);
++		dev = tmp;
++	}
++	driver_unregister(&amb_driver->driver);
++}
++EXPORT_SYMBOL(amb_unregister_driver);
++
++int amb_register_driver(struct amb_driver *amb_driver)
++{
++	int error;
++	unsigned int id;
++
++	amb_driver->driver.bus	= &amb_bus_type;
++	amb_driver->devices	= NULL;
++
++	error = driver_register(&amb_driver->driver);
++	if (error)
++		return error;
++
++	for (id = 0; id < 1; id++) {
++		struct amb_dev *amb_dev;
++
++		amb_dev = kzalloc(sizeof *amb_dev, GFP_KERNEL);
++		if (!amb_dev) {
++			error = -ENOMEM;
++			break;
++		}
++
++		amb_dev->dev.parent	= &amb_bus;
++		amb_dev->dev.bus	= &amb_bus_type;
++
++		dev_set_name(&amb_dev->dev, "%s",
++			     amb_driver->driver.name);
++		amb_dev->dev.platform_data	= amb_driver;
++		amb_dev->dev.release		= amb_dev_release;
++
++		amb_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24);
++		amb_dev->dev.dma_mask = &amb_dev->dev.coherent_dma_mask;
++
++		error = device_register(&amb_dev->dev);
++		if (error) {
++			put_device(&amb_dev->dev);
++			break;
++		}
++
++		if (amb_dev->dev.platform_data) {
++			amb_dev->next = amb_driver->devices;
++			amb_driver->devices = &amb_dev->dev;
++		} else
++			device_unregister(&amb_dev->dev);
++	}
++
++	if (!error && !amb_driver->devices)
++		error = -ENODEV;
++
++	if (error)
++		amb_unregister_driver(amb_driver);
++
++	return error;
++}
++EXPORT_SYMBOL(amb_register_driver);
++
++static int __init amb_bus_init(void)
++{
++	int error;
++
++	error = bus_register(&amb_bus_type);
++	if (!error) {
++		error = device_register(&amb_bus);
++		if (error)
++			bus_unregister(&amb_bus_type);
++	}
++	return error;
++}
++
++device_initcall(amb_bus_init);
+diff --git a/drivers/base/ambpriv.c b/drivers/base/ambpriv.c
+new file mode 100644
+index 00000000..135b6312
+--- /dev/null
++++ b/drivers/base/ambpriv.c
+@@ -0,0 +1,796 @@
++/*
++ * ambpriv.c
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/pm_runtime.h>
++#include <linux/ambpriv_device.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/of_irq.h>
++#include <linux/of_platform.h>
++#include "base.h"
++
++#define to_ambpriv_driver(drv)	(container_of((drv), struct ambpriv_driver, driver))
++
++struct device ambpriv_bus = {
++	.init_name	= "ambpriv",
++};
++
++static int of_ambpriv_match_device(struct device *dev, void *match)
++{
++	return !!of_match_device(match, dev);
++}
++
++struct ambpriv_device *of_find_ambpriv_device_by_match(struct of_device_id *match)
++{
++	struct device *dev;
++
++	dev = bus_find_device(&ambpriv_bus_type, NULL, match, of_ambpriv_match_device);
++	return dev ? to_ambpriv_device(dev) : NULL;
++}
++EXPORT_SYMBOL(of_find_ambpriv_device_by_match);
++
++static int of_ambpriv_node_device(struct device *dev, void *data)
++{
++	return dev->of_node == data;
++}
++
++struct ambpriv_device *of_find_ambpriv_device_by_node(struct device_node *np)
++{
++	struct device *dev;
++
++	dev = bus_find_device(&ambpriv_bus_type, NULL, np, of_ambpriv_node_device);
++	return dev ? to_ambpriv_device(dev) : NULL;
++}
++EXPORT_SYMBOL(of_find_ambpriv_device_by_node);
++
++int ambpriv_get_irq(struct ambpriv_device *dev, unsigned int num)
++{
++	struct resource *r = NULL;
++	int i;
++
++	if (dev == NULL)
++		return -ENODEV;
++
++	for (i = 0; i < dev->num_resources; i++) {
++		r = &dev->resource[i];
++		if ((resource_type(r) == IORESOURCE_IRQ) && num-- == 0)
++			break;
++	}
++
++	if (i == dev->num_resources)
++		return -ENXIO;
++
++	if (r && r->flags & IORESOURCE_BITS)
++		irqd_set_trigger_type(irq_get_irq_data(r->start),
++				      r->flags & IORESOURCE_BITS);
++
++	return r->start;
++}
++EXPORT_SYMBOL(ambpriv_get_irq);
++
++int ambpriv_get_irq_by_name(struct ambpriv_device *dev, const char *name)
++{
++	struct resource *r = NULL;
++	int i;
++
++	if (dev == NULL)
++		return -ENODEV;
++
++	for (i = 0; i < dev->num_resources; i++) {
++		r = &dev->resource[i];
++
++		if (unlikely(!r->name))
++			continue;
++
++		if ((resource_type(r) == IORESOURCE_IRQ) && !strcmp(r->name, name))
++			break;
++	}
++
++	if (i == dev->num_resources)
++		return -ENXIO;
++
++	return r->start;
++}
++EXPORT_SYMBOL(ambpriv_get_irq_by_name);
++
++static struct ambpriv_device *of_ambpriv_device_alloc(struct device_node *np,
++		struct device *parent)
++{
++	struct ambpriv_device *dev;
++	const __be32 *reg_prop;
++	struct resource *res;
++	int psize, i, num_reg = 0, num_irq;
++
++	dev = ambpriv_device_alloc("", -1);
++	if (!dev)
++		return NULL;
++
++	reg_prop = of_get_property(np, "reg", &psize);
++	if (reg_prop)
++		num_reg = psize / sizeof(u32) / 2;
++
++
++	num_irq = of_irq_count(np);
++
++	if (num_reg || num_irq) {
++		res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
++		if (!res) {
++			ambpriv_device_put(dev);
++			return NULL;
++		}
++
++		dev->resource = res;
++		dev->num_resources = num_reg + num_irq;
++
++		for (i = 0; i < num_reg; i++, res++, reg_prop += 2) {
++			res->start = be32_to_cpup(reg_prop);
++			res->end = res->start + be32_to_cpup(reg_prop + 1) - 1;
++			res->flags = IORESOURCE_MEM;
++		}
++
++		of_irq_to_resource_table(np, res, num_irq);
++	}
++
++	dev->dev.of_node = of_node_get(np);
++	dev->dev.parent = parent ? : &ambpriv_bus;
++	of_device_make_bus_id(&dev->dev);
++	dev->name = dev_name(&dev->dev);
++
++	return dev;
++}
++
++static struct ambpriv_device *of_ambpriv_device_create_pdata(
++		struct device_node *np, struct device *parent)
++{
++	struct ambpriv_device *dev;
++
++	dev = of_ambpriv_device_alloc(np, parent);
++	if (!dev)
++		return NULL;
++
++	if (ambpriv_device_add(dev) < 0) {
++		ambpriv_device_put(dev);
++		return NULL;
++	}
++
++	return dev;
++}
++
++static int of_ambpriv_bus_create(struct device_node *bus,
++		const struct of_device_id *matches, struct device *parent)
++{
++	struct device_node *child;
++	struct ambpriv_device *dev;
++	int rc = 0;
++
++	/* Make sure it has a compatible property */
++	if (!of_get_property(bus, "compatible", NULL))
++		return 0;
++
++	dev = of_ambpriv_device_create_pdata(bus, parent);
++	if (!dev || !of_match_node(matches, bus))
++		return 0;
++
++	for_each_child_of_node(bus, child) {
++		rc = of_ambpriv_bus_create(child, matches, &dev->dev);
++		if (rc) {
++			of_node_put(child);
++			break;
++		}
++	}
++
++	return rc;
++}
++
++static const struct of_device_id of_ambpriv_bus_match_table[] = {
++	{ .compatible = "ambpriv-bus", },
++	{} /* Empty terminated list */
++};
++
++static int __init of_ambpriv_populate(void)
++{
++	struct device_node *root, *child;
++	int rval;
++
++	root = of_find_node_by_path("/iav");
++	if (!root)
++		return -EINVAL;
++
++	for_each_child_of_node(root, child) {
++		rval = of_ambpriv_bus_create(child, of_ambpriv_bus_match_table, NULL);
++		if (rval) {
++			of_node_put(child);
++			break;
++		}
++	}
++
++	of_node_put(root);
++
++	return 0;
++}
++late_initcall(of_ambpriv_populate);
++
++
++int ambpriv_add_devices(struct ambpriv_device **devs, int num)
++{
++	int i, ret = 0;
++
++	for (i = 0; i < num; i++) {
++		ret = ambpriv_device_register(devs[i]);
++		if (ret) {
++			while (--i >= 0)
++				ambpriv_device_unregister(devs[i]);
++			break;
++		}
++	}
++
++	return ret;
++}
++EXPORT_SYMBOL(ambpriv_add_devices);
++
++struct ambpriv_object {
++	struct ambpriv_device ambdev;
++	char name[1];
++};
++
++void ambpriv_device_put(struct ambpriv_device *ambdev)
++{
++	if (ambdev)
++		put_device(&ambdev->dev);
++}
++EXPORT_SYMBOL(ambpriv_device_put);
++
++static void ambpriv_device_release(struct device *dev)
++{
++	struct ambpriv_object *pa;
++
++	pa = container_of(dev, struct ambpriv_object, ambdev.dev);
++	kfree(pa->ambdev.dev.platform_data);
++	kfree(pa->ambdev.resource);
++	kfree(pa);
++}
++
++struct ambpriv_device *ambpriv_device_alloc(const char *name, int id)
++{
++	struct ambpriv_object *pa;
++
++	pa = kzalloc(sizeof(struct ambpriv_object) + strlen(name), GFP_KERNEL);
++	if (pa) {
++		strcpy(pa->name, name);
++		pa->ambdev.name = pa->name;
++		pa->ambdev.id = id;
++		device_initialize(&pa->ambdev.dev);
++		pa->ambdev.dev.release = ambpriv_device_release;
++	}
++
++	return pa ? &pa->ambdev : NULL;
++}
++EXPORT_SYMBOL(ambpriv_device_alloc);
++
++int ambpriv_device_add_resources(struct ambpriv_device *ambdev,
++				  const struct resource *res, unsigned int num)
++{
++	struct resource *r;
++
++	if (!res)
++		return 0;
++
++	r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
++	if (r) {
++		ambdev->resource = r;
++		ambdev->num_resources = num;
++		return 0;
++	}
++	return -ENOMEM;
++}
++EXPORT_SYMBOL(ambpriv_device_add_resources);
++
++int ambpriv_device_add_data(struct ambpriv_device *ambdev, const void *data,
++			     size_t size)
++{
++	void *d;
++
++	if (!data)
++		return 0;
++
++	d = kmemdup(data, size, GFP_KERNEL);
++	if (d) {
++		ambdev->dev.platform_data = d;
++		return 0;
++	}
++	return -ENOMEM;
++}
++EXPORT_SYMBOL(ambpriv_device_add_data);
++
++int ambpriv_device_add(struct ambpriv_device *ambdev)
++{
++	int i, ret = 0;
++
++	if (!ambdev)
++		return -EINVAL;
++
++	if (!ambdev->dev.parent)
++		ambdev->dev.parent = &ambpriv_bus;
++
++	ambdev->dev.bus = &ambpriv_bus_type;
++
++	if (ambdev->id != -1)
++		dev_set_name(&ambdev->dev, "%s.%d", ambdev->name,  ambdev->id);
++	else
++		dev_set_name(&ambdev->dev, "%s", ambdev->name);
++
++	for (i = 0; i < ambdev->num_resources; i++) {
++		struct resource *p, *r = &ambdev->resource[i];
++
++		if (r->name == NULL)
++			r->name = dev_name(&ambdev->dev);
++
++		p = r->parent;
++		if (!p) {
++			if (resource_type(r) == IORESOURCE_MEM)
++				p = &iomem_resource;
++			else if (resource_type(r) == IORESOURCE_IO)
++				p = &ioport_resource;
++		}
++
++		if (p && insert_resource(p, r)) {
++			printk(KERN_ERR
++			       "%s: failed to claim resource %d\n",
++			       dev_name(&ambdev->dev), i);
++			ret = -EBUSY;
++			goto failed;
++		}
++	}
++
++	pr_debug("Registering ambpriv device '%s'. Parent at %s\n",
++		 dev_name(&ambdev->dev), dev_name(ambdev->dev.parent));
++
++	ret = device_add(&ambdev->dev);
++	if (ret == 0)
++		return ret;
++
++ failed:
++	while (--i >= 0) {
++		struct resource *r = &ambdev->resource[i];
++		unsigned long type = resource_type(r);
++
++		if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
++			release_resource(r);
++	}
++
++	return ret;
++}
++EXPORT_SYMBOL(ambpriv_device_add);
++
++void ambpriv_device_del(struct ambpriv_device *ambdev)
++{
++	int i;
++
++	if (ambdev) {
++		device_del(&ambdev->dev);
++
++		for (i = 0; i < ambdev->num_resources; i++) {
++			struct resource *r = &ambdev->resource[i];
++			unsigned long type = resource_type(r);
++
++			if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
++				release_resource(r);
++		}
++	}
++}
++EXPORT_SYMBOL(ambpriv_device_del);
++
++int ambpriv_device_register(struct ambpriv_device *ambdev)
++{
++	device_initialize(&ambdev->dev);
++	return ambpriv_device_add(ambdev);
++}
++EXPORT_SYMBOL(ambpriv_device_register);
++
++void ambpriv_device_unregister(struct ambpriv_device *ambdev)
++{
++	ambpriv_device_del(ambdev);
++	ambpriv_device_put(ambdev);
++}
++EXPORT_SYMBOL(ambpriv_device_unregister);
++
++static int ambpriv_drv_probe(struct device *_dev)
++{
++	struct ambpriv_driver *drv = to_ambpriv_driver(_dev->driver);
++	struct ambpriv_device *dev = to_ambpriv_device(_dev);
++
++	return drv->probe(dev);
++}
++
++static int ambpriv_drv_remove(struct device *_dev)
++{
++	struct ambpriv_driver *drv = to_ambpriv_driver(_dev->driver);
++	struct ambpriv_device *dev = to_ambpriv_device(_dev);
++
++	return drv->remove(dev);
++}
++
++static void ambpriv_drv_shutdown(struct device *_dev)
++{
++	struct ambpriv_driver *drv = to_ambpriv_driver(_dev->driver);
++	struct ambpriv_device *dev = to_ambpriv_device(_dev);
++
++	drv->shutdown(dev);
++}
++
++int ambpriv_driver_register(struct ambpriv_driver *drv)
++{
++	drv->driver.bus = &ambpriv_bus_type;
++	if (drv->probe)
++		drv->driver.probe = ambpriv_drv_probe;
++	if (drv->remove)
++		drv->driver.remove = ambpriv_drv_remove;
++	if (drv->shutdown)
++		drv->driver.shutdown = ambpriv_drv_shutdown;
++
++	return driver_register(&drv->driver);
++}
++EXPORT_SYMBOL(ambpriv_driver_register);
++
++void ambpriv_driver_unregister(struct ambpriv_driver *drv)
++{
++	driver_unregister(&drv->driver);
++}
++EXPORT_SYMBOL(ambpriv_driver_unregister);
++
++struct ambpriv_device * __init_or_module ambpriv_create_bundle(
++			struct ambpriv_driver *driver,
++			struct resource *res, unsigned int n_res,
++			const void *data, size_t size)
++{
++	struct ambpriv_device *ambdev;
++	int error;
++
++	ambdev = of_find_ambpriv_device_by_match(
++			(struct of_device_id *)driver->driver.of_match_table);
++	if (ambdev)
++		goto register_drv;
++
++	ambdev = ambpriv_device_alloc(driver->driver.name, -1);
++	if (!ambdev) {
++		error = -ENOMEM;
++		goto err_out;
++	}
++
++	error = ambpriv_device_add_resources(ambdev, res, n_res);
++	if (error)
++		goto err_pdev_put;
++
++	error = ambpriv_device_add_data(ambdev, data, size);
++	if (error)
++		goto err_pdev_put;
++
++	error = ambpriv_device_add(ambdev);
++	if (error)
++		goto err_pdev_put;
++
++register_drv:
++	error = ambpriv_driver_register(driver);
++	if (error)
++		goto err_pdev_del;
++
++	return ambdev;
++
++err_pdev_del:
++	ambpriv_device_del(ambdev);
++err_pdev_put:
++	ambpriv_device_put(ambdev);
++err_out:
++	return ERR_PTR(error);
++}
++EXPORT_SYMBOL(ambpriv_create_bundle);
++
++static int ambpriv_match(struct device *dev, struct device_driver *drv)
++{
++	struct ambpriv_device *ambdev = to_ambpriv_device(dev);
++
++	if (of_driver_match_device(dev, drv))
++		return 1;
++
++	return (strcmp(ambdev->name, drv->name) == 0);
++}
++
++#ifdef CONFIG_PM_SLEEP
++
++static int ambpriv_pm_prepare(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (drv && drv->pm && drv->pm->prepare)
++		ret = drv->pm->prepare(dev);
++
++	return ret;
++}
++
++static void ambpriv_pm_complete(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++
++	if (drv && drv->pm && drv->pm->complete)
++		drv->pm->complete(dev);
++}
++
++#else /* !CONFIG_PM_SLEEP */
++
++#define ambpriv_pm_prepare		NULL
++#define ambpriv_pm_complete		NULL
++
++#endif /* !CONFIG_PM_SLEEP */
++
++#ifdef CONFIG_SUSPEND
++
++int __weak ambpriv_pm_suspend(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->suspend)
++		ret = drv->pm->suspend(dev);
++
++	return ret;
++}
++
++int __weak ambpriv_pm_suspend_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->suspend_noirq)
++		ret = drv->pm->suspend_noirq(dev);
++
++	return ret;
++}
++
++int __weak ambpriv_pm_resume(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->resume)
++		ret = drv->pm->resume(dev);
++
++	return ret;
++}
++
++int __weak ambpriv_pm_resume_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->resume_noirq)
++		ret = drv->pm->resume_noirq(dev);
++
++	return ret;
++}
++
++#else /* !CONFIG_SUSPEND */
++
++#define ambpriv_pm_suspend		NULL
++#define ambpriv_pm_resume		NULL
++#define ambpriv_pm_suspend_noirq	NULL
++#define ambpriv_pm_resume_noirq	NULL
++
++#endif /* !CONFIG_SUSPEND */
++
++#ifdef CONFIG_HIBERNATION
++
++static int ambpriv_pm_freeze(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->freeze)
++		ret = drv->pm->freeze(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_freeze_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->freeze_noirq)
++		ret = drv->pm->freeze_noirq(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_thaw(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->thaw)
++		ret = drv->pm->thaw(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_thaw_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->thaw_noirq)
++		ret = drv->pm->thaw_noirq(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_poweroff(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->poweroff)
++		ret = drv->pm->poweroff(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_poweroff_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->poweroff_noirq)
++		ret = drv->pm->poweroff_noirq(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_restore(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->restore)
++		ret = drv->pm->restore(dev);
++
++	return ret;
++}
++
++static int ambpriv_pm_restore_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm && drv->pm->restore_noirq)
++		ret = drv->pm->restore_noirq(dev);
++
++	return ret;
++}
++
++#else /* !CONFIG_HIBERNATION */
++
++#define ambpriv_pm_freeze		NULL
++#define ambpriv_pm_thaw		NULL
++#define ambpriv_pm_poweroff		NULL
++#define ambpriv_pm_restore		NULL
++#define ambpriv_pm_freeze_noirq	NULL
++#define ambpriv_pm_thaw_noirq		NULL
++#define ambpriv_pm_poweroff_noirq	NULL
++#define ambpriv_pm_restore_noirq	NULL
++
++#endif /* !CONFIG_HIBERNATION */
++
++#ifdef CONFIG_PM_RUNTIME
++
++int __weak ambpriv_pm_runtime_suspend(struct device *dev)
++{
++	return pm_generic_runtime_suspend(dev);
++};
++
++int __weak ambpriv_pm_runtime_resume(struct device *dev)
++{
++	return pm_generic_runtime_resume(dev);
++};
++
++int __weak ambpriv_pm_runtime_idle(struct device *dev)
++{
++	return pm_generic_runtime_idle(dev);
++};
++
++#else /* !CONFIG_PM_RUNTIME */
++
++#define ambpriv_pm_runtime_suspend NULL
++#define ambpriv_pm_runtime_resume NULL
++#define ambpriv_pm_runtime_idle NULL
++
++#endif /* !CONFIG_PM_RUNTIME */
++
++static const struct dev_pm_ops ambpriv_dev_pm_ops = {
++	.prepare = ambpriv_pm_prepare,
++	.complete = ambpriv_pm_complete,
++	.suspend = ambpriv_pm_suspend,
++	.resume = ambpriv_pm_resume,
++	.freeze = ambpriv_pm_freeze,
++	.thaw = ambpriv_pm_thaw,
++	.poweroff = ambpriv_pm_poweroff,
++	.restore = ambpriv_pm_restore,
++	.suspend_noirq = ambpriv_pm_suspend_noirq,
++	.resume_noirq = ambpriv_pm_resume_noirq,
++	.freeze_noirq = ambpriv_pm_freeze_noirq,
++	.thaw_noirq = ambpriv_pm_thaw_noirq,
++	.poweroff_noirq = ambpriv_pm_poweroff_noirq,
++	.restore_noirq = ambpriv_pm_restore_noirq,
++	.runtime_suspend = ambpriv_pm_runtime_suspend,
++	.runtime_resume = ambpriv_pm_runtime_resume,
++	.runtime_idle = ambpriv_pm_runtime_idle,
++};
++
++struct bus_type ambpriv_bus_type = {
++	.name		= "ambpriv",
++	.match		= ambpriv_match,
++	.pm		= &ambpriv_dev_pm_ops,
++};
++EXPORT_SYMBOL(ambpriv_bus_type);
++
++int __init ambpriv_bus_init(void)
++{
++	int error;
++
++	error = device_register(&ambpriv_bus);
++	if (error)
++		return error;
++	error = bus_register(&ambpriv_bus_type);
++	if (error)
++		device_unregister(&ambpriv_bus);
++	return error;
++}
++
++core_initcall(ambpriv_bus_init);
++
+diff --git a/drivers/char/.gitignore b/drivers/char/.gitignore
+new file mode 100644
+index 00000000..7bcea53c
+--- /dev/null
++++ b/drivers/char/.gitignore
+@@ -0,0 +1,2 @@
++consolemap_deftbl.c
++defkeymap.c
+diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
+index 6e57543f..928233b3 100644
+--- a/drivers/cpufreq/Kconfig.arm
++++ b/drivers/cpufreq/Kconfig.arm
+@@ -150,3 +150,12 @@ config ARM_SPEAR_CPUFREQ
+ 	default y
+ 	help
+ 	  This adds the CPUFreq driver support for SPEAr SOCs.
++
++config ARM_AMBARALLA_CPUFREQ
++	bool "Ambarella CPUFreq Driver"
++	depends on ARCH_AMBARELLA
++	default y
++	help
++	  This adds the CPUFreq driver for Ambarella SoC.
++	  If in doubt, say N.
++
+diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
+index 3b95322f..8cefc80d 100644
+--- a/drivers/cpufreq/Makefile
++++ b/drivers/cpufreq/Makefile
+@@ -3,7 +3,7 @@ obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+ # CPUfreq stats
+ obj-$(CONFIG_CPU_FREQ_STAT)             += cpufreq_stats.o
+ 
+-# CPUfreq governors 
++# CPUfreq governors
+ obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
+ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)	+= cpufreq_powersave.o
+ obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= cpufreq_userspace.o
+@@ -50,6 +50,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= arm_big_little.o
+ # LITTLE drivers, so that it is probed last.
+ obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
+ 
++obj-$(CONFIG_ARM_AMBARALLA_CPUFREQ)		+= ambarella-cpufreq.o
+ obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
+ obj-$(CONFIG_UX500_SOC_DB8500)		+= dbx500-cpufreq.o
+ obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)	+= exynos-cpufreq.o
+diff --git a/drivers/cpufreq/ambarella-cpufreq.c b/drivers/cpufreq/ambarella-cpufreq.c
+new file mode 100644
+index 00000000..5831980a
+--- /dev/null
++++ b/drivers/cpufreq/ambarella-cpufreq.c
+@@ -0,0 +1,285 @@
++/*
++ * drivers/cpufreq/ambarella-cpufreq.c
++ *
++ * CPU Frequency Scaling for Ambarella platform
++ *
++ * Copyright (C) 2015 ST Ambarella Shanghai Co., Ltd.
++ * XianqingZheng <xqzheng@ambarella.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++#include <linux/clk.h>
++#include <linux/cpufreq.h>
++#include <linux/err.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <plat/event.h>
++#include <linux/io.h>
++#include <plat/rct.h>
++
++//#define amba_cpufreq_debug	//used at debug mode
++
++#ifdef amba_cpufreq_debug
++#define amba_cpufreq_prt printk
++#else
++#define amba_cpufreq_prt(format, arg...) do {} while (0)
++#endif
++
++/* Ambarella CPUFreq driver data structure */
++static struct {
++	struct clk *core_clk;
++	struct clk *cortex_clk;
++	unsigned int transition_latency;
++	struct cpufreq_frequency_table *cortex_clktbl;
++	struct cpufreq_frequency_table *core_clktbl;
++} amba_cpufreq;
++
++static int amba_cpufreq_verify(struct cpufreq_policy *policy)
++{
++	return cpufreq_frequency_table_verify(policy, amba_cpufreq.cortex_clktbl);
++}
++
++static unsigned int amba_cpufreq_get(unsigned int cpu)
++{
++	return clk_get_rate(amba_cpufreq.cortex_clk) / 1000;
++}
++
++static int amba_cpufreq_target(struct cpufreq_policy *policy,
++		unsigned int target_freq, unsigned int relation)
++{
++	struct cpufreq_freqs freqs;
++	unsigned long cortex_newfreq, core_newfreq;
++	int index, ret;
++	unsigned int cur_freq;
++
++	if(target_freq < 96000) {
++		printk("Target frequency is too low, cortex is not stable, it should be more than 96000\n");
++		return -EINVAL;
++	}
++
++	if (cpufreq_frequency_table_target(policy, amba_cpufreq.cortex_clktbl,
++				target_freq, relation, &index))
++		return -EINVAL;
++
++	freqs.old = amba_cpufreq_get(0);
++	cortex_newfreq = amba_cpufreq.cortex_clktbl[index].frequency * 1000;
++	core_newfreq = amba_cpufreq.core_clktbl[index].frequency * 1000;
++	freqs.new = cortex_newfreq / 1000;
++
++	amba_cpufreq_prt(KERN_INFO "prepare to switch the frequency from %d KHz to %d KHz\n"
++				,freqs.old, freqs.new);
++
++	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
++	ambarella_set_event(AMBA_EVENT_PRE_CPUFREQ, NULL);
++
++	ret = clk_set_rate(amba_cpufreq.cortex_clk, cortex_newfreq);
++	/* Get current rate after clk_set_rate, in case of failure */
++	if (ret) {
++		pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret);
++		freqs.new = clk_get_rate(amba_cpufreq.cortex_clk) / 1000;
++	}
++
++	ret = clk_set_rate(amba_cpufreq.core_clk, core_newfreq);
++	/* Get current rate after clk_set_rate, in case of failure */
++	if (ret) {
++		pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret);
++	}
++
++#if (CHIP_REV == S2L) || (CHIP_REV == S3L)
++	if(amba_cpufreq.core_clktbl[index].frequency <= 96000) {
++		/*Disable IDSP/VDSP to Save Power*/
++		amba_writel(CKEN_CLUSTER_REG, 0x540);
++	} else {
++		/*Enable IDSP/VDSP to Save Power*/
++		amba_writel(CKEN_CLUSTER_REG, 0x3fff);
++	}
++#endif
++	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
++	ambarella_set_event(AMBA_EVENT_POST_CPUFREQ, NULL);
++
++	cur_freq = clk_get_rate(amba_cpufreq.cortex_clk) / 1000;
++	amba_cpufreq_prt(KERN_INFO "current frequency of cortex clock is:%d KHz\n",
++				 cur_freq);
++
++
++	return ret;
++}
++
++static int amba_cpufreq_init(struct cpufreq_policy *policy)
++{
++	int ret;
++
++	ret = cpufreq_frequency_table_cpuinfo(policy, amba_cpufreq.cortex_clktbl);
++	if (ret) {
++		pr_err("cpufreq_frequency_table_cpuinfo() failed");
++		return ret;
++	}
++
++	cpufreq_frequency_table_get_attr(amba_cpufreq.cortex_clktbl, policy->cpu);
++	policy->cpuinfo.transition_latency = amba_cpufreq.transition_latency;
++	policy->cur = amba_cpufreq_get(0);
++
++	cpumask_setall(policy->cpus);
++
++	return 0;
++}
++
++static int amba_cpufreq_exit(struct cpufreq_policy *policy)
++{
++	cpufreq_frequency_table_put_attr(policy->cpu);
++	return 0;
++}
++
++static struct freq_attr *amba_cpufreq_attr[] = {
++	 &cpufreq_freq_attr_scaling_available_freqs,
++	 NULL,
++};
++
++static struct cpufreq_driver amba_cpufreq_driver = {
++	.name		= "amba-cpufreq",
++	.flags		= CPUFREQ_STICKY,
++	.verify		= amba_cpufreq_verify,
++	.target		= amba_cpufreq_target,
++	.get		= amba_cpufreq_get,
++	.init		= amba_cpufreq_init,
++	.exit		= amba_cpufreq_exit,
++	.attr		= amba_cpufreq_attr,
++};
++
++static int amba_cpufreq_driver_init(void)
++{
++	struct device_node *np;
++	const struct property *prop;
++	struct cpufreq_frequency_table *cortex_freqtbl;
++	struct cpufreq_frequency_table *core_freqtbl;
++	const __be32 *val;
++	int cnt, i, ret, clk_div;
++
++	printk("ambarella cpufreq driver init\n");
++	np = of_find_node_by_path("/cpus");
++	if (!np) {
++		pr_err("No cpu node found");
++		return -ENODEV;
++	}
++
++	ret = of_property_read_u32(np, "amb,core-div", &clk_div);
++	if (ret != 0 || !((clk_div == 1 || clk_div == 2))) {
++		/*Default is that the pll_out_core is twice gclk_core */
++		clk_div = 2;
++	}
++
++	if (of_property_read_u32(np, "clock-latency",
++				&amba_cpufreq.transition_latency))
++		amba_cpufreq.transition_latency = CPUFREQ_ETERNAL;
++
++	prop = of_find_property(np, "cpufreq_tbl", NULL);
++	if (!prop || !prop->value) {
++		pr_err("Invalid cpufreq_tbl");
++		ret = -ENODEV;
++		goto out_put_node;
++	}
++
++	cnt = prop->length / sizeof(u32) / 2;
++	val = prop->value;
++
++	cortex_freqtbl = kmalloc(sizeof(*cortex_freqtbl) * (cnt + 2), GFP_KERNEL);
++	if (!cortex_freqtbl) {
++		ret = -ENOMEM;
++		goto out_put_node;
++	}
++
++	core_freqtbl = kmalloc(sizeof(*core_freqtbl) * (cnt + 2), GFP_KERNEL);
++	if (!core_freqtbl) {
++		ret = -ENOMEM;
++		goto out_put_node;
++	}
++
++	for (i = 0; i < cnt; i++) {
++		core_freqtbl[i].index = i;
++		/*pll_out_core = clk_div * gclk_core;*/
++		core_freqtbl[i].frequency = be32_to_cpup(val) * clk_div;
++
++		cortex_freqtbl[i].index = i;
++		cortex_freqtbl[i].frequency = be32_to_cpup((val + 1));
++		val = val + 2;
++
++	}
++
++	cortex_freqtbl[i].index = i;
++	cortex_freqtbl[i].frequency = clk_get_rate(clk_get(NULL, "gclk_cortex")) / 1000;
++
++	core_freqtbl[i].index = i;
++	core_freqtbl[i].frequency = clk_get_rate(clk_get(NULL, "gclk_core")) / 1000 * clk_div;
++
++	i++;
++	cortex_freqtbl[i].index = i;
++	cortex_freqtbl[i].frequency = CPUFREQ_TABLE_END;
++
++	core_freqtbl[i].index = i;
++	core_freqtbl[i].frequency = CPUFREQ_TABLE_END;
++
++	amba_cpufreq.cortex_clktbl = cortex_freqtbl;
++	amba_cpufreq.core_clktbl = core_freqtbl;
++
++	of_node_put(np);
++
++	amba_cpufreq.core_clk = clk_get(NULL, "pll_out_core");
++	if (IS_ERR(amba_cpufreq.core_clk)) {
++		pr_err("Unable to get core clock\n");
++		ret = PTR_ERR(amba_cpufreq.core_clk);
++		goto out_put_mem;
++	}
++
++	amba_cpufreq.cortex_clk = clk_get(NULL, "gclk_cortex");
++	if (IS_ERR(amba_cpufreq.cortex_clk)) {
++		pr_err("Unable to get cotex clock\n");
++		ret = PTR_ERR(amba_cpufreq.cortex_clk);
++		goto out_put_mem;
++	}
++
++	ret = cpufreq_register_driver(&amba_cpufreq_driver);
++	if (!ret)
++		return 0;
++
++	pr_err("failed register driver: %d\n", ret);
++	clk_put(amba_cpufreq.core_clk);
++	clk_put(amba_cpufreq.cortex_clk);
++
++out_put_mem:
++	kfree(cortex_freqtbl);
++	kfree(core_freqtbl);
++	return ret;
++
++out_put_node:
++	of_node_put(np);
++	return ret;
++}
++
++module_init(amba_cpufreq_driver_init);
++
++static void __exit amba_cpufreq_driver_exit(void)
++{
++	cpufreq_unregister_driver(&amba_cpufreq_driver);
++	if(amba_cpufreq.cortex_clktbl != NULL) {
++		kfree(amba_cpufreq.cortex_clktbl);
++		amba_cpufreq.cortex_clktbl = NULL;
++	}
++
++	if(amba_cpufreq.core_clktbl != NULL) {
++		kfree(amba_cpufreq.core_clktbl);
++		amba_cpufreq.core_clktbl = NULL;
++	}
++
++}
++module_exit(amba_cpufreq_driver_exit);
++
++
++MODULE_AUTHOR("XianqingZheng <xqzheng@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella CPUFreq driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
+index 0d8bd55e..3753df3f 100644
+--- a/drivers/cpuidle/Makefile
++++ b/drivers/cpuidle/Makefile
+@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
+ 
+ obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
+ obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
++obj-$(CONFIG_ARCH_AMBARELLA) += cpuidle-ambarella.o
+diff --git a/drivers/cpuidle/cpuidle-ambarella.c b/drivers/cpuidle/cpuidle-ambarella.c
+new file mode 100644
+index 00000000..5ada4d09
+--- /dev/null
++++ b/drivers/cpuidle/cpuidle-ambarella.c
+@@ -0,0 +1,280 @@
++/*
++ * Copyright 2015 ambarella, Inc.
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * Maintainer: Jorney Tu <qtu@ambarella.com>
++ */
++
++#include <linux/cpuidle.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++#include <linux/suspend.h>
++#include <asm/cpuidle.h>
++#include <asm/proc-fns.h>
++#include <asm/smp_scu.h>
++#include <linux/interrupt.h>
++#include <linux/percpu.h>
++#include <linux/cpu.h>
++#include <linux/clk.h>
++#include <linux/cpufreq.h>
++#include "../../kernel/time/tick-internal.h"
++
++#define DEFAULT_FREQENCY_INDEX  1
++
++#define MIN(x,y)   ( (x) < (y) ? (x) : (y) )
++
++#define CPUIDLE_DBG  0
++
++#if CPUIDLE_DBG
++#define dbg_print(fmt, args...)   printk(fmt, ##args)
++#else
++#define dbg_print(fmt, args...)   do{}while(0)
++#endif
++
++
++struct ambarella_cpuidle_info {
++	unsigned int core_old_freqency ;
++	unsigned int cortex_old_freqency ;
++
++	unsigned int freq_tbl_cnt;
++	struct cpufreq_frequency_table *freq_tbl;
++
++	struct clk *core_clk ;   // pll_out_core !!!
++	struct clk *cortex_clk ;
++};
++
++static struct ambarella_cpuidle_info *info = NULL;
++
++static int ambarella_cpufreq_probe(void)
++{
++	const struct property *prop;
++	struct cpufreq_frequency_table *freqs;
++	struct device_node *np;
++	int i, count;
++	int ret = 0;
++	const __be32 *value;
++
++	info = kmalloc(sizeof(struct ambarella_cpuidle_info), GFP_KERNEL);
++	if (!info) {
++		pr_err("kmalloc ambarella_cpuidle_info failed !\n");
++		return -ENOMEM;
++	}
++
++	np = of_find_node_by_path("/cpus");
++	if (!np) {
++		pr_err("No cpu node found");
++		ret = -EFAULT;
++		goto info_mem;
++	}
++
++	prop = of_find_property(np, "cpufreq_tbl", NULL);
++	if (!prop || !prop->value) {
++		pr_err("Invalid cpufreq_tbl");
++		ret = -ENODEV;
++		goto node_put;
++	}
++
++	count = prop->length / sizeof(u32);
++	value = prop->value;
++
++	freqs = kmalloc(sizeof(struct cpufreq_frequency_table) * count,GFP_KERNEL);
++	if (!freqs) {
++		ret = -ENOMEM;
++		goto node_put;
++	}
++
++
++	for (i = 0; i < count; i++) {
++		freqs[i].index = i;
++		freqs[i].frequency = be32_to_cpup(value++);
++	}
++
++	info->freq_tbl_cnt = count;
++	info->freq_tbl = freqs;
++
++	info->core_clk = clk_get(NULL, "pll_out_core");
++	if (IS_ERR(info->core_clk)){
++		pr_err("unable get core clk\n");
++		ret = -EFAULT;
++		goto freq_mem;
++	}
++
++	info->cortex_clk = clk_get(NULL, "gclk_cortex");
++	if (IS_ERR(info->cortex_clk)){
++		pr_err("unable get cortex clk\n");
++		ret = -EFAULT;
++		goto freq_mem;
++	}
++
++	of_node_put(np);
++	return ret;
++
++freq_mem:
++	kfree(freqs);
++node_put:
++	of_node_put(np);
++info_mem:
++	kfree(info);
++	return ret;
++}
++
++static unsigned int ambarella_cur_freq(struct clk *clk)
++{
++	return clk_get_rate(clk) / 1000;
++}
++
++static int ambarella_cpufreq_switch(unsigned int index)
++{
++	int ret ;
++	unsigned int core_new_freqency = 0;
++	unsigned int cortex_new_freqency = 0;
++
++	if(index < 0 || 2 * index > info->freq_tbl_cnt)
++		index = 0;
++
++	info->core_old_freqency = ambarella_cur_freq(info->core_clk) / 2;
++	info->cortex_old_freqency = ambarella_cur_freq(info->cortex_clk);
++
++	core_new_freqency = info->freq_tbl[index * 2].frequency;
++	cortex_new_freqency = info->freq_tbl[index * 2  + 1].frequency;
++
++	ret = clk_set_rate(info->core_clk, core_new_freqency * 1000 * 2);
++	if (ret){
++		pr_err("Core clock set failed\n");
++		return -1;
++	}
++
++	ret = clk_set_rate(info->cortex_clk, cortex_new_freqency * 1000);
++	if (ret){
++		pr_err("Cortex clock set failed\n");
++		return -1;
++	}
++
++	dbg_print("Switch Core frequency from %d to %d\n", info->core_old_freqency, core_new_freqency);
++	dbg_print("Switch Cortex frequency from %d to %d\n", info->cortex_old_freqency, cortex_new_freqency);
++	return 0;
++}
++
++static int ambarella_cpufreq_recover(void)
++{
++	int ret ;
++	unsigned int core_new_freqency = 0;
++	unsigned int cortex_new_freqency = 0;
++
++	core_new_freqency = info->core_old_freqency;
++	cortex_new_freqency = info->cortex_old_freqency;
++
++	info->core_old_freqency = ambarella_cur_freq(info->core_clk) / 2;
++	info->cortex_old_freqency = ambarella_cur_freq(info->cortex_clk);
++
++	ret = clk_set_rate(info->core_clk, core_new_freqency * 1000 * 2);
++	if (ret){
++		pr_err("Core clock set failed\n");
++		return -1;
++	}
++
++	ret = clk_set_rate(info->cortex_clk, cortex_new_freqency * 1000);
++	if (ret){
++		pr_err("Cortex clock set failed\n");
++		return -1;
++	}
++
++	dbg_print("Recover Core frequency from %d to %d\n", info->core_old_freqency, core_new_freqency);
++	dbg_print("Recover Cortex frequency from %d to %d\n", info->cortex_old_freqency, cortex_new_freqency);
++	return 0;
++}
++
++static int disable_percpu_timer(void)
++{
++
++	struct clock_event_device  *dev;
++	struct tick_device *td;
++	int cpu;
++
++	cpu = smp_processor_id();
++	td = &per_cpu(tick_cpu_device, cpu);
++	dev = td->evtdev;
++	clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
++
++	return 0;
++}
++
++static int enable_percpu_timer(void)
++{
++
++	struct clock_event_device  *dev;
++	struct tick_device *td;
++	int cpu;
++
++	cpu = smp_processor_id();
++	td = &per_cpu(tick_cpu_device, cpu);
++	dev = td->evtdev;
++	clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
++
++	return 0;
++}
++
++static void ambarella_idle_exec(unsigned int freq_index)
++{
++
++	ambarella_cpufreq_switch(freq_index);
++
++	disable_percpu_timer();
++
++	cpu_do_idle();
++
++	enable_percpu_timer();
++
++	ambarella_cpufreq_recover();
++}
++
++static int ambarella_pwrdown_idle(struct cpuidle_device *dev,
++				struct cpuidle_driver *drv,
++				int index)
++{
++	ambarella_idle_exec(DEFAULT_FREQENCY_INDEX);
++
++	return index;
++}
++
++static struct cpuidle_driver ambarella_idle_driver = {
++	.name = "ambarella_idle",
++	.states = {
++		ARM_CPUIDLE_WFI_STATE,
++		{
++			.name = "FG",
++			.desc = "FREQ Gate",
++			.flags = CPUIDLE_FLAG_TIMER_STOP,
++			.exit_latency = 30,
++			.power_usage = 50,
++			.target_residency = 400000,      // for judging cpu idle time
++			.enter = ambarella_pwrdown_idle,
++		},
++	},
++	.state_count = 2,
++};
++
++static int __init ambarella_cpuidle_init(void)
++{
++
++	if (ambarella_cpufreq_probe())
++		return -EFAULT;
++
++	return cpuidle_register(&ambarella_idle_driver, NULL);
++}
++module_init(ambarella_cpuidle_init);
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index dffb8552..465af1e8 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -232,6 +232,14 @@ config CRYPTO_DEV_IXP4XX
+ 	help
+ 	  Driver for the IXP4xx NPE crypto engine.
+ 
++config CRYPTO_DEV_AMBARELLA
++	tristate "Driver for Ambarella HW CRYPTO"
++	depends on PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
++	select CRYPTO_AES
++	select CRYPTO_DES
++	help
++	  Driver for Ambarella Soc crypto engine.
++
+ config CRYPTO_DEV_PPC4XX
+ 	tristate "Driver AMCC PPC4xx crypto accelerator"
+ 	depends on PPC && 4xx
+diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
+index 38ce13d3..4a99d530 100644
+--- a/drivers/crypto/Makefile
++++ b/drivers/crypto/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
+ obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
+ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/
+ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
++obj-$(CONFIG_CRYPTO_DEV_AMBARELLA) += ambarella_crypto.o
+ obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
+ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
+ obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
+diff --git a/drivers/crypto/ambarella_crypto.c b/drivers/crypto/ambarella_crypto.c
+new file mode 100644
+index 00000000..53f72e2e
+--- /dev/null
++++ b/drivers/crypto/ambarella_crypto.c
+@@ -0,0 +1,1360 @@
++/*
++ * ambarella_crypto.c
++ *
++ * History:
++ *	2009/09/07 - [Qiao Wang]
++ *    2013/01/04 - [Johnson Diao]
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/io.h>
++#include <linux/interrupt.h>
++#include <linux/completion.h>
++#include <linux/platform_device.h>
++#include <linux/workqueue.h>
++#include <linux/of.h>
++#include <linux/cryptohash.h>
++#include <crypto/algapi.h>
++#include <crypto/aes.h>
++#include <crypto/des.h>
++#include <crypto/sha.h>
++#include <crypto/md5.h>
++#include <crypto/internal/hash.h>
++#include <mach/hardware.h>
++#include <plat/crypto.h>
++
++DEFINE_MUTEX(engine_lock);
++#define AMBA_CIPHER_COPY (1<<4)
++
++static DECLARE_COMPLETION(g_aes_irq_wait);
++static DECLARE_COMPLETION(g_des_irq_wait);
++static DECLARE_COMPLETION(g_md5_sha1_irq_wait);
++
++static struct workqueue_struct *handle_queue;
++static struct work_struct work;
++
++static int config_polling_mode = 0;
++module_param(config_polling_mode, int, S_IRUGO);
++
++static const char *ambdev_name =
++	"Ambarella Media Processor Cryptography Engine";
++
++struct des_ctx {
++	u32 expkey[DES_EXPKEY_WORDS];
++};
++#define AMBA_AES_BLOCK 16
++static md5_digest_t g_md5_digest __attribute__((__aligned__(4)));
++static md5_data_t g_md5_data __attribute__((__aligned__(4)));
++static sha1_digest_t g_sha1_digest __attribute__((__aligned__(4)));
++static sha1_data_t g_sha1_data __attribute__((__aligned__(4)));
++/******************* Basic Function ***************************************/
++static unsigned long long int __ambarella_crypto_aligned_read64(u32 src)
++{
++	long long unsigned int ret;
++	__asm__ __volatile__ (
++	"ldrd %0,[%1]\n"
++	: "=&r"(ret)
++	: "r"(src)
++	 );
++	return ret;
++}
++
++static void __ambarella_crypto_aligned_write64(u32 low, u32 high,u32 dst)
++{
++	__asm__ __volatile__ (
++	"mov r4, %0 \n\t"
++	"mov r5, %1 \n\t"
++	"strd r4, [%2] \n\t"
++	:
++	: "r"(low) , "r"(high),"r"(dst)
++	: "r4", "r5", "memory" );
++}
++
++static int _ambarella_crypto_aligned_read64(u32 * buf,u32 * addr, unsigned int len) {
++	int errCode = -1;
++	int i;
++	if ( ( 0 == (((u32) addr) & 0x07) ) && (0 == (len%8))) {
++		/* address and length should be 64 bit aligned */
++		for (i = 0; i < len/8; i++) {
++			*(unsigned long long int *)(buf + 2*i) = __ambarella_crypto_aligned_read64((u32)(addr + 2*i));
++		}
++		errCode = 0;
++	};
++	return errCode;
++
++}
++
++static int _ambarella_crypto_aligned_write64(u32 * addr,u32 * buf, unsigned int len ) {
++	int errCode = -1;
++	int i;
++	if ( ( 0 == (((u32) addr) & 0x07) ) && (0 == (len%8))) {
++		/* address and length should be 64 bit aligned */
++		for (i = 0; i < len/8; i++) {
++			__ambarella_crypto_aligned_write64(*(u32 *)(buf + 2*i), *(u32 *)(buf + 2*i+1),(u32)(addr + 2*i));
++		}
++		errCode = 0;
++	};
++	return errCode;
++
++}
++
++//merge temp buffer
++#define MAX_MERGE_SIZE 8
++__attribute__ ((aligned (4))) u32 merg[MAX_MERGE_SIZE]={};
++
++struct ambarella_crypto_info {
++	void __iomem *regbase;
++
++	bool binary_mode;
++	bool cap_md5_sha1;
++	bool data_swap;
++	bool reg_64bit;
++};
++struct aes_fun_t{
++	void (*opcode)(u32);
++	void (*wdata)(u32*,u32*,int);
++	void (*rdata)(u32*,u32*,int);
++	u32*  (*reg_enc)(void);
++	u32* (*reg_dec)(void);
++}aes_fun;
++u32* aes_reg_enc_dec_32(void)
++{
++	 return((u32*)CRYPT_A_INPUT1);
++}
++u32* aes_reg_enc_64(void)
++{
++	return( (u32*)CRYPT_A_INPUT1);
++}
++
++u32* aes_reg_dec_64(void)
++{
++	// When run the a5s or other with 32-bit register,this defined is NULL ,
++	//so make sure correct in ambarella_crypto_probe
++	return( (u32*)CRYPT_A_INPUT2);
++}
++
++void swap_write(u32 *offset,u32 *src,int size)
++{
++	int point=0;
++	int len=size;
++
++	for(size=(size>>2)-1;size >= 0;size--,point++){
++		*(merg+point) = ntohl(*(src+size));
++	}
++	//the iONE registers need to accessed by 64-bit boundaries
++	_ambarella_crypto_aligned_write64(offset,merg,len);
++
++}
++
++void swap_read(u32 *offset,u32 *src,int size)
++{
++	int point=0,len=size;
++
++	//the iONE registers need to accessed by 64-bit boundaries
++	_ambarella_crypto_aligned_read64(merg,src,len);
++	for(size=(size>>2)-1;size >= 0;size--,point++){
++		*(offset+point) = ntohl(*(merg+size));
++	}
++}
++
++void aes_opcode(u32 flag)
++{
++	// When run the a7 or higher version with 64-bit  register,this defined is NULL,
++	//so make sure correct in ambarella_crypto_probe
++	amba_writel(CRYPT_A_OPCODE, flag);
++}
++
++void null_fun(u32 flag) {}
++/***************** AES Function **********************************/
++static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++	struct crypto_aes_ctx *ctx=crypto_tfm_ctx(tfm);
++	const __le32 *src = (const __le32 *)in;
++	__le32 *dst = (__le32 *)out;
++	u32 ready;
++	u32 *offset=NULL;
++	do{}while(mutex_trylock(&engine_lock) == 0);
++	switch (ctx->key_length){
++	case 16:
++		offset = (u32*)CRYPT_A_128_96_REG;
++		aes_fun.wdata(offset,ctx->key_enc,16);
++		break;
++	case 24:
++		offset = (u32*)CRYPT_A_192_160_REG;
++		aes_fun.wdata(offset,ctx->key_enc,24);
++		break;
++	case 32:
++		offset = (u32*)CRYPT_A_256_224_REG;
++		aes_fun.wdata(offset,ctx->key_enc,32);
++		break;
++	}
++	//enc or dec option mode
++	aes_fun.opcode(AMBA_HW_ENCRYPT_CMD);
++
++	//get the input offset
++	offset = aes_fun.reg_enc();
++
++	//input the src
++	aes_fun.wdata(offset,(u32*)src,16);
++
++	do{
++		ready = amba_readl(CRYPT_A_OUTPUT_READY_REG);
++	}while(ready != 1);
++
++	//get the output
++	offset = (u32*)CRYPT_A_OUTPUT_96_REG;
++	aes_fun.rdata(dst,offset,16);
++	mutex_unlock(&engine_lock);
++}
++
++
++static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++	struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
++	const __le32 *src = (const __le32 *)in;
++	__le32 *dst = (__le32 *)out;
++	u32 ready;
++	u32 *offset=NULL;
++
++	do{}while(mutex_trylock(&engine_lock) == 0);
++	switch (ctx->key_length) {
++	case 16:
++		offset = (u32*)CRYPT_A_128_96_REG;
++		aes_fun.wdata(offset,ctx->key_enc,16);
++	        break;
++	case 24:
++		offset = (u32*)CRYPT_A_192_160_REG;
++		aes_fun.wdata(offset,ctx->key_enc,24);
++	        break;
++	case 32:
++		offset = (u32*)CRYPT_A_256_224_REG;
++		aes_fun.wdata(offset,ctx->key_enc,32);
++	        break;
++	}
++	//enc or dec option mode
++	aes_fun.opcode(AMBA_HW_DECRYPT_CMD);
++
++	//get the input offset
++	offset = aes_fun.reg_dec();
++
++	//input the src
++	aes_fun.wdata(offset,(u32*)src,16);
++
++	do{
++		ready = amba_readl(CRYPT_A_OUTPUT_READY_REG);
++	}while(ready != 1);
++
++
++	//get the output
++	offset = (u32*)CRYPT_A_OUTPUT_96_REG;
++	aes_fun.rdata(dst,offset,16);
++	mutex_unlock(&engine_lock);
++}
++
++static struct crypto_alg aes_alg = {
++	.cra_name		=	"aes",
++	.cra_driver_name	=	"aes-ambarella",
++	.cra_priority		=	AMBARELLA_CRA_PRIORITY,
++	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
++	.cra_blocksize		=	AES_BLOCK_SIZE,
++	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
++	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
++	.cra_module		=	THIS_MODULE,
++	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
++	.cra_u			=	{
++		.cipher = {
++			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
++			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
++			.cia_setkey	   		= 	crypto_aes_set_key,
++			.cia_encrypt	 	=	aes_encrypt,
++			.cia_decrypt	  	=	aes_decrypt,
++		}
++	}
++};
++
++/****************** DES Function **************************/
++struct des_fun_t{
++	void (*opcode)(u32);
++	void (*wdata)(u32*,u32*,int);
++	void (*rdata)(u32*,u32*,int);
++	u32* (*reg_enc)(void);
++	u32* (*reg_dec)(void);
++}des_fun;
++
++u32* des_reg_enc_dec_32(void)
++{
++	return((u32*)CRYPT_D_INPUT1);
++}
++
++u32* des_reg_enc_64(void)
++{
++	return((u32*)CRYPT_D_INPUT1);
++}
++
++u32* des_reg_dec_64(void)
++{
++	// When run the a5s or other with 32-bit register,this defined is NULL ,
++	//so make sure correct in ambarella_crypto_probe
++	return((u32*)CRYPT_D_INPUT2);
++}
++
++void des_opcode(u32 flag)
++{
++	// When run the a7 or higher version with 64-bit  register,this defined is NULL,
++	//so make sure correct in ambarella_crypto_probe
++	amba_writel(CRYPT_D_OPCODE, flag);
++}
++
++static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
++		      unsigned int keylen)
++{
++	struct des_ctx *dctx = crypto_tfm_ctx(tfm);
++	u32 *flags = &tfm->crt_flags;
++	u32 tmp[DES_EXPKEY_WORDS];
++	int ret;
++
++
++	/* Expand to tmp */
++	ret = des_ekey(tmp, key);
++
++	if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
++		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
++		return -EINVAL;
++	}
++
++	/* Copy to output */
++	memcpy(dctx->expkey, key, keylen);
++
++	return 0;
++}
++
++static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++	struct des_ctx *ctx = crypto_tfm_ctx(tfm);
++	const __le32 *src = (const __le32 *)in;
++	__le32 *dst = (__le32 *)out;
++	u32 ready;
++	u32 *offset=NULL;
++
++	do{}while(mutex_trylock(&engine_lock) == 0);
++	//set key
++	des_fun.wdata((u32*)CRYPT_D_HI_REG,ctx->expkey,8);
++
++	//enc or dec option mode
++	des_fun.opcode(AMBA_HW_ENCRYPT_CMD);
++
++	//get the input offset
++	offset = des_fun.reg_enc();
++
++	//input the src
++	des_fun.wdata(offset,(u32*)src,8);
++
++	do{
++		ready = amba_readl(CRYPT_D_OUTPUT_READY_REG);
++	}while(ready != 1);
++
++
++	//get the output
++	offset = (u32*)CRYPT_D_OUTPUT_HI_REG;
++	des_fun.rdata(dst,offset,8);
++	mutex_unlock(&engine_lock);
++}
++
++static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++	struct des_ctx *ctx = crypto_tfm_ctx(tfm);
++	const __le32 *src = (const __le32 *)in;
++	__le32 *dst = (__le32 *)out;
++	u32 ready;
++	u32 *offset=NULL;
++
++	do{}while(mutex_trylock(&engine_lock) == 0);
++	//set key
++	des_fun.wdata((u32*)CRYPT_D_HI_REG,ctx->expkey,8);
++
++	//enc or dec option mode
++	des_fun.opcode(AMBA_HW_DECRYPT_CMD);
++
++	//get the input offset
++	offset = des_fun.reg_dec();
++
++	//input the src
++	des_fun.wdata(offset,(u32*)src,8);
++
++	do{
++		ready = amba_readl(CRYPT_D_OUTPUT_READY_REG);
++	}while(ready != 1);
++
++	//get the output
++	offset = (u32*)CRYPT_D_OUTPUT_HI_REG;
++	des_fun.rdata(dst,offset,8);
++	mutex_unlock(&engine_lock);
++
++}
++
++
++static struct crypto_alg des_alg = {
++	.cra_name		=	"des",
++	.cra_driver_name	=	"des-ambarella",
++	.cra_priority		=	AMBARELLA_CRA_PRIORITY,
++	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
++	.cra_blocksize		=	DES_BLOCK_SIZE,
++	.cra_ctxsize		=	sizeof(struct des_ctx),
++	.cra_module		=	THIS_MODULE,
++	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
++	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
++	.cra_u			=	{
++		.cipher = {
++			.cia_min_keysize	=	DES_KEY_SIZE,
++			.cia_max_keysize	=	DES_KEY_SIZE,
++			.cia_setkey		=	des_setkey,
++			.cia_encrypt		=	des_encrypt,
++			.cia_decrypt		=	des_decrypt
++		}
++	}
++};
++/******************** ECB(AES) Function ***************************************************/
++
++#define MAX_BLOCK 8192
++#define AES_MAX_KEYLENGTH	(15 * 16)
++#define AES_MAX_KEYLENGTH_U32	(AES_MAX_KEYLENGTH / sizeof(u32))
++struct amba_ecb_ctx {
++	u32 enc_key[AES_MAX_KEYLENGTH_U32];
++	int key_len;
++};
++
++struct request_ops{
++	enum{
++		enc,
++		dec,
++	}op;
++	struct ablkcipher_walk walk;
++};
++
++static struct pri_queue {
++	struct crypto_queue queue;
++	spinlock_t lock;
++
++	enum {
++		IDLE,
++		BUSY,
++	}status;
++
++}amba_queue;
++
++static void  handle_aes_encrypt(struct amba_ecb_ctx *ctx, u8 *out, u8* in)
++{
++	u32 *offset=NULL;
++	__le32 *src = (__le32 *)in;
++	__le32 *dst = (__le32 *)out;
++	int ready=0;
++
++	switch (ctx->key_len){
++	case 16:
++		offset = (u32*)CRYPT_A_128_96_REG;
++		aes_fun.wdata(offset,ctx->enc_key,16);
++		break;
++	case 24:
++		offset = (u32*)CRYPT_A_192_160_REG;
++		aes_fun.wdata(offset,ctx->enc_key,24);
++		break;
++	case 32:
++		offset = (u32*)CRYPT_A_256_224_REG;
++		aes_fun.wdata(offset,ctx->enc_key,32);
++		break;
++	}
++	aes_fun.opcode(AMBA_HW_ENCRYPT_CMD);
++	offset = aes_fun.reg_enc();
++	aes_fun.wdata(offset,(u32*)src,16);
++
++	do{
++		ready = try_wait_for_completion(&g_aes_irq_wait);
++	}while(ready != 1);
++
++	offset = (u32*)CRYPT_A_OUTPUT_96_REG;
++	aes_fun.rdata(dst,offset,16);
++
++}
++static void handle_aes_decrypt(struct amba_ecb_ctx *ctx, u8 *out, u8* in)
++{
++	u32 *offset=NULL;
++	__le32 *src = (__le32 *)in;
++	__le32 *dst = (__le32 *)out;
++	int ready = 0;
++
++
++	switch (ctx->key_len){
++	case 16:
++		offset = (u32*)CRYPT_A_128_96_REG;
++		aes_fun.wdata(offset,ctx->enc_key,16);
++		break;
++	case 24:
++		offset = (u32*)CRYPT_A_192_160_REG;
++		aes_fun.wdata(offset,ctx->enc_key,24);
++		break;
++	case 32:
++		offset = (u32*)CRYPT_A_256_224_REG;
++		aes_fun.wdata(offset,ctx->enc_key,32);
++		break;
++	}
++
++	aes_fun.opcode(AMBA_HW_DECRYPT_CMD);
++	offset = aes_fun.reg_dec();
++	aes_fun.wdata(offset,(u32*)src,16);
++
++	do{
++		ready = try_wait_for_completion(&g_aes_irq_wait);
++	}while(ready != 1);
++
++	offset = (u32*)CRYPT_A_OUTPUT_96_REG;
++	aes_fun.rdata(dst,offset,16);
++
++}
++
++static int handle_ecb_aes_req(struct ablkcipher_request *req)
++{
++	int nbytes,err;
++	struct amba_ecb_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
++	struct crypto_async_request *base = &req->base;
++	struct request_ops *req_ctx = ablkcipher_request_ctx(req);
++	struct crypto_tfm *tfm = req->base.tfm;
++	struct blkcipher_desc desc = {
++		.tfm = __crypto_blkcipher_cast(tfm),
++		.info = req->info,
++		.flags = req->base.flags,
++	};
++	void (*fun)(struct amba_ecb_ctx *ctx, u8 *out, u8* in);
++	struct blkcipher_walk walk;
++
++	walk.flags |= AMBA_CIPHER_COPY;
++	blkcipher_walk_init(&walk, req->dst, req->src, req->nbytes);
++
++
++	if (req_ctx->op == enc){
++		fun = handle_aes_encrypt;
++	}else{
++		fun = handle_aes_decrypt;
++	}
++
++
++	err = blkcipher_walk_virt(&desc, &walk);
++
++	while ((nbytes = walk.nbytes)) {
++			u8 *wsrc = walk.src.virt.addr;
++			u8 *wdst = walk.dst.virt.addr;
++
++			do {
++				fun(ctx, wdst, wsrc);
++
++				wsrc += AMBA_AES_BLOCK;
++				wdst += AMBA_AES_BLOCK;
++			} while ((nbytes -= AMBA_AES_BLOCK) >= AMBA_AES_BLOCK);
++
++			err = blkcipher_walk_done(&desc, &walk, nbytes);
++	}
++
++
++	local_bh_disable();
++	base->complete(base,err);
++	local_bh_enable();
++	return 0;
++}
++
++static void do_queue(void)
++{
++	struct crypto_async_request *async_req = NULL;
++	struct crypto_async_request *backlog=NULL;
++	spin_lock_irq(&amba_queue.lock);
++	if (amba_queue.status == IDLE){
++		backlog = crypto_get_backlog(&amba_queue.queue);
++		async_req = crypto_dequeue_request(&amba_queue.queue);
++		if(async_req){
++			BUG_ON(amba_queue.status != IDLE);
++			amba_queue.status = BUSY;
++		}
++	}
++	spin_unlock_irq(&amba_queue.lock);
++	if (backlog){
++		backlog->complete(backlog,-EINPROGRESS);
++		backlog = NULL;
++	}
++	if (async_req){
++		struct ablkcipher_request *req =
++				container_of(async_req,
++						struct ablkcipher_request,
++						base);
++		// handle the request
++		handle_ecb_aes_req(req);
++		amba_queue.status = IDLE;
++	}
++	return;
++}
++
++static int ecb_aes_set_key(struct crypto_ablkcipher *cipher,const u8 *key,
++			unsigned int len)
++{
++	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
++	struct amba_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
++	switch (len){
++	case 16:
++	case 24:
++	case 32:
++		break;
++	default:
++		crypto_ablkcipher_set_flags(cipher,CRYPTO_TFM_RES_BAD_KEY_LEN);
++		return -EINVAL;
++	}
++	ctx->key_len = len;
++	memcpy(ctx->enc_key,key,len);
++	return 0;
++}
++
++static int amba_handle_req(struct ablkcipher_request *req)
++{
++	int ret;
++	unsigned long flags;
++
++	spin_lock_irqsave(&amba_queue.lock,flags);
++	ret = crypto_enqueue_request(&amba_queue.queue,&req->base);
++	spin_unlock_irqrestore(&amba_queue.lock,flags);
++
++	queue_work(handle_queue,&work);
++
++	return ret;
++}
++
++static int ecb_aes_encrypt(struct ablkcipher_request *req)
++{
++	struct request_ops *req_ctx = ablkcipher_request_ctx(req);
++	req_ctx->op = enc;
++	return amba_handle_req(req);
++}
++
++static int ecb_aes_decrypt(struct ablkcipher_request *req)
++{
++	struct request_ops *req_ctx = ablkcipher_request_ctx(req);
++	req_ctx->op = dec;
++	return amba_handle_req(req);
++}
++
++static int aes_cra_init(struct crypto_tfm *tfm)
++{
++	return 0;
++}
++
++
++static struct crypto_alg ecb_aes_alg = {
++	.cra_name		=	"ecb(aes)",
++	.cra_driver_name	=	"ecb-aes-ambarella",
++	.cra_priority		=	AMBARELLA_COMPOSITE_PRIORITY,
++	.cra_flags		=	CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
++	.cra_blocksize		=	AES_BLOCK_SIZE,
++	.cra_ctxsize		=	sizeof(struct amba_ecb_ctx),
++	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
++	.cra_type		=	&crypto_ablkcipher_type,
++	.cra_module		=	THIS_MODULE,
++	.cra_init		= aes_cra_init,
++	.cra_u			=	{
++		.ablkcipher = {
++			.min_keysize		=	AES_MIN_KEY_SIZE,
++			.max_keysize		=	AES_MAX_KEY_SIZE,
++			.setkey	   		= 	ecb_aes_set_key,
++			.encrypt		=	ecb_aes_encrypt,
++			.decrypt		=	ecb_aes_decrypt,
++		}
++	}
++};
++
++static int cbc_aes_encrypt(struct blkcipher_desc *desc,
++			   struct scatterlist *dst, struct scatterlist *src,
++			   unsigned int nbytes)
++{
++	int err = 0;
++
++	return err;
++}
++
++static int cbc_aes_decrypt(struct blkcipher_desc *desc,
++			   struct scatterlist *dst, struct scatterlist *src,
++			   unsigned int nbytes)
++{
++	int err = 0;
++
++	return err;
++}
++
++static struct crypto_alg cbc_aes_alg = {
++	.cra_name		=	"cbc(aes)",
++	.cra_driver_name	=	"cbc-aes-ambarella",
++	.cra_priority		=	AMBARELLA_COMPOSITE_PRIORITY,
++	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
++	.cra_blocksize		=	AES_BLOCK_SIZE,
++	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
++	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
++	.cra_type		=	&crypto_blkcipher_type,
++	.cra_module		=	THIS_MODULE,
++	.cra_list		=	LIST_HEAD_INIT(cbc_aes_alg.cra_list),
++	.cra_u			=	{
++		.blkcipher = {
++			.min_keysize		=	AES_MIN_KEY_SIZE,
++			.max_keysize		=	AES_MAX_KEY_SIZE,
++			.ivsize			=	AES_BLOCK_SIZE,
++			.setkey	   		= 	crypto_aes_set_key,
++			.encrypt		=	cbc_aes_encrypt,
++			.decrypt		=	cbc_aes_decrypt,
++		}
++	}
++};
++/************************************MD5 START**************************/
++
++struct md5_sha1_fun_t{
++	void (*wdata)(u32*,u32*,int);
++	void (*rdata)(u32*,u32*,int);
++}md5_sha1_fun;
++
++static void ambarella_md5_transform(u32 *hash, u32 const *in)
++{
++	u32 ready;
++	do{}while(mutex_trylock(&engine_lock) == 0);
++
++	memcpy(&g_md5_digest.digest_0, hash, 16);
++
++	do{
++		ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
++	}while(ready != 1);
++
++	md5_sha1_fun.wdata((u32 *)CRYPT_MD5_INIT_31_0,&(g_md5_digest.digest_0),16);
++
++	do{
++		ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
++	}while(ready != 1);
++
++	memcpy(&g_md5_data.data[0], in, 64);
++
++	md5_sha1_fun.wdata((u32 *)CRYPT_MD5_INPUT_31_0,&(g_md5_data.data[0]),64);
++
++	if(unlikely(config_polling_mode == 0)) {
++		do{
++			ready = try_wait_for_completion(&g_md5_sha1_irq_wait);
++		}while(ready != 1);
++	}else{
++		do{
++			ready = amba_readl(CRYPT_MD5_OUTPUT_READY);
++		}while(ready != 1);
++	}
++
++	md5_sha1_fun.rdata(&(g_md5_digest.digest_0),(u32 *)CRYPT_MD5_OUTPUT_31_0, 16);
++
++	memcpy(hash, &g_md5_digest.digest_0, 16);
++
++	mutex_unlock(&engine_lock);
++}
++
++static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
++{
++	while (words--) {
++		__le32_to_cpus(buf);
++		buf++;
++	}
++}
++
++static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
++{
++	while (words--) {
++		__cpu_to_le32s(buf);
++		buf++;
++	}
++}
++
++static inline void ambarella_md5_transform_helper(struct md5_state *ctx)
++{
++	le32_to_cpu_array(ctx->block, sizeof(ctx->block)/sizeof(u32));
++	ambarella_md5_transform(ctx->hash, ctx->block);
++}
++
++static int ambarella_md5_init(struct shash_desc *desc)
++{
++	struct md5_state *mctx = shash_desc_ctx(desc);
++	mctx->hash[0] = 0x67452301;
++	mctx->hash[1] = 0xefcdab89;
++	mctx->hash[2] = 0x98badcfe;
++	mctx->hash[3] = 0x10325476;
++	mctx->byte_count = 0;
++	return 0;
++}
++
++static int ambarella_md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
++{
++	struct md5_state *mctx = shash_desc_ctx(desc);
++	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
++	mctx->byte_count += len;
++
++	if (avail > len) {
++		memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
++		       data, len);
++		return 0;
++	}
++
++	memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
++	       data, avail);
++
++	ambarella_md5_transform_helper(mctx);
++	data += avail;
++	len -= avail;
++
++	while (len >= sizeof(mctx->block)) {
++		memcpy(mctx->block, data, sizeof(mctx->block));
++		ambarella_md5_transform_helper(mctx);
++		data += sizeof(mctx->block);
++		len -= sizeof(mctx->block);
++	}
++
++	memcpy(mctx->block, data, len);
++
++	return 0;
++}
++
++static int ambarella_md5_final(struct shash_desc *desc, u8 *out)
++{
++	struct md5_state *mctx = shash_desc_ctx(desc);
++	const unsigned int offset = mctx->byte_count & 0x3f;
++	char *p = (char *)mctx->block + offset;
++	int padding = 56 - (offset + 1);
++	*p++ = 0x80;
++	if (padding < 0) {
++		memset(p, 0x00, padding + sizeof (u64));
++		ambarella_md5_transform_helper(mctx);
++		p = (char *)mctx->block;
++		padding = 56;
++	}
++
++	memset(p, 0, padding);
++	mctx->block[14] = mctx->byte_count << 3;
++	mctx->block[15] = mctx->byte_count >> 29;
++	le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
++	                  sizeof(u64)) / sizeof(u32));
++	ambarella_md5_transform(mctx->hash, mctx->block);
++	cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
++	memcpy(out, mctx->hash, sizeof(mctx->hash));
++	memset(mctx, 0, sizeof(*mctx));
++	return 0;
++}
++
++static int ambarella_md5_export(struct shash_desc *desc, void *out)
++{
++	struct md5_state *ctx = shash_desc_ctx(desc);
++	memcpy(out, ctx, sizeof(*ctx));
++	return 0;
++}
++
++static int ambarella_md5_import(struct shash_desc *desc, const void *in)
++{
++	struct md5_state *ctx = shash_desc_ctx(desc);
++	memcpy(ctx, in, sizeof(*ctx));
++	return 0;
++}
++
++static struct shash_alg md5_alg = {
++	.digestsize	=	MD5_DIGEST_SIZE,
++	.init		=	ambarella_md5_init,
++	.update		=	ambarella_md5_update,
++	.final		=	ambarella_md5_final,
++	.export		=	ambarella_md5_export,
++	.import		=	ambarella_md5_import,
++	.descsize	=	sizeof(struct md5_state),
++	.statesize	=	sizeof(struct md5_state),
++	.base		=	{
++		.cra_name	=	"md5",
++		.cra_driver_name=	"md5-ambarella",
++		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
++		.cra_blocksize	=	MD5_HMAC_BLOCK_SIZE,
++		.cra_module	=	THIS_MODULE,
++	}
++};
++/************************************MD5 END**************************/
++
++/************************************SHA1 START**************************/
++static inline void be32_to_cpu_array(u32 *buf, unsigned int words)
++{
++	while (words--) {
++		__be32_to_cpus(buf);
++		buf++;
++	}
++}
++
++static inline void cpu_to_be32_array(u32 *buf, unsigned int words)
++{
++	while (words--) {
++		__cpu_to_be32s(buf);
++		buf++;
++	}
++}
++
++static int ambarella_sha1_init(struct shash_desc *desc)
++{
++	struct sha1_state *sctx = shash_desc_ctx(desc);
++	*sctx = (struct sha1_state){
++		.state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
++	};
++	return 0;
++}
++
++void md5_sha1_write64(u32 * addr,u32 * buf, unsigned int len )
++{
++	/* len%8 ,align at 64bit*/
++	if ((len&0x7)){
++		len += (len&0x7);
++	}
++	_ambarella_crypto_aligned_write64(addr,buf,len);
++}
++
++void md5_sha1_read64(u32 * addr,u32 * buf, unsigned int len )
++{
++	/* len%8 ,align at 64bit*/
++	if ((len&0x7)){
++		len += (len&0x7);
++	}
++	_ambarella_crypto_aligned_read64(addr,buf,len);
++}
++
++void ambarella_sha1_transform(__u32 *digest, const char *in, __u32 *W)
++{
++    u32 ready;
++
++    do{}while(mutex_trylock(&engine_lock) == 0);
++
++    cpu_to_be32_array(digest, 5);
++    memcpy(&g_sha1_digest.digest_0, digest, 16);
++    g_sha1_digest.digest_128 = digest[4];
++
++    do{
++        ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
++    }while(ready != 1);
++
++    md5_sha1_fun.wdata((u32 *)CRYPT_SHA1_INIT_31_0,&(g_sha1_digest.digest_0),20);
++    do{
++        ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
++    }while(ready != 1);
++
++    memcpy(&g_sha1_data.data[0], in, 64);
++
++    md5_sha1_fun.wdata((u32 *)CRYPT_SHA1_INPUT_31_0,&(g_sha1_data.data[0]),64);
++
++    if(likely(config_polling_mode == 0)) {
++	do{
++            ready = try_wait_for_completion(&g_md5_sha1_irq_wait);
++        }while(ready != 1);
++
++    }else{
++        do{
++            ready = amba_readl(CRYPT_SHA1_OUTPUT_READY);
++        }while(ready != 1);
++    }
++
++    md5_sha1_fun.rdata(&(g_sha1_digest.digest_0),(u32 *)CRYPT_SHA1_OUTPUT_31_0,20);
++
++    memcpy(digest, &g_sha1_digest.digest_0, 20);
++    cpu_to_be32_array(digest, 5);
++
++    mutex_unlock(&engine_lock);
++}
++
++
++
++static int ambarella_sha1_update(struct shash_desc *desc, const u8 *data,
++			unsigned int len)
++{
++	struct sha1_state *sctx = shash_desc_ctx(desc);
++	unsigned int partial, done;
++	const u8 *src;
++
++	partial = sctx->count & 0x3f;
++	sctx->count += len;
++	done = 0;
++	src = data;
++
++	if ((partial + len) > 63) {
++		u32 temp[SHA_WORKSPACE_WORDS];
++
++		if (partial) {
++			done = -partial;
++			memcpy(sctx->buffer + partial, data, done + 64);
++			src = sctx->buffer;
++		}
++
++		do {
++			ambarella_sha1_transform(sctx->state, src, temp);
++			done += 64;
++			src = data + done;
++		} while (done + 63 < len);
++
++		memset(temp, 0, sizeof(temp));
++		partial = 0;
++	}
++	memcpy(sctx->buffer + partial, src, len - done);
++
++	return 0;
++}
++
++/* Add padding and return the message digest. */
++static int ambarella_sha1_final(struct shash_desc *desc, u8 *out)
++{
++	struct sha1_state *sctx = shash_desc_ctx(desc);
++	__be32 *dst = (__be32 *)out;
++	u32 i, index, padlen;
++	__be64 bits;
++	static const u8 padding[64] = { 0x80, };
++
++	bits = cpu_to_be64(sctx->count << 3);
++
++	/* Pad out to 56 mod 64 */
++	index = sctx->count & 0x3f;
++	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
++	ambarella_sha1_update(desc, padding, padlen);
++
++	/* Append length */
++	ambarella_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
++
++	/* Store state in digest */
++	for (i = 0; i < 5; i++)
++		dst[i] = cpu_to_be32(sctx->state[i]);
++
++	/* Wipe context */
++	memset(sctx, 0, sizeof *sctx);
++
++	return 0;
++}
++
++static int ambarella_sha1_export(struct shash_desc *desc, void *out)
++{
++	struct sha1_state *sctx = shash_desc_ctx(desc);
++	memcpy(out, sctx, sizeof(*sctx));
++	return 0;
++}
++
++static int ambarella_sha1_import(struct shash_desc *desc, const void *in)
++{
++	struct sha1_state *sctx = shash_desc_ctx(desc);
++	memcpy(sctx, in, sizeof(*sctx));
++	return 0;
++}
++
++
++static struct shash_alg sha1_alg = {
++	.digestsize	=	SHA1_DIGEST_SIZE,
++	.init		=	ambarella_sha1_init,
++	.update		=	ambarella_sha1_update,
++	.final		=	ambarella_sha1_final,
++	.export		=	ambarella_sha1_export,
++	.import		=	ambarella_sha1_import,
++	.descsize	=	sizeof(struct sha1_state),
++	.statesize	=	sizeof(struct sha1_state),
++	.base		=	{
++		.cra_name	=	"sha1",
++		.cra_driver_name=	"sha1-ambarella",
++		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
++		.cra_blocksize	=	SHA1_BLOCK_SIZE,
++		.cra_module	=	THIS_MODULE,
++	}
++};
++
++/************************************SHA1 END****************************/
++
++static irqreturn_t ambarella_aes_irq(int irqno, void *dev_id)
++{
++	complete(&g_aes_irq_wait);
++
++	return IRQ_HANDLED;
++}
++static irqreturn_t ambarella_des_irq(int irqno, void *dev_id)
++{
++	complete(&g_des_irq_wait);
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t ambarella_md5_sha1_irq(int irqno, void *dev_id)
++{
++	complete(&g_md5_sha1_irq_wait);
++
++	return IRQ_HANDLED;
++}
++
++static int ambarella_crypto_of_parse(struct platform_device *pdev,
++			struct ambarella_crypto_info *pinfo)
++{
++	struct device_node *np = pdev->dev.of_node;
++
++	pinfo->binary_mode = !!of_find_property(np, "amb,binary-mode", NULL);
++	pinfo->cap_md5_sha1 = !!of_find_property(np, "amb,cap-md5-sha1", NULL);
++	pinfo->data_swap = !!of_find_property(np, "amb,data-swap", NULL);
++	pinfo->reg_64bit = !!of_find_property(np, "amb,reg-64bit", NULL);
++
++	return 0;
++}
++
++static int ambarella_crypto_probe(struct platform_device *pdev)
++{
++	struct resource	*mem = 0;
++	struct ambarella_crypto_info *pinfo = 0;
++	int aes_irq, des_irq, md5_irq, sha1_irq;
++	int errCode;
++
++	pinfo = devm_kzalloc(&pdev->dev, sizeof(*pinfo), GFP_KERNEL);
++	if (pinfo == NULL) {
++		dev_err(&pdev->dev, "Out of memory!\n");
++		return -ENOMEM;
++	}
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get crypto mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	pinfo->regbase = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
++	if (!pinfo->regbase) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	platform_set_drvdata(pdev, pinfo);
++
++	ambarella_crypto_of_parse(pdev, pinfo);
++
++	if(likely(config_polling_mode == 0)) {
++		aes_irq = platform_get_irq_byname(pdev,"aes-irq");
++		if (aes_irq < 0) {
++			dev_err(&pdev->dev, "Get crypto aes irq failed!\n");
++			return aes_irq;
++		}
++
++		des_irq = platform_get_irq_byname(pdev,"des-irq");
++		if (des_irq < 0) {
++			dev_err(&pdev->dev, "Get crypto des irq failed!\n");
++			return aes_irq;
++		}
++
++		errCode = devm_request_irq(&pdev->dev, aes_irq,
++					ambarella_aes_irq, IRQF_TRIGGER_RISING,
++					dev_name(&pdev->dev), pinfo);
++		if (errCode < 0) {
++			dev_err(&pdev->dev, "Request aes irq failed!\n");
++			return errCode;
++		}
++		errCode = devm_request_irq(&pdev->dev, des_irq,
++					ambarella_des_irq, IRQF_TRIGGER_RISING,
++					dev_name(&pdev->dev), pinfo);
++		if (errCode < 0) {
++			dev_err(&pdev->dev, "Request des irq failed!\n");
++			return errCode;
++		}
++
++		amba_writel(CRYPT_A_INT_EN_REG, 0x0001);
++		amba_writel(CRYPT_D_INT_EN_REG, 0x0001);
++
++		if (pinfo->cap_md5_sha1 == 1) {
++			md5_irq = platform_get_irq_byname(pdev,"md5-irq");
++			if (md5_irq < 0){
++				dev_err(&pdev->dev, "Get crypto md5 irq failed!\n");
++				return md5_irq;
++			}
++
++			sha1_irq = platform_get_irq_byname(pdev,"sha1-irq");
++			if (sha1_irq < 0){
++				dev_err(&pdev->dev, "Get crypto sha1 irq failed!\n");
++				return sha1_irq;
++			}
++
++			/* md5 and sha1 opentions can't be interleaved, so we
++			 * use the same return irq func */
++			errCode = devm_request_irq(&pdev->dev, md5_irq,
++						ambarella_md5_sha1_irq,
++						IRQF_TRIGGER_RISING,
++						dev_name(&pdev->dev), pinfo);
++			if (errCode < 0) {
++				dev_err(&pdev->dev, "Request md5 irq failed!\n");
++				return errCode;
++			}
++
++			errCode = devm_request_irq(&pdev->dev, sha1_irq,
++						ambarella_md5_sha1_irq,
++						IRQF_TRIGGER_RISING,
++						dev_name(&pdev->dev), pinfo);
++			if (errCode < 0) {
++				dev_err(&pdev->dev, "Request sha1 irq failed!\n");
++				return errCode;
++			}
++
++			amba_writel(CRYPT_MD5_INT_EN, 0x0001);
++			amba_writel(CRYPT_SHA1_INT_EN, 0x0001);
++		}
++		//init workqueue
++
++		spin_lock_init(&amba_queue.lock);
++		handle_queue = create_workqueue("Crypto Ablk Workqueue");
++		INIT_WORK(&work,(void *)do_queue);
++
++		//register ecb aes ,des
++		errCode = crypto_register_alg(&ecb_aes_alg);
++		if (errCode <0) {
++			dev_err(&pdev->dev,"register ecb_aes_alg failed. \n");
++			return errCode;
++		}
++
++		crypto_init_queue(&amba_queue.queue,50);
++	} else {
++		errCode = crypto_register_alg(&aes_alg);
++		if (errCode <0) {
++			dev_err(&pdev->dev, "reigster aes_alg  failed.\n");
++			return errCode;
++		}
++	}
++
++	if (pinfo->binary_mode){
++		aes_fun.opcode = aes_opcode;
++		des_fun.opcode = des_opcode;
++	}else{
++		aes_fun.opcode = null_fun;
++		des_fun.opcode = null_fun;
++	}
++
++	if (pinfo->data_swap){
++		aes_fun.wdata = swap_write;
++		aes_fun.rdata = swap_read;
++		des_fun.wdata = swap_write;
++		des_fun.rdata = swap_read;
++	}else{
++		aes_fun.wdata = (void*)memcpy;
++		aes_fun.rdata = (void*)memcpy;
++		des_fun.wdata = (void*)memcpy;
++		des_fun.rdata = (void*)memcpy;
++	}
++
++	if (pinfo->reg_64bit){
++		aes_fun.reg_enc = aes_reg_enc_64;
++		aes_fun.reg_dec = aes_reg_dec_64;
++		des_fun.reg_enc = des_reg_enc_64;
++		des_fun.reg_dec = des_reg_dec_64;
++	}else{
++		aes_fun.reg_enc = aes_reg_enc_dec_32;
++		aes_fun.reg_dec = aes_reg_enc_dec_32;
++		des_fun.reg_enc = des_reg_enc_dec_32;
++		des_fun.reg_dec = des_reg_enc_dec_32;
++	}
++
++	if (pinfo->cap_md5_sha1) {
++		md5_sha1_fun.wdata = (void*)md5_sha1_write64;
++		md5_sha1_fun.rdata = (void*)md5_sha1_read64;
++
++		if ((errCode = crypto_register_shash(&sha1_alg))) {
++			dev_err(&pdev->dev, "reigster sha1_alg  failed.\n");
++			goto crypto_errCode_free_md5_sha1_irq;
++		}
++		if ((errCode = crypto_register_shash(&md5_alg))) {
++			dev_err(&pdev->dev, "reigster md5_alg  failed.\n");
++			goto crypto_errCode_free_sha1;
++		}
++	}
++
++	if ((errCode = crypto_register_alg(&des_alg))) {
++		dev_err(&pdev->dev, "reigster des_alg failed.\n");
++		goto crypto_errCode_free_md5;
++	}
++
++	dev_notice(&pdev->dev,"%s probed(%s mode).\n", ambdev_name,
++		config_polling_mode ? "polling" : "interrupt");
++
++	return 0;
++
++crypto_errCode_free_md5:
++	if (pinfo->cap_md5_sha1)
++		crypto_unregister_shash(&md5_alg);
++
++crypto_errCode_free_sha1:
++	if (pinfo->cap_md5_sha1)
++		crypto_unregister_shash(&sha1_alg);
++
++crypto_errCode_free_md5_sha1_irq:
++	if(unlikely(config_polling_mode == 0)){
++		destroy_workqueue(handle_queue);
++		crypto_unregister_alg(&ecb_aes_alg);
++	}else{
++		crypto_unregister_alg(&aes_alg);
++	}
++
++	return errCode;
++}
++
++static int ambarella_crypto_remove(struct platform_device *pdev)
++{
++	struct ambarella_crypto_info *pinfo;
++	int errCode = 0;
++
++	pinfo = platform_get_drvdata(pdev);
++
++	if (pinfo->cap_md5_sha1) {
++		crypto_unregister_shash(&sha1_alg);
++		crypto_unregister_shash(&md5_alg);
++	}
++	crypto_unregister_alg(&des_alg);
++
++	if (config_polling_mode == 0) {
++		destroy_workqueue(handle_queue);
++		crypto_unregister_alg(&ecb_aes_alg);
++
++		platform_set_drvdata(pdev, NULL);
++	} else {
++		crypto_unregister_alg(&aes_alg);
++	}
++
++	dev_notice(&pdev->dev, "%s removed.\n", ambdev_name);
++
++	return errCode;
++}
++
++static const struct of_device_id ambarella_crypto_dt_ids[] = {
++	{.compatible = "ambarella,crypto", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_crypto_dt_ids);
++
++static struct platform_driver ambarella_crypto_driver = {
++	.probe		= ambarella_crypto_probe,
++	.remove		= ambarella_crypto_remove,
++#ifdef CONFIG_PM
++	.suspend	= NULL,
++	.resume		= NULL,
++#endif
++	.driver		= {
++		.name	= "ambarella-crypto",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_crypto_dt_ids,
++	},
++};
++
++module_platform_driver(ambarella_crypto_driver);
++
++MODULE_DESCRIPTION("Ambarella Cryptography Engine");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Qiao Wang");
++MODULE_ALIAS("crypo-all");
++
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+index 0ba5a951..4933aa6a 100644
+--- a/drivers/dma/Kconfig
++++ b/drivers/dma/Kconfig
+@@ -312,6 +312,17 @@ config MMP_PDMA
+ 	help
+ 	  Support the MMP PDMA engine for PXA and MMP platfrom.
+ 
++config AMBARELLA_DMA
++	tristate "Ambarella DMA Engine System support"
++	depends on PLAT_AMBARELLA
++	select DMA_ENGINE
++	help
++	  Support the Ambarella DMA Engine. This engine is integrated into
++	  Ambarella chip.
++
++	  Say Y here if you have such a chipest.
++	  If unsure,say N.
++
+ config DMA_ENGINE
+ 	bool
+ 
+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
+index a2b0df59..613c2d4c 100644
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -38,3 +38,4 @@ obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
+ obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
+ obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+ obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
++obj-$(CONFIG_AMBARELLA_DMA) += ambarella_dma.o
+diff --git a/drivers/dma/ambarella_dma.c b/drivers/dma/ambarella_dma.c
+new file mode 100644
+index 00000000..21d04852
+--- /dev/null
++++ b/drivers/dma/ambarella_dma.c
+@@ -0,0 +1,1337 @@
++/*
++ * drivers/dma/ambarella_dma.c  --  Ambarella DMA engine driver
++ *
++ * History:
++ *	2012/05/10 - Ken He <jianhe@ambarella.com> created file
++ *
++ * Coryright (c) 2008-2012, Ambarella, Inc.
++ * http://www.ambarella.com
++ *
++ * 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.
++*/
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/device.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <linux/delay.h>
++#include <linux/of.h>
++#include <linux/of_dma.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <mach/hardware.h>
++#include <plat/dma.h>
++#include <plat/rct.h>
++#include "dmaengine.h"
++#include "ambarella_dma.h"
++
++int ambarella_dma_channel_id(void *chan)
++{
++	return to_ambdma_chan((struct dma_chan *)chan)->id;
++}
++EXPORT_SYMBOL(ambarella_dma_channel_id);
++
++static int ambdma_proc_show(struct seq_file *m, void *v)
++{
++	struct ambdma_device *amb_dma = m->private;
++	struct ambdma_chan *amb_chan;
++	const char *sw_status;
++	const char *hw_status;
++	int i, len = 0;
++
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		amb_chan = &amb_dma->amb_chan[i];
++
++		switch(amb_chan->status) {
++		case AMBDMA_STATUS_IDLE:
++			sw_status = "idle";
++			break;
++		case AMBDMA_STATUS_BUSY:
++			sw_status = "busy";
++			break;
++		case AMBDMA_STATUS_STOPPING:
++			sw_status = "stopping";
++			break;
++		default:
++			sw_status = "unknown";
++			break;
++		}
++
++		if (ambdma_chan_is_enabled(amb_chan))
++			hw_status = "running";
++		else
++			hw_status = "stopped";
++
++		len += seq_printf(m, "channel %d:   %s, %d, %s, %s\n",
++			amb_chan->id, dma_chan_name(&amb_chan->chan),
++			amb_chan->chan.client_count, sw_status, hw_status);
++	}
++
++	len += seq_printf(m, "\nInput channel ID to stop specific dma channel:\n");
++	len += seq_printf(m, "    example: echo 3 > dma\n\n");
++
++	return len;
++}
++
++static int ambdma_proc_write(struct file *file,
++	const char __user *buffer, size_t count, loff_t *ppos)
++{
++	struct ambdma_device *amb_dma = PDE_DATA(file_inode(file));
++	int id, ret;
++
++	ret = kstrtouint_from_user(buffer, count, 0, &id);
++	if (ret)
++		return ret;
++
++	if (id >= NUM_DMA_CHANNELS) {
++		printk("Invalid channel id\n");
++		return -EINVAL;
++	}
++
++	dmaengine_terminate_all(&amb_dma->amb_chan[id].chan);
++
++	return count;
++}
++
++static int ambdma_proc_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, ambdma_proc_show, PDE_DATA(inode));
++}
++
++static const struct file_operations proc_ambdma_fops = {
++	.open = ambdma_proc_open,
++	.read = seq_read,
++	.llseek = seq_lseek,
++	.write = ambdma_proc_write,
++};
++
++static struct ambdma_desc *ambdma_alloc_desc(struct dma_chan *chan, gfp_t gfp_flags)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++	struct ambdma_desc *amb_desc = NULL;
++	dma_addr_t phys;
++
++	amb_desc = kzalloc(sizeof(struct ambdma_desc), gfp_flags);
++	if (!amb_desc)
++		return NULL;
++
++	amb_desc->lli = dma_pool_alloc(amb_dma->lli_pool, gfp_flags, &phys);
++	if (!amb_desc->lli) {
++		kfree(amb_desc);
++		return NULL;
++	}
++
++	INIT_LIST_HEAD(&amb_desc->tx_list);
++	dma_async_tx_descriptor_init(&amb_desc->txd, chan);
++	/* txd.flags will be overwritten in prep functions */
++	amb_desc->txd.flags = DMA_CTRL_ACK;
++	amb_desc->txd.tx_submit = ambdma_tx_submit;
++	amb_desc->txd.phys = phys;
++	amb_desc->is_cyclic = 0;
++
++	return amb_desc;
++}
++
++static void ambdma_free_desc(struct dma_chan *chan, struct ambdma_desc *amb_desc)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++
++	dma_pool_free(amb_dma->lli_pool, amb_desc->lli, amb_desc->txd.phys);
++	kfree(amb_desc);
++}
++
++static struct ambdma_desc *ambdma_get_desc(struct ambdma_chan *amb_chan)
++{
++	struct ambdma_desc *desc, *_desc;
++	struct ambdma_desc *ret = NULL;
++	unsigned long flags;
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++	list_for_each_entry_safe(desc, _desc, &amb_chan->free_list, desc_node) {
++		if (async_tx_test_ack(&desc->txd)) {
++			list_del_init(&desc->desc_node);
++			ret = desc;
++			break;
++		}
++	}
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++
++	/* no more descriptor available in initial pool: create one more */
++	if (!ret) {
++		ret = ambdma_alloc_desc(&amb_chan->chan, GFP_ATOMIC);
++		if (ret) {
++			spin_lock_irqsave(&amb_chan->lock, flags);
++			amb_chan->descs_allocated++;
++			spin_unlock_irqrestore(&amb_chan->lock, flags);
++		} else {
++			pr_err("%s: no more descriptors available\n", __func__);
++		}
++	}
++
++	return ret;
++}
++
++
++static void ambdma_put_desc(struct ambdma_chan *amb_chan,
++		struct ambdma_desc *amb_desc)
++{
++	unsigned long flags;
++
++	if (amb_desc) {
++		spin_lock_irqsave(&amb_chan->lock, flags);
++		list_splice_init(&amb_desc->tx_list, &amb_chan->free_list);
++		list_add_tail(&amb_desc->desc_node, &amb_chan->free_list);
++		spin_unlock_irqrestore(&amb_chan->lock, flags);
++	}
++}
++
++static void ambdma_return_desc(struct ambdma_chan *amb_chan,
++		struct ambdma_desc *amb_desc)
++{
++	/* move children to free_list */
++	list_splice_init(&amb_desc->tx_list, &amb_chan->free_list);
++	/* move myself to free_list */
++	list_move_tail(&amb_desc->desc_node, &amb_chan->free_list);
++
++}
++
++static void ambdma_chain_complete(struct ambdma_chan *amb_chan,
++		struct ambdma_desc *amb_desc)
++{
++	struct dma_async_tx_descriptor	*txd = &amb_desc->txd;
++
++	dma_cookie_complete(txd);
++
++	ambdma_return_desc(amb_chan, amb_desc);
++
++	spin_unlock(&amb_chan->lock);
++	if (txd->callback && (txd->flags & DMA_PREP_INTERRUPT))
++		txd->callback(txd->callback_param);
++	spin_lock(&amb_chan->lock);
++
++	dma_run_dependencies(txd);
++}
++
++
++static void ambdma_complete_all(struct ambdma_chan *amb_chan)
++{
++	struct ambdma_desc *amb_desc, *_desc;
++	LIST_HEAD(list);
++
++	list_splice_init(&amb_chan->active_list, &list);
++
++	/* submit queued descriptors ASAP, i.e. before we go through
++	 * the completed ones. */
++	if (!list_empty(&amb_chan->queue)) {
++		list_splice_init(&amb_chan->queue, &amb_chan->active_list);
++		ambdma_dostart(amb_chan, ambdma_first_active(amb_chan));
++	}
++
++	list_for_each_entry_safe(amb_desc, _desc, &list, desc_node)
++		ambdma_chain_complete(amb_chan, amb_desc);
++}
++
++static void ambdma_advance_work(struct ambdma_chan *amb_chan)
++{
++	if (list_empty(&amb_chan->active_list) || list_is_singular(&amb_chan->active_list)) {
++		ambdma_complete_all(amb_chan);
++	} else {
++		ambdma_chain_complete(amb_chan, ambdma_first_active(amb_chan));
++		/* active_list has been updated by ambdma_chain_complete(),
++		 * so ambdma_first_active() will get another amb_desc. */
++		ambdma_dostart(amb_chan, ambdma_first_active(amb_chan));
++	}
++}
++
++static void ambdma_handle_error(struct ambdma_chan *amb_chan,
++		struct ambdma_desc *bad_desc)
++{
++	list_del_init(&bad_desc->desc_node);
++
++	/* try to submit queued descriptors to restart dma */
++	list_splice_init(&amb_chan->queue, amb_chan->active_list.prev);
++	if (!list_empty(&amb_chan->active_list))
++		ambdma_dostart(amb_chan, ambdma_first_active(amb_chan));
++
++	pr_crit("%s: DMA error on channel %d: 0x%08x\n",
++		__func__, amb_chan->id, bad_desc->lli->rpt);
++
++	/* pretend the descriptor completed successfully */
++	ambdma_chain_complete(amb_chan, bad_desc);
++}
++
++static void ambdma_tasklet(unsigned long data)
++{
++	struct ambdma_chan *amb_chan = (struct ambdma_chan *)data;
++	struct ambdma_desc *amb_desc = NULL;
++	enum ambdma_status old_status;
++	unsigned long flags;
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++
++	old_status = amb_chan->status;
++	if (!ambdma_chan_is_enabled(amb_chan)) {
++		amb_chan->status = AMBDMA_STATUS_IDLE;
++		if (!list_empty(&amb_chan->stopping_list))
++			ambdma_return_desc(amb_chan, ambdma_first_stopping(amb_chan));
++	}
++
++	/* someone might have called terminate all */
++	if (list_empty(&amb_chan->active_list))
++		goto tasklet_out;
++
++	/* note: if the DMA channel is stopped by DMA_TERMINATE_ALL rather
++	 * than naturally end, then ambdma_first_active() will return the next
++	 * descriptor that need to be started, but not the descriptor that
++	 * invoke this tasklet (IRQ) */
++	amb_desc = ambdma_first_active(amb_chan);
++
++	if (!amb_desc->is_cyclic && amb_chan->status != AMBDMA_STATUS_IDLE) {
++		pr_err("%s: channel(%d) invalid status\n", __func__, amb_chan->id);
++		goto tasklet_out;
++	}
++
++	if (old_status == AMBDMA_STATUS_BUSY) {
++		/* the IRQ is triggered by DMA stopping naturally or by errors.*/
++		if (ambdma_desc_is_error(amb_desc)) {
++			ambdma_handle_error(amb_chan, amb_desc);
++		} else if (amb_desc->is_cyclic) {
++			spin_unlock(&amb_chan->lock);
++			if (amb_desc->txd.callback)
++				amb_desc->txd.callback(amb_desc->txd.callback_param);
++			spin_lock(&amb_chan->lock);
++		} else {
++			ambdma_advance_work(amb_chan);
++		}
++	} else if (old_status == AMBDMA_STATUS_STOPPING) {
++		/* the DMA channel is stopped by DMA_TERMINATE_ALL.  */
++		ambdma_dostart(amb_chan, amb_desc);
++	}
++
++tasklet_out:
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++}
++
++static irqreturn_t ambdma_dma_irq_handler(int irq, void *dev_data)
++{
++	struct ambdma_device *amb_dma = dev_data;
++	u32 i, int_src;
++	irqreturn_t ret = IRQ_NONE;
++
++	int_src = amba_readl(DMA_REG(DMA_INT_OFFSET));
++
++	if (int_src == 0)
++		return IRQ_HANDLED;
++
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		spin_lock(&amb_dma->amb_chan[i].lock);
++		if (int_src & (1 << i)) {
++			amba_writel(DMA_CHAN_STA_REG(i), 0);
++			tasklet_schedule(&amb_dma->amb_chan[i].tasklet);
++			ret = IRQ_HANDLED;
++		}
++		spin_unlock(&amb_dma->amb_chan[i].lock);
++	}
++
++	return ret;
++}
++
++static int ambdma_stop_channel(struct ambdma_chan *amb_chan)
++{
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++	struct ambdma_desc *first, *amb_desc;
++	int id = amb_chan->id;
++
++	if (amb_chan->status == AMBDMA_STATUS_BUSY) {
++		if (amb_chan->force_stop == 0 || amb_dma->support_prs) {
++			/* if force_stop == 0, the DMA channel is still running
++			 * at this moment. And if the chip doesn't support early
++			 * end, normally there are still two IRQs will be triggered
++			 * untill DMA channel stops. */
++			first = ambdma_first_active(amb_chan);
++			first->lli->attr |= DMA_DESC_EOC;
++			list_for_each_entry(amb_desc, &first->tx_list, desc_node) {
++				amb_desc->lli->attr |= DMA_DESC_EOC;
++			}
++			amb_chan->status = AMBDMA_STATUS_STOPPING;
++			/* active_list is still being used by DMA controller,
++			 * so move it to stopping_list to avoid being
++			 * initialized by next transfer */
++			list_move_tail(&first->desc_node, &amb_chan->stopping_list);
++
++			if (amb_dma->support_prs)
++				amba_setbitsl(DMA_REG(DMA_EARLY_END_OFFSET), 0x1 << id);
++		} else {
++			/* Disable DMA: this sequence is not mentioned at APM.*/
++			amba_writel(DMA_CHAN_STA_REG(id), DMA_CHANX_STA_OD);
++			amba_writel(DMA_CHAN_DA_REG(id), amb_dma->dummy_lli_phys);
++			amba_writel(DMA_CHAN_CTR_REG(id),
++				DMA_CHANX_CTR_WM | DMA_CHANX_CTR_NI);
++			udelay(1);
++			/* avoid to trigger dummy IRQ.*/
++			amba_writel(DMA_CHAN_STA_REG(id), 0x0);
++			amb_chan->force_stop = 0;
++			if (ambdma_chan_is_enabled(amb_chan)) {
++				pr_err("%s: stop dma channel(%d) failed\n",
++					__func__, id);
++				return -EIO;
++			}
++			amb_chan->status = AMBDMA_STATUS_IDLE;
++		}
++	}
++
++	return 0;
++}
++
++static int ambdma_pause_channel(struct ambdma_chan *amb_chan)
++{
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++
++	if (!amb_dma->support_prs)
++		return -ENXIO;
++
++	amba_setbitsl(DMA_REG(DMA_PAUSE_SET_OFFSET), 1 << amb_chan->id);
++
++	return 0;
++}
++
++static int ambdma_resume_channel(struct ambdma_chan *amb_chan)
++{
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++
++	if (!amb_dma->support_prs)
++		return -ENXIO;
++
++	amba_setbitsl(DMA_REG(DMA_PAUSE_CLR_OFFSET), 1 << amb_chan->id);
++
++	return 0;
++}
++
++static void ambdma_dostart(struct ambdma_chan *amb_chan, struct ambdma_desc *first)
++{
++	int id = amb_chan->id;
++
++	/* if DMA channel is not idle right now, the DMA descriptor
++	 * will be started at ambdma_tasklet(). */
++	if (amb_chan->status > AMBDMA_STATUS_IDLE)
++		return;
++
++	if (ambdma_chan_is_enabled(amb_chan)) {
++		pr_err("%s: channel(%d) should be idle here\n", __func__, id);
++		return;
++	}
++
++	amba_writel(DMA_CHAN_STA_REG(id), 0x0);
++	amba_writel(DMA_CHAN_DA_REG(id), first->txd.phys);
++	amba_writel(DMA_CHAN_CTR_REG(id), DMA_CHANX_CTR_EN | DMA_CHANX_CTR_D);
++	amb_chan->status = AMBDMA_STATUS_BUSY;
++}
++
++static dma_cookie_t ambdma_tx_submit(struct dma_async_tx_descriptor *tx)
++{
++	struct ambdma_desc *amb_desc;
++	struct ambdma_chan *amb_chan;
++	dma_cookie_t cookie;
++	unsigned long flags;
++
++	amb_desc = to_ambdma_desc(tx);
++	amb_chan = to_ambdma_chan(tx->chan);
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++
++	cookie = dma_cookie_assign(tx);
++
++	if (list_empty(&amb_chan->active_list)) {
++		list_add_tail(&amb_desc->desc_node, &amb_chan->active_list);
++		ambdma_dostart(amb_chan, amb_desc);
++	} else {
++		list_add_tail(&amb_desc->desc_node, &amb_chan->queue);
++	}
++
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++
++	return cookie;
++}
++
++/* DMA Engine API begin */
++static int ambdma_alloc_chan_resources(struct dma_chan *chan)
++{
++	struct ambdma_chan *amb_chan;
++	struct ambdma_desc *amb_desc;
++	LIST_HEAD(tmp_list);
++	unsigned long flags;
++	int i;
++
++	amb_chan = to_ambdma_chan(chan);
++
++	if (amb_chan->status == AMBDMA_STATUS_BUSY) {
++		pr_err("%s: channel(%d) not idle!\n", __func__, amb_chan->id);
++		return -EIO;
++	}
++
++	/* Alloc descriptors for this channel */
++	for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) {
++		amb_desc = ambdma_alloc_desc(chan, GFP_KERNEL);
++		if (amb_desc == NULL) {
++			struct ambdma_desc *d, *_d;
++			list_for_each_entry_safe(d, _d, &tmp_list, desc_node) {
++				ambdma_free_desc(chan, d);
++			}
++			pr_err("%s: failed to allocate descriptor\n", __func__);
++			return -ENOMEM;
++		}
++
++		list_add_tail(&amb_desc->desc_node, &tmp_list);
++	}
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++	amb_chan->descs_allocated = i;
++	list_splice_init(&tmp_list, &amb_chan->free_list);
++	dma_cookie_init(chan);
++	amb_chan->force_stop = 0;
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++
++	return amb_chan->descs_allocated;
++}
++
++static void ambdma_free_chan_resources(struct dma_chan *chan)
++{
++	struct ambdma_chan *amb_chan;
++	struct ambdma_desc *amb_desc, *_desc;
++	LIST_HEAD(list);
++	unsigned long flags;
++
++	amb_chan = to_ambdma_chan(chan);
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++	BUG_ON(!list_empty(&amb_chan->active_list));
++	BUG_ON(!list_empty(&amb_chan->queue));
++	BUG_ON(amb_chan->status == AMBDMA_STATUS_BUSY);
++
++	list_splice_init(&amb_chan->free_list, &list);
++	amb_chan->descs_allocated = 0;
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++
++	list_for_each_entry_safe(amb_desc, _desc, &list, desc_node)
++		ambdma_free_desc(chan, amb_desc);
++}
++
++/* If this function is called when the dma channel is transferring data,
++ * you may get inaccuracy result. */
++static u32 ambdma_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct ambdma_desc *first = NULL, *amb_desc;
++	unsigned long flags;
++	u32 count = 0;
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++
++	/* according to the cookie, find amb_desc in active_list. */
++	if (!list_empty(&amb_chan->active_list)) {
++		amb_desc = ambdma_first_active(amb_chan);
++		if (amb_desc->txd.cookie == cookie)
++			first = amb_desc;
++	}
++
++	/* if it's in active list, we should get the count for non-completed
++	 * desc from the dma channel status register, and get the count for
++	 * completed desc from the "rpt" field in desc. */
++	if (first) {
++		count = amba_readl(DMA_CHAN_STA_REG(amb_chan->id));
++		count &= AMBARELLA_DMA_MAX_LENGTH;
++
++		count += ambdma_desc_transfer_count(first);
++		if (!list_empty(&first->tx_list)) {
++			list_for_each_entry(amb_desc, &first->tx_list, desc_node) {
++				count += ambdma_desc_transfer_count(amb_desc);
++			}
++		}
++	} else if (!list_empty(&amb_chan->queue)) {
++		/* if it's in queue list, all of the desc have not been started,
++		 * so the transferred count is always 0.  */
++		list_for_each_entry(amb_desc, &amb_chan->queue, desc_node) {
++			if (amb_desc->txd.cookie == cookie) {
++				first = amb_desc;
++				count = 0;
++				break;
++			}
++		}
++	}
++
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++
++	BUG_ON(!first);
++
++	return first->len - count;
++}
++
++static enum dma_status ambdma_tx_status(struct dma_chan *chan,
++		dma_cookie_t cookie, struct dma_tx_state *txstate)
++{
++	enum dma_status ret;
++
++	ret = dma_cookie_status(chan, cookie, txstate);
++	if (ret != DMA_SUCCESS)
++		dma_set_residue(txstate, ambdma_get_bytes_left(chan, cookie));
++
++	return ret;
++}
++
++static void ambdma_issue_pending(struct dma_chan *chan)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	unsigned long flags;
++
++	spin_lock_irqsave(&amb_chan->lock, flags);
++
++	/* if dma channel is not idle, will active queue list in tasklet. */
++	if (amb_chan->status == AMBDMA_STATUS_IDLE) {
++		if (!list_empty(&amb_chan->active_list))
++			pr_err("%s: active_list should be empty here\n", __func__);
++		else
++			ambdma_advance_work(amb_chan);
++	}
++
++	spin_unlock_irqrestore(&amb_chan->lock, flags);
++}
++
++static int ambdma_device_control(struct dma_chan *chan,
++		enum dma_ctrl_cmd cmd, 	unsigned long arg)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct dma_slave_config *config = (void *)arg;
++	enum dma_slave_buswidth width = 0;
++	int ret = 0, maxburst;
++	struct ambdma_desc *amb_desc, *_desc;
++	LIST_HEAD(list);
++	unsigned long flags;
++
++	switch (cmd) {
++	case DMA_TERMINATE_ALL:
++		spin_lock_irqsave(&amb_chan->lock, flags);
++		ambdma_stop_channel(amb_chan);
++
++		/* active_list entries will end up before queued entries */
++		list_splice_init(&amb_chan->queue, &list);
++		list_splice_init(&amb_chan->active_list, &list);
++
++		/* Flush all pending and queued descriptors */
++		list_for_each_entry_safe(amb_desc, _desc, &list, desc_node) {
++			/* move children to free_list */
++			list_splice_init(&amb_desc->tx_list, &amb_chan->free_list);
++			/* move myself to free_list */
++			list_move_tail(&amb_desc->desc_node, &amb_chan->free_list);
++		}
++		spin_unlock_irqrestore(&amb_chan->lock, flags);
++
++		break;
++	case DMA_SLAVE_CONFIG:
++		/* We only support mem to dev or dev to mem transfers */
++		switch (config->direction) {
++		case DMA_MEM_TO_DEV:
++			width = config->dst_addr_width;
++			maxburst = config->dst_maxburst;
++			amb_chan->rt_addr = config->dst_addr;
++			amb_chan->rt_attr = DMA_DESC_RM | DMA_DESC_NI |
++					DMA_DESC_IE | DMA_DESC_ST;
++			break;
++		case DMA_DEV_TO_MEM:
++			width = config->src_addr_width;
++			maxburst = config->src_maxburst;
++			amb_chan->rt_addr = config->src_addr;
++			amb_chan->rt_attr = DMA_DESC_WM | DMA_DESC_NI |
++					DMA_DESC_IE | DMA_DESC_ST;
++			break;
++		default:
++			return -ENXIO;
++		}
++
++		/* bus width for descriptor mode control_info [ts fileds] */
++		switch (width) {
++		case DMA_SLAVE_BUSWIDTH_8_BYTES:
++			amb_chan->rt_attr |= DMA_DESC_TS_8B;
++			break;
++		case DMA_SLAVE_BUSWIDTH_4_BYTES:
++			amb_chan->rt_attr |= DMA_DESC_TS_4B;
++			break;
++		case DMA_SLAVE_BUSWIDTH_2_BYTES:
++			amb_chan->rt_attr |= DMA_DESC_TS_2B;
++			break;
++		case DMA_SLAVE_BUSWIDTH_1_BYTE:
++			amb_chan->rt_attr |= DMA_DESC_TS_1B;
++			break;
++		default:
++			break;
++		}
++
++		/* burst for descriptor mode control_info [blk fileds] */
++		switch (maxburst) {
++		case 1024:
++			amb_chan->rt_attr |= DMA_DESC_BLK_1024B;
++			break;
++		case 512:
++			amb_chan->rt_attr |= DMA_DESC_BLK_512B;
++			break;
++		case 256:
++			amb_chan->rt_attr |= DMA_DESC_BLK_256B;
++			break;
++		case 128:
++			amb_chan->rt_attr |= DMA_DESC_BLK_128B;
++			break;
++		case 64:
++			amb_chan->rt_attr |= DMA_DESC_BLK_64B;
++			break;
++		case 32:
++			amb_chan->rt_attr |= DMA_DESC_BLK_32B;
++			break;
++		case 16:
++			amb_chan->rt_attr |= DMA_DESC_BLK_16B;
++			break;
++		case 8:
++			amb_chan->rt_attr |= DMA_DESC_BLK_8B;
++			break;
++		default:
++			break;
++		}
++
++		break;
++	case DMA_PAUSE:
++		spin_lock_irqsave(&amb_chan->lock, flags);
++		ret = ambdma_pause_channel(amb_chan);
++		spin_unlock_irqrestore(&amb_chan->lock, flags);
++		break;
++	case DMA_RESUME:
++		spin_lock_irqsave(&amb_chan->lock, flags);
++		ret = ambdma_resume_channel(amb_chan);
++		spin_unlock_irqrestore(&amb_chan->lock, flags);
++		break;
++	default:
++		ret = -ENXIO;
++	}
++
++	return ret;
++}
++
++static struct dma_async_tx_descriptor *ambdma_prep_dma_cyclic(
++		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
++		size_t period_len, enum dma_transfer_direction direction,
++		unsigned long flags, void *context)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++	struct ambdma_desc *amb_desc, *first = NULL, *prev = NULL;
++	int left_len = buf_len;
++
++	if (buf_len == 0 || period_len == 0) {
++		pr_err("%s: buf/period length is zero!\n", __func__);
++		return NULL;
++	}
++
++	if (!IS_ALIGNED(buf_addr, 1<<(amb_dma->copy_align)) ||
++		!IS_ALIGNED(period_len, 1<<(amb_dma->copy_align))) {
++		pr_err("%s: buf_addr/period_len is not %dbytes aligned! (%d,%d)\n",
++			__func__, 1<<(amb_dma->copy_align), buf_addr, period_len);
++		return NULL;
++	}
++
++	do {
++		amb_desc = ambdma_get_desc(amb_chan);
++		if (!amb_desc)
++			goto dma_cyclic_err;
++
++		amb_desc->is_cyclic = 1;
++
++		if (period_len > left_len)
++			period_len = left_len;
++
++		if (direction == DMA_MEM_TO_DEV) {
++			amb_desc->lli->src = buf_addr;
++			amb_desc->lli->dst = amb_chan->rt_addr;
++		} else if (direction == DMA_DEV_TO_MEM) {
++			amb_desc->lli->src = amb_chan->rt_addr;
++			amb_desc->lli->dst = buf_addr;
++		} else {
++			goto dma_cyclic_err;
++		}
++		/* trigger interrupt after each dma transaction ends. */
++		amb_desc->lli->attr = amb_chan->rt_attr | DMA_DESC_ID;
++		amb_desc->lli->xfr_count = period_len;
++		/* rpt_addr points to amb_desc->lli->rpt */
++		amb_desc->lli->rpt_addr =
++			amb_desc->txd.phys + sizeof(struct ambdma_lli) - 4;
++		/* here we initialize rpt to 0 */
++		amb_desc->lli->rpt = 0;
++
++		if (first == NULL)
++			first = amb_desc;
++		else {
++			prev->lli->next_desc = amb_desc->txd.phys;
++			list_add_tail(&amb_desc->desc_node, &first->tx_list);
++		}
++
++		prev = amb_desc;
++
++		left_len -= period_len;
++		buf_addr += period_len;
++
++		/* our dma controller can't transfer data larger than 4M Bytes,
++		 * but it seems that no use case will transfer so large data,
++		 * so we just trigger a BUG here for reminder. */
++		BUG_ON(amb_desc->lli->xfr_count > AMBARELLA_DMA_MAX_LENGTH);
++	} while (left_len > 0);
++
++	/* lets make a cyclic list */
++	amb_desc->lli->next_desc = first->txd.phys;
++
++	/* First descriptor of the chain embedds additional information */
++	first->txd.cookie = -EBUSY;
++	first->len = buf_len;
++
++	return &first->txd;
++
++dma_cyclic_err:
++	dev_err(&chan->dev->device, "prep_dma_cyclic error: %p\n", amb_desc);
++	ambdma_put_desc(amb_chan, first);
++	return NULL;
++}
++
++
++static struct dma_async_tx_descriptor *ambdma_prep_slave_sg(
++		struct dma_chan *chan, struct scatterlist *sgl,
++		unsigned int sg_len, enum dma_transfer_direction direction,
++		unsigned long flags, void *context)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct ambdma_desc *amb_desc, *first = NULL, *prev = NULL;
++	struct scatterlist *sgent;
++	size_t total_len = 0;
++	unsigned i = 0;
++
++	if (sg_len == 0) {
++		pr_err("%s: sg length is zero!\n", __func__);
++		return NULL;
++	}
++
++	for_each_sg(sgl, sgent, sg_len, i) {
++		amb_desc = ambdma_get_desc(amb_chan);
++		if (!amb_desc)
++			goto slave_sg_err;
++
++		amb_desc->is_cyclic = 0;
++
++		if (direction == DMA_MEM_TO_DEV) {
++			amb_desc->lli->src = sg_dma_address(sgent);
++			amb_desc->lli->dst = amb_chan->rt_addr;
++		} else if (direction == DMA_DEV_TO_MEM) {
++			amb_desc->lli->src = amb_chan->rt_addr;
++			amb_desc->lli->dst = sg_dma_address(sgent);
++		} else {
++			goto slave_sg_err;
++		}
++		amb_desc->lli->attr = amb_chan->rt_attr;
++		amb_desc->lli->xfr_count = sg_dma_len(sgent);
++		/* rpt_addr points to amb_desc->lli->rpt */
++		amb_desc->lli->rpt_addr =
++			amb_desc->txd.phys + sizeof(struct ambdma_lli) - 4;
++		/* here we initialize rpt to 0 */
++		amb_desc->lli->rpt = 0;
++
++		if (first == NULL)
++			first = amb_desc;
++		else {
++			prev->lli->next_desc = amb_desc->txd.phys;
++			list_add_tail(&amb_desc->desc_node, &first->tx_list);
++		}
++
++		prev = amb_desc;
++		total_len += amb_desc->lli->xfr_count;
++
++		/* our dma controller can't transfer data larger than 4M Bytes,
++		 * but it seems that no use case will transfer so large data,
++		 * so we just trigger a BUG here for reminder. */
++		BUG_ON(amb_desc->lli->xfr_count > AMBARELLA_DMA_MAX_LENGTH);
++	}
++
++	/* set EOC flag to specify the last descriptor */
++	amb_desc->lli->attr |= DMA_DESC_EOC;
++
++	/* First descriptor of the chain embedds additional information */
++	first->txd.cookie = -EBUSY;
++	first->txd.flags = flags; /* client is in control of this ack */
++	first->len = total_len;
++
++	return &first->txd;
++
++slave_sg_err:
++	dev_err(&chan->dev->device, "prep_slave_sg error: %p\n", amb_desc);
++	ambdma_put_desc(amb_chan, first);
++	return NULL;
++}
++
++static struct dma_async_tx_descriptor *ambdma_prep_dma_memcpy(
++		struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
++		size_t len, unsigned long flags)
++{
++	struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	struct ambdma_device *amb_dma = amb_chan->amb_dma;
++	struct ambdma_desc *amb_desc = NULL, *first = NULL, *prev = NULL;
++	size_t left_len = len, xfer_count;
++
++	if (unlikely(!len)) {
++		pr_info("%s: length is zero!\n", __func__);
++		return NULL;
++	}
++
++	if (!IS_ALIGNED(dst, 1<<(amb_dma->copy_align)) ||
++		!IS_ALIGNED(src, 1<<(amb_dma->copy_align))) {
++		pr_err("%s: dst/src is not %dbytes aligned! (%d,%d)\n",
++			__func__, 1<<(amb_dma->copy_align), dst, src);
++		return NULL;
++	}
++
++	do{
++		amb_desc = ambdma_get_desc(amb_chan);
++		if (!amb_desc)
++			goto dma_memcpy_err;
++
++		amb_desc->is_cyclic = 0;
++
++		amb_desc->lli->src = src;
++		amb_desc->lli->dst = dst;
++		amb_desc->lli->attr = DMA_DESC_RM | DMA_DESC_WM | DMA_DESC_IE |
++				DMA_DESC_ST | DMA_DESC_BLK_32B | DMA_DESC_TS_4B;
++		xfer_count = min(left_len, (size_t)AMBARELLA_DMA_MAX_LENGTH);
++		amb_desc->lli->xfr_count = xfer_count;
++		/* rpt_addr points to amb_desc->lli->rpt */
++		amb_desc->lli->rpt_addr =
++			amb_desc->txd.phys + sizeof(struct ambdma_lli) - 4;
++		/* here we initialize rpt to 0 */
++		amb_desc->lli->rpt = 0;
++
++		if (first == NULL)
++			first = amb_desc;
++		else {
++			prev->lli->next_desc = amb_desc->txd.phys;
++			list_add_tail(&amb_desc->desc_node, &first->tx_list);
++		}
++
++		prev = amb_desc;
++
++		src += xfer_count;
++		dst += xfer_count;
++		left_len -= xfer_count;
++
++	} while (left_len > 0);
++
++	/* set EOC flag to specify the last descriptor */
++	amb_desc->lli->attr |= DMA_DESC_EOC;
++
++	/* First descriptor of the chain embedds additional information */
++	first->txd.cookie = -EBUSY;
++	first->txd.flags = flags; /* client is in control of this ack */
++	first->len = len;
++
++	return &first->txd;
++
++dma_memcpy_err:
++	dev_err(&chan->dev->device, "prep_dma_memcpy error: %p\n", amb_desc);
++	ambdma_put_desc(amb_chan, first);
++
++	return NULL;
++}
++
++struct amba_dma_filter_param {
++	struct device_node *of_node;
++	unsigned int chan_id;
++	unsigned int dma_type;
++	//unsigned int force_stop;
++};
++
++static bool amba_dma_filter_fn(struct dma_chan *chan, void *fn_param)
++{
++	struct amba_dma_filter_param *param = fn_param;
++	//struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
++	//struct ambdma_device *amb_dma = amb_chan->amb_dma;
++
++	if (chan->chan_id != param->chan_id)
++		return false;
++
++	//amb_chan->chan.private = &param->force_stop;
++	return true;
++}
++
++static struct dma_chan *amb_dma_xlate(struct of_phandle_args *dma_spec,
++			       struct of_dma *ofdma)
++{
++	struct ambdma_device *amb_dma = ofdma->of_dma_data;
++	dma_cap_mask_t mask;
++	struct amba_dma_filter_param param;
++
++	if (dma_spec->args_count != 2)
++		return NULL;
++	if (dma_spec->args[1] == 1)
++		mask = amb_dma->dma_slave.cap_mask;
++	else
++		mask = amb_dma->dma_memcpy.cap_mask;
++
++	param.of_node = ofdma->of_node;
++	param.chan_id = dma_spec->args[0];
++
++	if (param.chan_id >= amb_dma->nr_channels)
++		return NULL;
++
++	return dma_request_channel(mask, amba_dma_filter_fn, &param);
++}
++
++static int ambarella_dma_probe(struct platform_device *pdev)
++{
++	struct ambdma_device *amb_dma;
++	struct ambdma_chan *amb_chan;
++	struct device_node *np = pdev->dev.of_node;
++	const char *prop_name = "dma-trans-type";
++	int val, i, ret = 0;
++
++	/* alloc the amba dma engine struct */
++	amb_dma = kzalloc(sizeof(*amb_dma), GFP_KERNEL);
++	if (amb_dma == NULL) {
++		ret = -ENOMEM;
++		goto ambdma_dma_probe_exit;
++	}
++
++	amb_dma->dma_irq = platform_get_irq(pdev, 0);
++	if (amb_dma->dma_irq < 0) {
++		ret = -EINVAL;
++		goto ambdma_dma_probe_exit1;
++	}
++
++	/* create a pool of consistent memory blocks for hardware descriptors */
++	amb_dma->lli_pool = dma_pool_create("ambdma_lli_pool",
++			&pdev->dev, sizeof(struct ambdma_lli), 16, 0);
++	if (!amb_dma->lli_pool) {
++		dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
++		ret = -ENOMEM;
++		goto ambdma_dma_probe_exit1;
++	}
++
++	/* alloc dummy_lli and dummy_data for terminate usage. */
++	amb_dma->dummy_lli = dma_pool_alloc(amb_dma->lli_pool,
++			GFP_KERNEL, &amb_dma->dummy_lli_phys);
++	if (amb_dma->dummy_lli == NULL) {
++		ret = -ENOMEM;
++		goto ambdma_dma_probe_exit2;
++	}
++
++	amb_dma->dummy_data = dma_pool_alloc(amb_dma->lli_pool,
++			GFP_KERNEL, &amb_dma->dummy_data_phys);
++	if (amb_dma->dummy_data == NULL) {
++		ret = -ENOMEM;
++		goto ambdma_dma_probe_exit3;
++	}
++
++	amb_dma->dummy_lli->attr = DMA_DESC_EOC | DMA_DESC_WM |
++					DMA_DESC_NI | DMA_DESC_IE |
++					DMA_DESC_ST | DMA_DESC_ID;
++	amb_dma->dummy_lli->next_desc = amb_dma->dummy_lli_phys;
++	amb_dma->dummy_lli->xfr_count = 0;
++	amb_dma->dummy_lli->src = 0;
++	amb_dma->dummy_lli->dst = amb_dma->dummy_data_phys;
++	/* rpt_addr points to ambdma_lli->rpt field */
++	amb_dma->dummy_lli->rpt_addr =
++		amb_dma->dummy_lli_phys + sizeof(struct ambdma_lli) - 4;
++
++	of_property_read_u32(np, "amb,copy-align", &amb_dma->copy_align);
++	amb_dma->support_prs = !!of_find_property(np, "amb,support-prs", NULL);
++	ret = of_property_read_u32(np, "dma-channels", &amb_dma->nr_channels);
++	if (ret) {
++		dev_err(&pdev->dev, "failed to read dma-channels\n");
++		return ret;
++	}
++	ret = of_property_read_u32(np, "dma-requests", &amb_dma->dma_requests);
++	if (ret) {
++		dev_err(&pdev->dev, "failed to read dma-requests\n");
++		return ret;
++	}
++
++	ret = of_property_read_u32_array(np, prop_name, amb_dma->dma_channel_type, amb_dma->nr_channels);
++	if (ret) {
++		dev_err(&pdev->dev, "failed to read dma-trans-type\n");
++		return ret;
++	}
++
++	/* Init dma_device struct */
++	dma_cap_zero(amb_dma->dma_slave.cap_mask);
++	dma_cap_set(DMA_PRIVATE, amb_dma->dma_slave.cap_mask);
++	dma_cap_set(DMA_SLAVE, amb_dma->dma_slave.cap_mask);
++	dma_cap_set(DMA_CYCLIC, amb_dma->dma_slave.cap_mask);
++	INIT_LIST_HEAD(&amb_dma->dma_slave.channels);
++	amb_dma->dma_slave.device_alloc_chan_resources = ambdma_alloc_chan_resources;
++	amb_dma->dma_slave.device_free_chan_resources = ambdma_free_chan_resources;
++	amb_dma->dma_slave.device_tx_status = ambdma_tx_status;
++	amb_dma->dma_slave.device_issue_pending = ambdma_issue_pending;
++	amb_dma->dma_slave.device_prep_dma_cyclic = ambdma_prep_dma_cyclic;
++	amb_dma->dma_slave.device_prep_slave_sg = ambdma_prep_slave_sg;
++	amb_dma->dma_slave.device_control = ambdma_device_control;
++	amb_dma->dma_slave.dev = &pdev->dev;
++
++	dma_cap_zero(amb_dma->dma_memcpy.cap_mask);
++	dma_cap_set(DMA_MEMCPY, amb_dma->dma_memcpy.cap_mask);
++	INIT_LIST_HEAD(&amb_dma->dma_memcpy.channels);
++	amb_dma->dma_memcpy.device_alloc_chan_resources = ambdma_alloc_chan_resources;
++	amb_dma->dma_memcpy.device_free_chan_resources = ambdma_free_chan_resources;
++	amb_dma->dma_memcpy.device_tx_status = ambdma_tx_status;
++	amb_dma->dma_memcpy.device_issue_pending = ambdma_issue_pending;
++	amb_dma->dma_memcpy.device_prep_dma_memcpy = ambdma_prep_dma_memcpy;
++	amb_dma->dma_memcpy.dev = &pdev->dev;
++	amb_dma->dma_memcpy.copy_align = (u8)(amb_dma->copy_align);
++
++	/* init dma_chan struct */
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		amb_chan = &amb_dma->amb_chan[i];
++
++		spin_lock_init(&amb_chan->lock);
++		amb_chan->amb_dma = amb_dma;
++		amb_chan->id = i;
++		amb_chan->status = AMBDMA_STATUS_IDLE;
++		INIT_LIST_HEAD(&amb_chan->active_list);
++		INIT_LIST_HEAD(&amb_chan->queue);
++		INIT_LIST_HEAD(&amb_chan->free_list);
++		INIT_LIST_HEAD(&amb_chan->stopping_list);
++
++		tasklet_init(&amb_chan->tasklet, ambdma_tasklet,
++				(unsigned long)amb_chan);
++		dma_cookie_init(&amb_chan->chan);
++
++		if (amb_dma->dma_channel_type[i] != 0) {
++			amb_chan->chan.device = &amb_dma->dma_slave;
++			list_add_tail(&amb_chan->chan.device_node,
++					&amb_dma->dma_slave.channels);
++		} else {
++			amb_chan->chan.device = &amb_dma->dma_memcpy;
++			list_add_tail(&amb_chan->chan.device_node,
++					&amb_dma->dma_memcpy.channels);
++		}
++	}
++
++#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
++	val = 0;
++	ret = of_property_read_u32_array(np, "dma-channel-sel",
++				amb_dma->dma_channel_sel, amb_dma->nr_channels);
++	if (ret) {
++		dev_err(&pdev->dev, "failed to read dma-channel-sel\n");
++	}
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		if (ret)
++			val |= i << (i * 4);
++		else
++			val |= (amb_dma->dma_channel_sel[i]) << (i * 4);
++	}
++	amba_writel(AHBSP_DMA_CHANNEL_SEL_REG, val);
++#endif
++
++	/* although FIOS DMA has its own driver, we also init FIOS DMA
++	 * status here, orelse dummy FIOS DMA interrupts may occurred
++	 * without its driver installed. */
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		/* I2S_RX_DMA_CHAN and I2S_TX_DMA_CHAN may be used
++		 * for fastboot in Amboot */
++		if ((i == I2S_RX_DMA_CHAN || i == I2S_TX_DMA_CHAN)
++			&& ambdma_chan_is_enabled(&amb_dma->amb_chan[i])) {
++			amb_dma->amb_chan[i].status = AMBDMA_STATUS_BUSY;
++			amb_dma->amb_chan[i].force_stop = 1;
++			continue;
++		}
++
++		amba_writel(DMA_CHAN_STA_REG(i), 0);
++		val = DMA_CHANX_CTR_WM | DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI;
++		amba_writel(DMA_CHAN_CTR_REG(i), val);
++	}
++
++	ret = request_irq(amb_dma->dma_irq, ambdma_dma_irq_handler,
++			IRQF_SHARED | IRQF_TRIGGER_HIGH,
++			dev_name(&pdev->dev), amb_dma);
++	if (ret)
++		goto ambdma_dma_probe_exit4;
++
++	ret = dma_async_device_register(&amb_dma->dma_slave);
++	if (ret) {
++		dev_err(&pdev->dev,
++			"failed to register slave DMA device: %d\n", ret);
++		goto ambdma_dma_probe_exit5;
++	}
++
++	ret = dma_async_device_register(&amb_dma->dma_memcpy);
++	if (ret) {
++		dev_err(&pdev->dev,
++			"failed to register memcpy DMA device: %d\n", ret);
++		goto ambdma_dma_probe_exit6;
++	}
++
++	proc_create_data("dma", S_IRUGO|S_IWUSR,
++		get_ambarella_proc_dir(), &proc_ambdma_fops, amb_dma);
++
++	platform_set_drvdata(pdev, amb_dma);
++
++	if (np) {
++		ret = of_dma_controller_register(np, amb_dma_xlate, amb_dma);
++		if (ret) {
++			dev_err(&pdev->dev,
++				"failed to register controller\n");
++			goto ambdma_dma_probe_exit6;
++		}
++	}
++
++	dev_info(&pdev->dev, "Ambarella DMA Engine \n");
++
++	return 0;
++
++ambdma_dma_probe_exit6:
++	dma_async_device_unregister(&amb_dma->dma_slave);
++
++ambdma_dma_probe_exit5:
++	free_irq(amb_dma->dma_irq, amb_dma);
++
++ambdma_dma_probe_exit4:
++	dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_data,
++			amb_dma->dummy_data_phys);
++
++ambdma_dma_probe_exit3:
++	dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_lli,
++			amb_dma->dummy_lli_phys);
++
++ambdma_dma_probe_exit2:
++	dma_pool_destroy(amb_dma->lli_pool);
++
++ambdma_dma_probe_exit1:
++	kfree(amb_dma);
++
++ambdma_dma_probe_exit:
++	return ret;
++}
++
++static int ambarella_dma_remove(struct platform_device *pdev)
++{
++	struct ambdma_device *amb_dma = platform_get_drvdata(pdev);
++	struct ambdma_chan *amb_chan;
++	int i;
++
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		amb_chan = &amb_dma->amb_chan[i];
++		ambdma_stop_channel(amb_chan);
++
++		tasklet_disable(&amb_chan->tasklet);
++		tasklet_kill(&amb_chan->tasklet);
++	}
++
++	if (pdev->dev.of_node)
++		of_dma_controller_free(pdev->dev.of_node);
++
++	dma_async_device_unregister(&amb_dma->dma_memcpy);
++	dma_async_device_unregister(&amb_dma->dma_slave);
++
++	free_irq(amb_dma->dma_irq, amb_dma);
++	dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_lli,
++			amb_dma->dummy_lli_phys);
++	dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_data,
++			amb_dma->dummy_data_phys);
++	dma_pool_destroy(amb_dma->lli_pool);
++
++	kfree(amb_dma);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
++static u32 ambdma_chan_sel_val = 0;
++#endif
++static int ambarella_dma_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct ambdma_device *amb_dma = platform_get_drvdata(pdev);
++	struct ambdma_chan *amb_chan;
++	int i;
++
++	/* save dma channel register */
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		amb_chan = &amb_dma->amb_chan[i];
++		amb_chan->ch_ctl = amba_readl(DMA_CHAN_CTR_REG(i));
++		amb_chan->ch_da = amba_readl(DMA_CHAN_DA_REG(i));
++		amb_chan->ch_sta = amba_readl(DMA_CHAN_STA_REG(i));
++	}
++#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
++	ambdma_chan_sel_val = amba_readl(AHBSP_DMA_CHANNEL_SEL_REG);
++#endif
++	return 0;
++
++}
++
++static int ambarella_dma_resume(struct platform_device *pdev)
++{
++	struct ambdma_device *amb_dma = platform_get_drvdata(pdev);
++	struct ambdma_chan *amb_chan;
++	int i;
++
++#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
++	amba_writel(AHBSP_DMA_CHANNEL_SEL_REG, ambdma_chan_sel_val);
++#endif
++	/* restore dma channel register */
++	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
++		amb_chan = &amb_dma->amb_chan[i];
++		amba_writel(DMA_CHAN_STA_REG(i), amb_chan->ch_sta);
++		amba_writel(DMA_CHAN_DA_REG(i), amb_chan->ch_da);
++		amba_writel(DMA_CHAN_CTR_REG(i), amb_chan->ch_ctl);
++	}
++
++	return 0;
++}
++#endif
++
++
++static const struct of_device_id ambarella_dma_dt_ids[] = {
++	{.compatible = "ambarella,dma", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_dma_dt_ids);
++
++static struct platform_driver ambarella_dma_driver = {
++	.probe		= ambarella_dma_probe,
++	.remove		= ambarella_dma_remove,
++#ifdef CONFIG_PM
++	.suspend		= ambarella_dma_suspend,
++	.resume		= ambarella_dma_resume,
++#endif
++	.driver		= {
++		.name	= "ambarella-dma",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_dma_dt_ids,
++	},
++};
++
++static int __init ambarella_dma_init(void)
++{
++	return platform_driver_register(&ambarella_dma_driver);
++}
++
++static void __exit ambarella_dma_exit(void)
++{
++	platform_driver_unregister(&ambarella_dma_driver);
++}
++
++subsys_initcall(ambarella_dma_init);
++module_exit(ambarella_dma_exit);
++
++MODULE_DESCRIPTION("Ambarella DMA Engine System Driver");
++MODULE_AUTHOR("Jian He <jianhe@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/dma/ambarella_dma.h b/drivers/dma/ambarella_dma.h
+new file mode 100644
+index 00000000..5c82ba39
+--- /dev/null
++++ b/drivers/dma/ambarella_dma.h
+@@ -0,0 +1,143 @@
++/*
++* linux/drivers/dma/ambarella_dma.h
++*
++* Header file for Ambarella DMA Controller driver
++*
++* History:
++*	2012/07/10 - [Cao Rongrong] created file
++*
++* Copyright (C) 2012 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef _AMBARELLA_DMA_H
++#define _AMBARELLA_DMA_H
++
++#define NR_DESCS_PER_CHANNEL		64
++#define AMBARELLA_DMA_MAX_LENGTH	((1 << 22) - 1)
++
++enum ambdma_status {
++	AMBDMA_STATUS_IDLE = 0,
++	AMBDMA_STATUS_BUSY,
++	AMBDMA_STATUS_STOPPING,
++};
++
++/* lli == Linked List Item; aka DMA buffer descriptor, used by hardware */
++struct ambdma_lli {
++	dma_addr_t			src;
++	dma_addr_t			dst;
++	dma_addr_t			next_desc;
++	dma_addr_t			rpt_addr;
++	u32				xfr_count;
++	u32				attr;
++	u32				rsvd;
++	u32				rpt;
++};
++
++struct ambdma_desc {
++	struct ambdma_lli		*lli;
++
++	struct dma_async_tx_descriptor	txd;
++	struct list_head		tx_list;
++	struct list_head		desc_node;
++	size_t				len;
++	bool				is_cyclic;
++};
++
++struct ambdma_chan {
++	struct dma_chan			chan;
++	struct ambdma_device		*amb_dma;
++	int				id;
++
++	struct tasklet_struct		tasklet;
++	spinlock_t			lock;
++
++	u32				descs_allocated;
++	struct list_head		active_list;
++	struct list_head		queue;
++	struct list_head		free_list;
++	struct list_head		stopping_list;
++
++	dma_addr_t			rt_addr;
++	u32				rt_attr;
++	u32				force_stop;
++	u32				ch_ctl;
++	u32				ch_sta;
++	u32				ch_da;
++	enum ambdma_status		status;
++};
++
++struct ambdma_device {
++	struct dma_device		dma_slave;
++	struct dma_device		dma_memcpy;
++	struct ambdma_chan		amb_chan[NUM_DMA_CHANNELS];
++	struct dma_pool			*lli_pool;
++	int				dma_irq;
++	/* dummy_desc is used to stop DMA immediately. */
++	struct ambdma_lli		*dummy_lli;
++	dma_addr_t			dummy_lli_phys;
++	u32				*dummy_data;
++	dma_addr_t			dummy_data_phys;
++	u32				copy_align;
++	/* support pause/resume/stop */
++	u32				support_prs : 1;
++	u32				nr_channels;
++	u32				dma_requests;
++	u32				dma_channel_type[NUM_DMA_CHANNELS];
++	u32				dma_channel_sel[NUM_DMA_CHANNELS];
++};
++
++
++static inline struct ambdma_desc *to_ambdma_desc(
++	struct dma_async_tx_descriptor *txd)
++{
++	return container_of(txd, struct ambdma_desc, txd);
++}
++
++static inline struct ambdma_desc *ambdma_first_active(
++	struct ambdma_chan *amb_chan)
++{
++	return list_first_entry(&amb_chan->active_list,
++			struct ambdma_desc, desc_node);
++}
++
++static inline struct ambdma_desc *ambdma_first_stopping(
++	struct ambdma_chan *amb_chan)
++{
++	return list_first_entry(&amb_chan->stopping_list,
++			struct ambdma_desc, desc_node);
++}
++
++static inline struct ambdma_chan *to_ambdma_chan(struct dma_chan *chan)
++{
++	return container_of(chan, struct ambdma_chan, chan);
++}
++
++static inline int ambdma_desc_is_error(struct ambdma_desc *amb_desc)
++{
++	return (amb_desc->lli->rpt & (DMA_CHANX_STA_OE | DMA_CHANX_STA_ME |
++			DMA_CHANX_STA_BE | DMA_CHANX_STA_RWE |
++			DMA_CHANX_STA_AE)) != 0x0;
++}
++
++static inline int ambdma_desc_transfer_count(struct ambdma_desc *amb_desc)
++{
++	return amb_desc->lli->rpt & AMBARELLA_DMA_MAX_LENGTH;
++}
++
++static inline int ambdma_chan_is_enabled(struct ambdma_chan *amb_chan)
++{
++	return !!(amba_readl(DMA_CHAN_CTR_REG(amb_chan->id)) & DMA_CHANX_CTR_EN);
++}
++
++static dma_cookie_t ambdma_tx_submit(struct dma_async_tx_descriptor *tx);
++static void ambdma_dostart(struct ambdma_chan *amb_chan,
++		struct ambdma_desc *first);
++
++#endif
++
+diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
+index 0cb2d656..211e979f 100644
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_GPIO_74X164)	+= gpio-74x164.o
+ obj-$(CONFIG_GPIO_ADNP)		+= gpio-adnp.o
+ obj-$(CONFIG_GPIO_ADP5520)	+= gpio-adp5520.o
+ obj-$(CONFIG_GPIO_ADP5588)	+= gpio-adp5588.o
++obj-$(CONFIG_ARCH_AMBARELLA)	+= gpio-ambarella.o
+ obj-$(CONFIG_GPIO_AMD8111)	+= gpio-amd8111.o
+ obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
+ obj-$(CONFIG_GPIO_BT8XX)	+= gpio-bt8xx.o
+diff --git a/drivers/gpio/gpio-ambarella.c b/drivers/gpio/gpio-ambarella.c
+new file mode 100644
+index 00000000..997226ac
+--- /dev/null
++++ b/drivers/gpio/gpio-ambarella.c
+@@ -0,0 +1,646 @@
++/*
++ * drivers/pinctrl/ambarella/pinctrl-amb.c
++ *
++ * History:
++ *	2013/12/18 - [Cao Rongrong] created file
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/gpio.h>
++#include <linux/io.h>
++#include <linux/slab.h>
++#include <linux/syscore_ops.h>
++#include <linux/irqdomain.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <linux/irqchip/chained_irq.h>
++#include <plat/iav_helper.h>
++#include <plat/pinctrl.h>
++
++#if defined(CONFIG_PM)
++struct amb_gpio_regs {
++	u32 irq_wake_mask;
++	u32 data;
++	u32 dir;
++	u32 is;
++	u32 ibe;
++	u32 iev;
++	u32 ie;
++	u32 afsel;
++	u32 mask;
++};
++
++struct amb_gpio_regs amb_gpio_pm[GPIO_INSTANCES];
++#endif
++
++struct amb_gpio_chip {
++	int				irq[GPIO_INSTANCES];
++	void __iomem			*regbase[GPIO_INSTANCES];
++	void __iomem			*iomux_base;
++	struct gpio_chip		*gc;
++	struct irq_domain		*domain;
++	struct ambarella_service	gpio_service;
++};
++
++static int ambarella_gpio_service(void *arg, void *result);
++
++/* gpiolib gpio_request callback function */
++static int amb_gpio_request(struct gpio_chip *gc, unsigned pin)
++{
++	return pinctrl_request_gpio(gc->base + pin);
++}
++
++/* gpiolib gpio_set callback function */
++static void amb_gpio_free(struct gpio_chip *gc, unsigned pin)
++{
++	pinctrl_free_gpio(gc->base + pin);
++}
++
++/* gpiolib gpio_free callback function */
++static void amb_gpio_set(struct gpio_chip *gc, unsigned pin, int value)
++{
++	struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
++	void __iomem *regbase;
++	u32 bank, offset, mask;
++
++	bank = PINID_TO_BANK(pin);
++	offset = PINID_TO_OFFSET(pin);
++	regbase = amb_gpio->regbase[bank];
++	mask = (0x1 << offset);
++
++	amba_writel(regbase + GPIO_MASK_OFFSET, mask);
++	if (value == GPIO_LOW)
++		mask = 0;
++	amba_writel(regbase + GPIO_DATA_OFFSET, mask);
++}
++
++/* gpiolib gpio_get callback function */
++static int amb_gpio_get(struct gpio_chip *gc, unsigned pin)
++{
++	struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
++	void __iomem *regbase;
++	u32 bank, offset, mask, data;
++
++	bank = PINID_TO_BANK(pin);
++	offset = PINID_TO_OFFSET(pin);
++	regbase = amb_gpio->regbase[bank];
++	mask = (0x1 << offset);
++
++	amba_writel(regbase + GPIO_MASK_OFFSET, mask);
++	data = amba_readl(regbase + GPIO_DATA_OFFSET);
++	data = (data >> offset) & 0x1;
++
++	return (data ? GPIO_HIGH : GPIO_LOW);
++}
++
++/* gpiolib gpio_direction_input callback function */
++static int amb_gpio_direction_input(struct gpio_chip *gc, unsigned pin)
++{
++	return pinctrl_gpio_direction_input(gc->base + pin);
++}
++
++/* gpiolib gpio_direction_output callback function */
++static int amb_gpio_direction_output(struct gpio_chip *gc,
++		unsigned pin, int value)
++{
++	int rval;
++
++	rval = pinctrl_gpio_direction_output(gc->base + pin);
++	if (rval < 0)
++		return rval;
++
++	amb_gpio_set(gc, pin, value);
++
++	return 0;
++}
++
++/* gpiolib gpio_to_irq callback function */
++static int amb_gpio_to_irq(struct gpio_chip *gc, unsigned pin)
++{
++	struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
++
++	return irq_create_mapping(amb_gpio->domain, pin);
++}
++
++static void amb_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
++{
++	struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
++	void __iomem *iomux_base = amb_gpio->iomux_base;
++	void __iomem *regbase;
++	u32 afsel = 0, data = 0, dir = 0, mask = 0;
++	u32 iomux0 = 0, iomux1 = 0, iomux2 = 0, alt = 0;
++	u32 i, bank, offset;
++
++	for (i = 0; i < gc->ngpio; i++) {
++		offset = PINID_TO_OFFSET(i);
++		if (offset == 0) {
++			bank = PINID_TO_BANK(i);
++			regbase = amb_gpio->regbase[bank];
++
++			afsel = amba_readl(regbase + GPIO_AFSEL_OFFSET);
++			dir = amba_readl(regbase + GPIO_DIR_OFFSET);
++			mask = amba_readl(regbase + GPIO_MASK_OFFSET);
++			amba_writel(regbase + GPIO_MASK_OFFSET, ~afsel);
++			data = amba_readl(regbase + GPIO_DATA_OFFSET);
++			amba_writel(regbase + GPIO_MASK_OFFSET, mask);
++
++			seq_printf(s, "\nGPIO[%d]:\t[%d - %d]\n",
++				bank, i, i + GPIO_BANK_SIZE - 1);
++			seq_printf(s, "GPIO_BASE:\t0x%08X\n", (u32)regbase);
++			seq_printf(s, "GPIO_AFSEL:\t0x%08X\n", afsel);
++			seq_printf(s, "GPIO_DIR:\t0x%08X\n", dir);
++			seq_printf(s, "GPIO_MASK:\t0x%08X:0x%08X\n", mask, ~afsel);
++			seq_printf(s, "GPIO_DATA:\t0x%08X\n", data);
++
++			if (iomux_base != NULL) {
++				iomux0 = amba_readl(iomux_base + bank * 12);
++				iomux1 = amba_readl(iomux_base + bank * 12 + 4);
++				iomux2 = amba_readl(iomux_base + bank * 12 + 8);
++				seq_printf(s, "IOMUX_REG%d_0:\t0x%08X\n", bank, iomux0);
++				seq_printf(s, "IOMUX_REG%d_1:\t0x%08X\n", bank, iomux1);
++				seq_printf(s, "IOMUX_REG%d_2:\t0x%08X\n", bank, iomux2);
++			}
++		}
++
++		seq_printf(s, " gpio-%-3d", gc->base + i);
++		if (iomux_base != NULL) {
++			alt = ((iomux2 >> offset) & 1) << 2;
++			alt |= ((iomux1 >> offset) & 1) << 1;
++			alt |= ((iomux0 >> offset) & 1) << 0;
++			if (alt != 0)
++				seq_printf(s, " [HW  ] (alt%d)\n", alt);
++			else {
++				const char *label = gpiochip_is_requested(gc, i);
++				label = label ? : "";
++				seq_printf(s, " [GPIO] (%-20.20s) %s %s\n", label,
++					(dir & (1 << offset)) ? "out" : "in ",
++					(data & (1 << offset)) ? "hi" : "lo");
++			}
++		} else {
++			if (afsel & (1 << offset)) {
++				seq_printf(s, " [HW  ]\n");
++			} else {
++				const char *label = gpiochip_is_requested(gc, i);
++				label = label ? : "";
++				seq_printf(s, " [GPIO] (%-20.20s) %s %s\n", label,
++					(dir & (1 << offset)) ? "out" : "in ",
++					(data & (1 << offset)) ? "hi" : "lo");
++			}
++		}
++	}
++}
++
++static struct gpio_chip amb_gc = {
++	.label			= "ambarella-gpio",
++	.base			= 0,
++	.ngpio			= AMBGPIO_SIZE,
++	.request		= amb_gpio_request,
++	.free			= amb_gpio_free,
++	.direction_input	= amb_gpio_direction_input,
++	.direction_output	= amb_gpio_direction_output,
++	.get			= amb_gpio_get,
++	.set			= amb_gpio_set,
++	.to_irq			= amb_gpio_to_irq,
++	.dbg_show		= amb_gpio_dbg_show,
++	.owner			= THIS_MODULE,
++};
++
++static void amb_gpio_irq_enable(struct irq_data *data)
++{
++	struct amb_gpio_chip *amb_gpio = dev_get_drvdata(amb_gc.dev);
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	void __iomem *iomux_base = amb_gpio->iomux_base;
++	u32 i, bank, offset, val;
++
++	bank = PINID_TO_BANK(data->hwirq);
++	offset = PINID_TO_OFFSET(data->hwirq);
++
++	/* make sure the pin is in gpio input mode */
++	if (!gpiochip_is_requested(&amb_gc, data->hwirq)) {
++		amba_clrbitsl(regbase + GPIO_AFSEL_OFFSET, 0x1 << offset);
++		amba_clrbitsl(regbase + GPIO_DIR_OFFSET, 0x1 << offset);
++
++		if (iomux_base) {
++			for (i = 0; i < 3; i++) {
++				val = amba_readl(iomux_base + IOMUX_REG_OFFSET(bank, i));
++				val &= (~(0x1 << offset));
++				amba_writel(iomux_base + IOMUX_REG_OFFSET(bank, i), val);
++			}
++			amba_writel(iomux_base + IOMUX_CTRL_SET_OFFSET, 0x1);
++			amba_writel(iomux_base + IOMUX_CTRL_SET_OFFSET, 0x0);
++		}
++	}
++
++	amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
++	amba_setbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
++}
++
++static void amb_gpio_irq_disable(struct irq_data *data)
++{
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++
++	amba_clrbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
++	amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
++}
++
++static void amb_gpio_irq_ack(struct irq_data *data)
++{
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++
++	amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
++}
++
++static void amb_gpio_irq_mask(struct irq_data *data)
++{
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++
++	amba_clrbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
++}
++
++static void amb_gpio_irq_mask_ack(struct irq_data *data)
++{
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++
++	amba_clrbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
++	amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
++}
++
++static void amb_gpio_irq_unmask(struct irq_data *data)
++{
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++
++	amba_setbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
++}
++
++static int amb_gpio_irq_set_type(struct irq_data *data, unsigned int type)
++{
++	void __iomem *regbase = irq_data_get_irq_chip_data(data);
++	struct irq_desc *desc = irq_to_desc(data->irq);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++	u32 mask, bit, sense, bothedges, event;
++
++	mask = ~(0x1 << offset);
++	bit = (0x1 << offset);
++	sense = amba_readl(regbase + GPIO_IS_OFFSET);
++	bothedges = amba_readl(regbase + GPIO_IBE_OFFSET);
++	event = amba_readl(regbase + GPIO_IEV_OFFSET);
++
++	switch (type) {
++	case IRQ_TYPE_EDGE_RISING:
++		sense &= mask;
++		bothedges &= mask;
++		event |= bit;
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_EDGE_FALLING:
++		sense &= mask;
++		bothedges &= mask;
++		event &= mask;
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_EDGE_BOTH:
++		sense &= mask;
++		bothedges |= bit;
++		event &= mask;
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_LEVEL_HIGH:
++		sense |= bit;
++		bothedges &= mask;
++		event |= bit;
++		desc->handle_irq = handle_level_irq;
++		break;
++	case IRQ_TYPE_LEVEL_LOW:
++		sense |= bit;
++		bothedges &= mask;
++		event &= mask;
++		desc->handle_irq = handle_level_irq;
++		break;
++	default:
++		pr_err("%s: irq[%d] type[%d] fail!\n",
++			__func__, data->irq, type);
++		return -EINVAL;
++	}
++
++	amba_writel(regbase + GPIO_IS_OFFSET, sense);
++	amba_writel(regbase + GPIO_IBE_OFFSET, bothedges);
++	amba_writel(regbase + GPIO_IEV_OFFSET, event);
++	/* clear obsolete irq */
++	amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
++
++	return 0;
++}
++
++static int amb_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
++{
++#if defined(CONFIG_PM)
++	u32 bank = PINID_TO_BANK(data->hwirq);
++	u32 offset = PINID_TO_OFFSET(data->hwirq);
++
++	if (on) {
++		amb_gpio_pm[bank].irq_wake_mask |= (1 << offset);
++	} else {
++		amb_gpio_pm[bank].irq_wake_mask &= ~(1 << offset);
++	}
++#endif
++	return 0;
++}
++
++static struct irq_chip amb_gpio_irqchip = {
++	.name		= "GPIO",
++	.irq_enable	= amb_gpio_irq_enable,
++	.irq_disable	= amb_gpio_irq_disable,
++	.irq_ack	= amb_gpio_irq_ack,
++	.irq_mask	= amb_gpio_irq_mask,
++	.irq_mask_ack	= amb_gpio_irq_mask_ack,
++	.irq_unmask	= amb_gpio_irq_unmask,
++	.irq_set_type	= amb_gpio_irq_set_type,
++	.irq_set_wake	= amb_gpio_irq_set_wake,
++	.flags		= IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND,
++};
++
++static int amb_gpio_irqdomain_map(struct irq_domain *d,
++			unsigned int irq, irq_hw_number_t hwirq)
++{
++	struct amb_gpio_chip *amb_gpio;
++
++	amb_gpio = (struct amb_gpio_chip *)d->host_data;
++
++	irq_set_chip_and_handler(irq, &amb_gpio_irqchip, handle_level_irq);
++	irq_set_chip_data(irq, amb_gpio->regbase[PINID_TO_BANK(hwirq)]);
++	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++
++	return 0;
++}
++
++const struct irq_domain_ops amb_gpio_irq_domain_ops = {
++	.map = amb_gpio_irqdomain_map,
++	.xlate = irq_domain_xlate_twocell,
++};
++
++static void amb_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
++{
++	struct irq_chip *irqchip;
++	struct amb_gpio_chip *amb_gpio;
++	u32 i, gpio_mis, gpio_hwirq, gpio_irq;
++
++	irqchip = irq_desc_get_chip(desc);
++	chained_irq_enter(irqchip, desc);
++
++	amb_gpio = irq_get_handler_data(irq);
++
++	/* find the GPIO bank generating this irq */
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		if (amb_gpio->irq[i] == irq)
++			break;
++	}
++
++	if (i == GPIO_INSTANCES)
++		return;
++
++	gpio_mis = amba_readl(amb_gpio->regbase[i] + GPIO_MIS_OFFSET);
++	if (gpio_mis) {
++		gpio_hwirq = i * GPIO_BANK_SIZE + ffs(gpio_mis) - 1;
++		gpio_irq = irq_find_mapping(amb_gpio->domain, gpio_hwirq);
++		generic_handle_irq(gpio_irq);
++	}
++
++	chained_irq_exit(irqchip, desc);
++}
++
++static int amb_gpio_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct device_node *parent;
++	struct amb_gpio_chip *amb_gpio;
++	int i, rval;
++
++	amb_gpio = devm_kzalloc(&pdev->dev, sizeof(*amb_gpio), GFP_KERNEL);
++	if (!amb_gpio) {
++		dev_err(&pdev->dev, "failed to allocate memory for private data\n");
++		return -ENOMEM;
++	}
++
++	parent = of_get_parent(np);
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		amb_gpio->regbase[i] = of_iomap(parent, i);
++		if (amb_gpio->regbase[i] == NULL) {
++			dev_err(&pdev->dev, "devm_ioremap() failed\n");
++			return -ENOMEM;
++		}
++
++		amba_writel(amb_gpio->regbase[i] + GPIO_ENABLE_OFFSET, 0xffffffff);
++
++		amb_gpio->irq[i] = irq_of_parse_and_map(np, i);
++		if (amb_gpio->irq[i] == 0) {
++			dev_err(&pdev->dev, "no irq for gpio[%d]!\n", i);
++			return -ENXIO;
++		}
++	}
++
++	/* iomux_base will get NULL if not existed */
++	amb_gpio->iomux_base = of_iomap(parent, i);
++
++	of_node_put(parent);
++
++	amb_gpio->gc = &amb_gc;
++	amb_gpio->gc->dev = &pdev->dev;
++	rval = gpiochip_add(amb_gpio->gc);
++	if (rval) {
++		dev_err(&pdev->dev,
++			"failed to register gpio_chip %s\n", amb_gpio->gc->label);
++		return rval;
++	}
++
++	/* Initialize GPIO irq */
++	amb_gpio->domain = irq_domain_add_linear(np, amb_gpio->gc->ngpio,
++					&amb_gpio_irq_domain_ops, amb_gpio);
++	if (!amb_gpio->domain) {
++		pr_err("%s: Failed to create irqdomain\n", np->full_name);
++		return -ENOSYS;
++	}
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		irq_set_irq_type(amb_gpio->irq[i], IRQ_TYPE_LEVEL_HIGH);
++		irq_set_handler_data(amb_gpio->irq[i], amb_gpio);
++		irq_set_chained_handler(amb_gpio->irq[i], amb_gpio_handle_irq);
++	}
++
++	platform_set_drvdata(pdev, amb_gpio);
++
++	dev_info(&pdev->dev, "Ambarella GPIO driver registered\n");
++
++	/* register ambarella gpio service for private operation */
++	amb_gpio->gpio_service.service = AMBARELLA_SERVICE_GPIO;
++	amb_gpio->gpio_service.func = ambarella_gpio_service;
++	ambarella_register_service(&amb_gpio->gpio_service);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int amb_gpio_irq_suspend(void)
++{
++	struct amb_gpio_chip *amb_gpio;
++	struct amb_gpio_regs *pm;
++	void __iomem *regbase;
++	int i;
++
++	amb_gpio = dev_get_drvdata(amb_gc.dev);
++	if (amb_gpio == NULL) {
++		pr_err("No device for ambarella gpio irq\n");
++		return -ENODEV;
++	}
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		regbase = amb_gpio->regbase[i];
++		pm = &amb_gpio_pm[i];
++		pm->afsel = amba_readl(regbase + GPIO_AFSEL_OFFSET);
++		pm->dir = amba_readl(regbase + GPIO_DIR_OFFSET);
++		pm->is = amba_readl(regbase + GPIO_IS_OFFSET);
++		pm->ibe = amba_readl(regbase + GPIO_IBE_OFFSET);
++		pm->iev = amba_readl(regbase + GPIO_IEV_OFFSET);
++		pm->ie = amba_readl(regbase + GPIO_IE_OFFSET);
++		pm->mask = ~pm->afsel;
++		amba_writel(regbase + GPIO_MASK_OFFSET, pm->mask);
++		pm->data = amba_readl(regbase + GPIO_DATA_OFFSET);
++
++		if (pm->irq_wake_mask) {
++			amba_writel(regbase + GPIO_IE_OFFSET, pm->irq_wake_mask);
++			pr_info("gpio_irq[%p]: irq_wake[0x%08X]\n",
++						regbase, pm->irq_wake_mask);
++		}
++	}
++
++	return 0;
++}
++
++static void amb_gpio_irq_resume(void)
++{
++	struct amb_gpio_chip *amb_gpio;
++	struct amb_gpio_regs *pm;
++	void __iomem *regbase;
++	int i;
++
++	amb_gpio = dev_get_drvdata(amb_gc.dev);
++	if (amb_gpio == NULL) {
++		pr_err("No device for ambarella gpio irq\n");
++		return;
++	}
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		regbase = amb_gpio->regbase[i];
++		pm = &amb_gpio_pm[i];
++		amba_writel(regbase + GPIO_AFSEL_OFFSET, pm->afsel);
++		amba_writel(regbase + GPIO_DIR_OFFSET, pm->dir);
++		amba_writel(regbase + GPIO_MASK_OFFSET, pm->mask);
++		amba_writel(regbase + GPIO_DATA_OFFSET, pm->data);
++		amba_writel(regbase + GPIO_IS_OFFSET, pm->is);
++		amba_writel(regbase + GPIO_IBE_OFFSET, pm->ibe);
++		amba_writel(regbase + GPIO_IEV_OFFSET, pm->iev);
++		amba_writel(regbase + GPIO_IE_OFFSET, pm->ie);
++		amba_writel(regbase + GPIO_ENABLE_OFFSET, 0xffffffff);
++	}
++}
++
++struct syscore_ops amb_gpio_irq_syscore_ops = {
++	.suspend	= amb_gpio_irq_suspend,
++	.resume		= amb_gpio_irq_resume,
++};
++
++#endif
++
++static const struct of_device_id amb_gpio_dt_match[] = {
++	{ .compatible = "ambarella,gpio" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, amb_gpio_dt_match);
++
++static struct platform_driver amb_gpio_driver = {
++	.probe	= amb_gpio_probe,
++	.driver	= {
++		.name	= "ambarella-gpio",
++		.owner	= THIS_MODULE,
++		.of_match_table = of_match_ptr(amb_gpio_dt_match),
++	},
++};
++
++static int __init amb_gpio_drv_register(void)
++{
++#ifdef CONFIG_PM
++	register_syscore_ops(&amb_gpio_irq_syscore_ops);
++#endif
++
++	return platform_driver_register(&amb_gpio_driver);
++}
++postcore_initcall(amb_gpio_drv_register);
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella SoC GPIO driver");
++MODULE_LICENSE("GPL v2");
++
++static int ambarella_gpio_service(void *arg, void *result)
++{
++	struct ambsvc_gpio *gpio_svc = arg;
++	u32 *value = result;
++	int rval = 0;
++
++	BUG_ON(!gpio_svc);
++
++	switch (gpio_svc->svc_id) {
++	case AMBSVC_GPIO_REQUEST:
++	{
++		rval = gpio_request(gpio_svc->gpio, "gpio");
++		break;
++	}
++	case AMBSVC_GPIO_OUTPUT:
++		rval = gpio_direction_output(gpio_svc->gpio, gpio_svc->value);
++		break;
++
++	case AMBSVC_GPIO_INPUT:
++		rval = gpio_direction_input(gpio_svc->gpio);
++		if (rval >= 0 && value)
++			*value = gpio_get_value_cansleep(gpio_svc->gpio);
++		break;
++
++	case AMBSVC_GPIO_FREE:
++		gpio_free(gpio_svc->gpio);
++		break;
++
++	case AMBSVC_GPIO_TO_IRQ:
++		*value = gpio_to_irq(gpio_svc->gpio);
++		break;
++
++	default:
++		pr_err("%s: Invalid gpio service (%d)\n", __func__, gpio_svc->svc_id);
++		rval = -EINVAL;
++		break;
++	}
++
++	return rval;
++}
++
+diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
+index e8faf53f..365324f2 100644
+--- a/drivers/gpio/gpio-pcf857x.c
++++ b/drivers/gpio/gpio-pcf857x.c
+@@ -27,8 +27,10 @@
+ #include <linux/irq.h>
+ #include <linux/irqdomain.h>
+ #include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/slab.h>
+ #include <linux/spinlock.h>
+-#include <linux/workqueue.h>
+ 
+ 
+ static const struct i2c_device_id pcf857x_id[] = {
+@@ -50,6 +52,27 @@ static const struct i2c_device_id pcf857x_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, pcf857x_id);
+ 
++#ifdef CONFIG_OF
++static const struct of_device_id pcf857x_of_table[] = {
++	{ .compatible = "nxp,pcf8574" },
++	{ .compatible = "nxp,pcf8574a" },
++	{ .compatible = "nxp,pca8574" },
++	{ .compatible = "nxp,pca9670" },
++	{ .compatible = "nxp,pca9672" },
++	{ .compatible = "nxp,pca9674" },
++	{ .compatible = "nxp,pcf8575" },
++	{ .compatible = "nxp,pca8575" },
++	{ .compatible = "nxp,pca9671" },
++	{ .compatible = "nxp,pca9673" },
++	{ .compatible = "nxp,pca9675" },
++	{ .compatible = "maxim,max7328" },
++	{ .compatible = "maxim,max7329" },
++	{ .compatible = "ti,tca9554" },
++	{ }
++};
++MODULE_DEVICE_TABLE(of, pcf857x_of_table);
++#endif
++
+ /*
+  * The pcf857x, pca857x, and pca967x chips only expose one read and one
+  * write register.  Writing a "one" bit (to match the reset state) lets
+@@ -66,12 +89,11 @@ struct pcf857x {
+ 	struct gpio_chip	chip;
+ 	struct i2c_client	*client;
+ 	struct mutex		lock;		/* protect 'out' */
+-	struct work_struct	work;		/* irq demux work */
+ 	struct irq_domain	*irq_domain;	/* for irq demux  */
+ 	spinlock_t		slock;		/* protect irq demux */
+ 	unsigned		out;		/* software latch */
+ 	unsigned		status;		/* current status */
+-	int			irq;		/* real irq number */
++	unsigned		irq_mapped;	/* mapped gpio irqs */
+ 
+ 	int (*write)(struct i2c_client *client, unsigned data);
+ 	int (*read)(struct i2c_client *client);
+@@ -164,48 +186,54 @@ static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value)
+ static int pcf857x_to_irq(struct gpio_chip *chip, unsigned offset)
+ {
+ 	struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
++	int ret;
++
++	ret = irq_create_mapping(gpio->irq_domain, offset);
++	if (ret > 0)
++		gpio->irq_mapped |= (1 << offset);
+ 
+-	return irq_create_mapping(gpio->irq_domain, offset);
++	return ret;
+ }
+ 
+-static void pcf857x_irq_demux_work(struct work_struct *work)
++static irqreturn_t pcf857x_irq(int irq, void *data)
+ {
+-	struct pcf857x *gpio = container_of(work,
+-					       struct pcf857x,
+-					       work);
++	struct pcf857x  *gpio = data;
+ 	unsigned long change, i, status, flags;
+ 
+ 	status = gpio->read(gpio->client);
+ 
+ 	spin_lock_irqsave(&gpio->slock, flags);
+ 
+-	change = gpio->status ^ status;
++	/*
++	 * call the interrupt handler iff gpio is used as
++	 * interrupt source, just to avoid bad irqs
++	 */
++
++	change = ((gpio->status ^ status) & gpio->irq_mapped);
+ 	for_each_set_bit(i, &change, gpio->chip.ngpio)
+ 		generic_handle_irq(irq_find_mapping(gpio->irq_domain, i));
+ 	gpio->status = status;
+ 
+ 	spin_unlock_irqrestore(&gpio->slock, flags);
+-}
+-
+-static irqreturn_t pcf857x_irq_demux(int irq, void *data)
+-{
+-	struct pcf857x	*gpio = data;
+-
+-	/*
+-	 * pcf857x can't read/write data here,
+-	 * since i2c data access might go to sleep.
+-	 */
+-	schedule_work(&gpio->work);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int virq,
++static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int irq,
+ 				 irq_hw_number_t hw)
+ {
+-	irq_set_chip_and_handler(virq,
++	struct pcf857x *gpio = domain->host_data;
++
++	irq_set_chip_and_handler(irq,
+ 				 &dummy_irq_chip,
+ 				 handle_level_irq);
++#ifdef CONFIG_ARM
++	set_irq_flags(irq, IRQF_VALID);
++#else
++	irq_set_noprobe(irq);
++#endif
++	gpio->irq_mapped |= (1 << hw);
++
+ 	return 0;
+ }
+ 
+@@ -218,12 +246,9 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio)
+ 	if (gpio->irq_domain)
+ 		irq_domain_remove(gpio->irq_domain);
+ 
+-	if (gpio->irq)
+-		free_irq(gpio->irq, gpio);
+ }
+ 
+ static int pcf857x_irq_domain_init(struct pcf857x *gpio,
+-				   struct pcf857x_platform_data *pdata,
+ 				   struct i2c_client *client)
+ {
+ 	int status;
+@@ -231,20 +256,21 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio,
+ 	gpio->irq_domain = irq_domain_add_linear(client->dev.of_node,
+ 						 gpio->chip.ngpio,
+ 						 &pcf857x_irq_domain_ops,
+-						 NULL);
++						 gpio);
+ 	if (!gpio->irq_domain)
+ 		goto fail;
+ 
+ 	/* enable real irq */
+-	status = request_irq(client->irq, pcf857x_irq_demux, 0,
+-			     dev_name(&client->dev), gpio);
++	status = devm_request_threaded_irq(&client->dev, client->irq,
++				NULL, pcf857x_irq, IRQF_ONESHOT |
++				IRQF_TRIGGER_FALLING | IRQF_SHARED,
++				dev_name(&client->dev), gpio);
++
+ 	if (status)
+ 		goto fail;
+ 
+ 	/* enable gpio_to_irq() */
+-	INIT_WORK(&gpio->work, pcf857x_irq_demux_work);
+ 	gpio->chip.to_irq	= pcf857x_to_irq;
+-	gpio->irq		= client->irq;
+ 
+ 	return 0;
+ 
+@@ -258,14 +284,18 @@ fail:
+ static int pcf857x_probe(struct i2c_client *client,
+ 			 const struct i2c_device_id *id)
+ {
+-	struct pcf857x_platform_data	*pdata;
++	struct pcf857x_platform_data	*pdata = dev_get_platdata(&client->dev);
++	struct device_node		*np = client->dev.of_node;
+ 	struct pcf857x			*gpio;
++	unsigned int			n_latch = 0;
+ 	int				status;
+ 
+-	pdata = client->dev.platform_data;
+-	if (!pdata) {
++	if (IS_ENABLED(CONFIG_OF) && np)
++		of_property_read_u32(np, "lines-initial-states", &n_latch);
++	else if (pdata)
++		n_latch = pdata->n_latch;
++	else
+ 		dev_dbg(&client->dev, "no platform data\n");
+-	}
+ 
+ 	/* Allocate, initialize, and register this gpio_chip. */
+ 	gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
+@@ -286,11 +316,11 @@ static int pcf857x_probe(struct i2c_client *client,
+ 	gpio->chip.ngpio		= id->driver_data;
+ 
+ 	/* enable gpio_to_irq() if platform has settings */
+-	if (pdata && client->irq) {
+-		status = pcf857x_irq_domain_init(gpio, pdata, client);
++	if (client->irq) {
++		status = pcf857x_irq_domain_init(gpio, client);
+ 		if (status < 0) {
+ 			dev_err(&client->dev, "irq_domain init failed\n");
+-			goto fail;
++			goto fail_irq_domain;
+ 		}
+ 	}
+ 
+@@ -358,11 +388,11 @@ static int pcf857x_probe(struct i2c_client *client,
+ 	 * may cause transient glitching since it can't know the last value
+ 	 * written (some pins may need to be driven low).
+ 	 *
+-	 * Using pdata->n_latch avoids that trouble.  When left initialized
+-	 * to zero, our software copy of the "latch" then matches the chip's
+-	 * all-ones reset state.  Otherwise it flags pins to be driven low.
++	 * Using n_latch avoids that trouble.  When left initialized to zero,
++	 * our software copy of the "latch" then matches the chip's all-ones
++	 * reset state.  Otherwise it flags pins to be driven low.
+ 	 */
+-	gpio->out = pdata ? ~pdata->n_latch : ~0;
++	gpio->out = ~n_latch;
+ 	gpio->status = gpio->out;
+ 
+ 	status = gpiochip_add(&gpio->chip);
+@@ -385,12 +415,13 @@ static int pcf857x_probe(struct i2c_client *client,
+ 	return 0;
+ 
+ fail:
+-	dev_dbg(&client->dev, "probe error %d for '%s'\n",
+-			status, client->name);
+-
+-	if (pdata && client->irq)
++	if (client->irq)
+ 		pcf857x_irq_domain_cleanup(gpio);
+ 
++fail_irq_domain:
++	dev_dbg(&client->dev, "probe error %d for '%s'\n",
++		status, client->name);
++
+ 	return status;
+ }
+ 
+@@ -411,7 +442,7 @@ static int pcf857x_remove(struct i2c_client *client)
+ 		}
+ 	}
+ 
+-	if (pdata && client->irq)
++	if (client->irq)
+ 		pcf857x_irq_domain_cleanup(gpio);
+ 
+ 	status = gpiochip_remove(&gpio->chip);
+@@ -424,6 +455,7 @@ static struct i2c_driver pcf857x_driver = {
+ 	.driver = {
+ 		.name	= "pcf857x",
+ 		.owner	= THIS_MODULE,
++		.of_match_table = of_match_ptr(pcf857x_of_table),
+ 	},
+ 	.probe	= pcf857x_probe,
+ 	.remove	= pcf857x_remove,
+diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
+index 33cb87f7..24c6c8b2 100644
+--- a/drivers/gpu/drm/i915/intel_panel.c
++++ b/drivers/gpu/drm/i915/intel_panel.c
+@@ -30,6 +30,7 @@
+ 
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ 
++#include <linux/kernel.h>
+ #include <linux/moduleparam.h>
+ #include "intel_drv.h"
+ 
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index f25f2983..471dd1ae 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -1528,6 +1528,13 @@ config SENSORS_MC13783_ADC
+         help
+           Support for the A/D converter on MC13783 and MC13892 PMIC.
+ 
++config SENSORS_AMBARELLA_ADC_TEMPER
++	tristate "AMBARELLA ADC temper"
++	help
++	  If you say yes here you get support for the hardware
++	  monitoring functionality of the Ambarella ADC temperature
++	  monitoring functionality.
++
+ if ACPI
+ 
+ comment "ACPI drivers"
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index d4fe13ee..0ef7d3a2 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -307,6 +307,18 @@ config I2C_POWERMAC
+ 
+ comment "I2C system bus drivers (mostly embedded / system-on-chip)"
+ 
++config I2C_AMBARELLA
++	tristate "Ambarella Media Soc I2C bus support"
++	depends on PLAT_AMBARELLA
++	select I2C_MUX if PLAT_AMBARELLA_SUPPORT_I2C_MUX
++	select I2C_MUX_AMBARELLA if PLAT_AMBARELLA_SUPPORT_I2C_MUX
++	help
++	  This driver supports the Ambarella Media Soc
++	  I2C Bus master controller
++
++	  This driver can also be built as a module.  If so, the module
++	  will be called ambarella_i2c.
++
+ config I2C_AT91
+ 	tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
+ 	depends on ARCH_AT91
+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
+index 8f4fc23b..57d318b2 100644
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
+ obj-$(CONFIG_I2C_POWERMAC)	+= i2c-powermac.o
+ 
+ # Embedded system I2C/SMBus host controller drivers
++obj-$(CONFIG_I2C_AMBARELLA)	+= i2c-ambarella.o
+ obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
+ obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
+ obj-$(CONFIG_I2C_BCM2835)	+= i2c-bcm2835.o
+diff --git a/drivers/i2c/busses/i2c-ambarella.c b/drivers/i2c/busses/i2c-ambarella.c
+new file mode 100644
+index 00000000..fd1499e5
+--- /dev/null
++++ b/drivers/i2c/busses/i2c-ambarella.c
+@@ -0,0 +1,759 @@
++/*
++ * drivers/i2c/busses/ambarella_i2c.c
++ *
++ * Anthony Ginger, <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/of_i2c.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/semaphore.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/clk.h>
++#include <asm/dma.h>
++
++#include <mach/hardware.h>
++#include <plat/idc.h>
++#include <plat/event.h>
++
++#ifndef CONFIG_I2C_AMBARELLA_RETRIES
++#define CONFIG_I2C_AMBARELLA_RETRIES		(3)
++#endif
++
++#ifndef CONFIG_I2C_AMBARELLA_ACK_TIMEOUT
++#define CONFIG_I2C_AMBARELLA_ACK_TIMEOUT	(3 * HZ)
++#endif
++
++#define CONFIG_I2C_AMBARELLA_BULK_RETRY_NUM	(4)
++
++/* must keep consistent with the name in device tree source, and the name
++ * of corresponding i2c client will be overwritten when it's in used. */
++#define AMBARELLA_I2C_VIN_FDT_NAME		"ambvin"
++#define AMBARELLA_I2C_VIN_MAX_NUM		8
++
++enum ambarella_i2c_state {
++	AMBA_I2C_STATE_IDLE,
++	AMBA_I2C_STATE_START,
++	AMBA_I2C_STATE_START_TEN,
++	AMBA_I2C_STATE_START_NEW,
++	AMBA_I2C_STATE_READ,
++	AMBA_I2C_STATE_READ_STOP,
++	AMBA_I2C_STATE_WRITE,
++	AMBA_I2C_STATE_WRITE_WAIT_ACK,
++	AMBA_I2C_STATE_BULK_WRITE,
++	AMBA_I2C_STATE_NO_ACK,
++	AMBA_I2C_STATE_ERROR
++};
++
++struct ambarella_i2c_dev_info {
++	unsigned char __iomem 			*regbase;
++
++	struct device				*dev;
++	unsigned int				irq;
++	struct i2c_adapter			adap;
++	enum ambarella_i2c_state		state;
++
++	u32					clk_limit;
++	u32					bulk_num;
++	u32					duty_cycle;
++	u32					stretch_scl;
++	u32					turbo_mode;
++
++	struct i2c_msg				*msgs;
++	__u16					msg_num;
++	__u16					msg_addr;
++	wait_queue_head_t			msg_wait;
++	unsigned int				msg_index;
++
++	struct notifier_block			system_event;
++	struct semaphore			system_event_sem;
++};
++
++int ambpriv_i2c_update_addr(const char *name, int bus, int addr)
++{
++	struct device_node *np;
++	struct i2c_adapter *adap;
++	struct i2c_client *client;
++	char buf[32];
++	int i;
++
++	adap = i2c_get_adapter(bus);
++	if (!adap) {
++		pr_err("No such i2c controller: %d\n", bus);
++		return -ENODEV;
++	}
++
++	for (i = 0; i < AMBARELLA_I2C_VIN_MAX_NUM; i++) {
++		snprintf(buf, 32, "%s%d", AMBARELLA_I2C_VIN_FDT_NAME, i);
++		np = of_get_child_by_name(adap->dev.of_node, buf);
++		if (!np) {
++			pr_err("ambpriv i2c: No FDT node named [%s]\n", buf);
++			return -ENODEV;
++		}
++
++		client = of_find_i2c_device_by_node(np);
++		if (!client) {
++			pr_err("failed to find i2c client\n");
++			return -ENODEV;
++		}
++
++		if (!strcmp(client->name, AMBARELLA_I2C_VIN_FDT_NAME) ||
++			!strcmp(client->name, name))
++			break;
++	}
++
++	if (i >= AMBARELLA_I2C_VIN_MAX_NUM) {
++		pr_err("fake vin sensor in device tree is not enough.\n");
++		return -ENODEV;
++	}
++
++	client->addr = addr;
++	strlcpy(client->name, name, I2C_NAME_SIZE);
++
++	return 0;
++}
++EXPORT_SYMBOL(ambpriv_i2c_update_addr);
++
++static inline void ambarella_i2c_set_clk(struct ambarella_i2c_dev_info *pinfo)
++{
++	unsigned int				apb_clk;
++	__u32					idc_prescale;
++
++	apb_clk = clk_get_rate(clk_get(NULL, "gclk_apb"));
++
++	amba_writel(pinfo->regbase + IDC_ENR_OFFSET, IDC_ENR_REG_DISABLE);
++
++	idc_prescale =( ((apb_clk / pinfo->clk_limit) - 2)/(4 + pinfo->duty_cycle)) - 1;
++
++	dev_dbg(pinfo->dev, "apb_clk[%dHz]\n", apb_clk);
++	dev_dbg(pinfo->dev, "idc_prescale[%d]\n", idc_prescale);
++	dev_dbg(pinfo->dev, "duty_cycle[%d]\n", pinfo->duty_cycle);
++	dev_dbg(pinfo->dev, "clk[%dHz]\n",
++		(apb_clk / ((idc_prescale + 1) << 2)));
++
++	amba_writeb(pinfo->regbase + IDC_PSLL_OFFSET,
++		(idc_prescale & 0xff));
++	amba_writeb(pinfo->regbase + IDC_PSLH_OFFSET,
++		((idc_prescale & 0xff00) >> 8));
++
++	amba_writeb(pinfo->regbase + IDC_DUTYCYCLE_OFFSET, pinfo->duty_cycle);
++	amba_writeb(pinfo->regbase + IDC_STRETCHSCL_OFFSET, pinfo->stretch_scl);
++
++	amba_writel(pinfo->regbase + IDC_ENR_OFFSET, IDC_ENR_REG_ENABLE);
++}
++
++static int ambarella_i2c_system_event(struct notifier_block *nb,
++	unsigned long val, void *data)
++{
++	int					errorCode = NOTIFY_OK;
++	struct platform_device			*pdev;
++	struct ambarella_i2c_dev_info		*pinfo;
++
++	pinfo = container_of(nb, struct ambarella_i2c_dev_info, system_event);
++	pdev = to_platform_device(pinfo->dev);
++
++	switch (val) {
++	case AMBA_EVENT_PRE_CPUFREQ:
++		pr_debug("%s[%d]: Pre Change\n", __func__, pdev->id);
++		down(&pinfo->system_event_sem);
++		break;
++
++	case AMBA_EVENT_POST_CPUFREQ:
++		pr_debug("%s[%d]: Post Change\n", __func__, pdev->id);
++		ambarella_i2c_set_clk(pinfo);
++		up(&pinfo->system_event_sem);
++		break;
++
++	default:
++		break;
++	}
++
++	return errorCode;
++}
++
++static inline void ambarella_i2c_hw_init(struct ambarella_i2c_dev_info *pinfo)
++{
++	ambarella_i2c_set_clk(pinfo);
++
++	pinfo->msgs = NULL;
++	pinfo->msg_num = 0;
++	pinfo->state = AMBA_I2C_STATE_IDLE;
++}
++
++static inline void ambarella_i2c_start_single_msg(
++	struct ambarella_i2c_dev_info *pinfo)
++{
++	if (pinfo->msgs->flags & I2C_M_TEN) {
++		pinfo->state = AMBA_I2C_STATE_START_TEN;
++		amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
++			(0xf0 | ((pinfo->msg_addr >> 8) & 0x07)));
++	} else {
++		pinfo->state = AMBA_I2C_STATE_START;
++		amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
++			(pinfo->msg_addr & 0xff));
++	}
++
++	amba_writel(pinfo->regbase + IDC_CTRL_OFFSET, IDC_CTRL_START);
++}
++
++static inline void ambarella_i2c_bulk_write(
++	struct ambarella_i2c_dev_info *pinfo,
++	__u32 fifosize)
++{
++	while (fifosize--) {
++		amba_writeb(pinfo->regbase + IDC_FMDATA_OFFSET,
++			pinfo->msgs->buf[pinfo->msg_index++]);
++		if (pinfo->msg_index >= pinfo->msgs->len)
++			break;
++	};
++
++	/* the last fifo data MUST be STOP+IF */
++	amba_writel(pinfo->regbase + IDC_FMCTRL_OFFSET,
++		IDC_FMCTRL_IF | IDC_FMCTRL_STOP);
++}
++
++static inline void ambarella_i2c_start_bulk_msg_write(
++	struct ambarella_i2c_dev_info *pinfo)
++{
++	__u32				fifosize = IDC_FIFO_BUF_SIZE;
++
++	pinfo->state = AMBA_I2C_STATE_BULK_WRITE;
++
++	amba_writel(pinfo->regbase + IDC_CTRL_OFFSET, 0);
++	amba_writel(pinfo->regbase + IDC_FMCTRL_OFFSET, IDC_FMCTRL_START);
++
++	if (pinfo->msgs->flags & I2C_M_TEN) {
++		amba_writeb(pinfo->regbase + IDC_FMDATA_OFFSET,
++			(0xf0 | ((pinfo->msg_addr >> 8) & 0x07)));
++		fifosize--;
++	}
++	amba_writeb(pinfo->regbase + IDC_FMDATA_OFFSET,
++		(pinfo->msg_addr & 0xff));
++	fifosize -= 2;
++
++	ambarella_i2c_bulk_write(pinfo, fifosize);
++}
++
++static inline void ambarella_i2c_start_current_msg(
++	struct ambarella_i2c_dev_info *pinfo)
++{
++	pinfo->msg_index = 0;
++	pinfo->msg_addr = (pinfo->msgs->addr << 1);
++
++	if (pinfo->msgs->flags & I2C_M_RD)
++		pinfo->msg_addr |= 1;
++
++	if (pinfo->msgs->flags & I2C_M_REV_DIR_ADDR)
++		pinfo->msg_addr ^= 1;
++
++	if (pinfo->msgs->flags & I2C_M_RD) {
++		ambarella_i2c_start_single_msg(pinfo);
++	} else if (pinfo->turbo_mode) {
++		ambarella_i2c_start_bulk_msg_write(pinfo);
++	} else {
++		ambarella_i2c_start_single_msg(pinfo);
++	}
++
++	dev_dbg(pinfo->dev, "msg_addr[0x%x], len[0x%x]",
++		pinfo->msg_addr, pinfo->msgs->len);
++}
++
++static inline void ambarella_i2c_stop(
++	struct ambarella_i2c_dev_info *pinfo,
++	enum ambarella_i2c_state state,
++	__u32 *pack_control)
++{
++	if(state != AMBA_I2C_STATE_IDLE) {
++		*pack_control |= IDC_CTRL_ACK;
++	}
++
++	pinfo->state = state;
++	pinfo->msgs = NULL;
++	pinfo->msg_num = 0;
++
++	*pack_control |= IDC_CTRL_STOP;
++
++	if(pinfo->state == AMBA_I2C_STATE_IDLE)
++		wake_up(&pinfo->msg_wait);
++}
++
++static inline __u32 ambarella_i2c_check_ack(
++	struct ambarella_i2c_dev_info *pinfo,
++	__u32 *pack_control,
++	__u32 retry_counter)
++{
++	__u32				retVal = IDC_CTRL_ACK;
++
++ambarella_i2c_check_ack_enter:
++	if (unlikely((*pack_control) & IDC_CTRL_ACK)) {
++		if (pinfo->msgs->flags & I2C_M_IGNORE_NAK)
++			goto ambarella_i2c_check_ack_exit;
++
++		if ((pinfo->msgs->flags & I2C_M_RD) &&
++			(pinfo->msgs->flags & I2C_M_NO_RD_ACK))
++			goto ambarella_i2c_check_ack_exit;
++
++		if (retry_counter--) {
++			udelay(100);
++			*pack_control = amba_readl(pinfo->regbase
++				+ IDC_CTRL_OFFSET);
++			goto ambarella_i2c_check_ack_enter;
++		}
++		retVal = 0;
++		*pack_control = 0;
++		ambarella_i2c_stop(pinfo,
++			AMBA_I2C_STATE_NO_ACK, pack_control);
++	}
++
++ambarella_i2c_check_ack_exit:
++	return retVal;
++}
++
++static irqreturn_t ambarella_i2c_irq(int irqno, void *dev_id)
++{
++	struct ambarella_i2c_dev_info	*pinfo;
++	__u32				status_reg;
++	__u32				control_reg;
++	__u32				ack_control = IDC_CTRL_CLS;
++
++	pinfo = (struct ambarella_i2c_dev_info *)dev_id;
++
++	status_reg = amba_readl(pinfo->regbase + IDC_STS_OFFSET);
++	control_reg = amba_readl(pinfo->regbase + IDC_CTRL_OFFSET);
++
++	dev_dbg(pinfo->dev, "state[0x%x]\n", pinfo->state);
++	dev_dbg(pinfo->dev, "status_reg[0x%x]\n", status_reg);
++	dev_dbg(pinfo->dev, "control_reg[0x%x]\n", control_reg);
++
++	switch (pinfo->state) {
++	case AMBA_I2C_STATE_START:
++		if (ambarella_i2c_check_ack(pinfo, &control_reg,
++			1) == IDC_CTRL_ACK) {
++			if (pinfo->msgs->flags & I2C_M_RD) {
++				if (pinfo->msgs->len == 1)
++					ack_control |= IDC_CTRL_ACK;
++				pinfo->state = AMBA_I2C_STATE_READ;
++			} else {
++				pinfo->state = AMBA_I2C_STATE_WRITE;
++				goto amba_i2c_irq_write;
++			}
++		} else {
++			ack_control = control_reg;
++		}
++		break;
++	case AMBA_I2C_STATE_START_TEN:
++		pinfo->state = AMBA_I2C_STATE_START;
++		amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
++			(pinfo->msg_addr & 0xff));
++		break;
++	case AMBA_I2C_STATE_START_NEW:
++amba_i2c_irq_start_new:
++		ambarella_i2c_start_current_msg(pinfo);
++		goto amba_i2c_irq_exit;
++		break;
++	case AMBA_I2C_STATE_READ_STOP:
++		pinfo->msgs->buf[pinfo->msg_index] =
++			amba_readb(pinfo->regbase + IDC_DATA_OFFSET);
++		pinfo->msg_index++;
++amba_i2c_irq_read_stop:
++		ambarella_i2c_stop(pinfo, AMBA_I2C_STATE_IDLE, &ack_control);
++		break;
++	case AMBA_I2C_STATE_READ:
++		pinfo->msgs->buf[pinfo->msg_index] =
++			amba_readb(pinfo->regbase + IDC_DATA_OFFSET);
++		pinfo->msg_index++;
++
++		if (pinfo->msg_index >= pinfo->msgs->len - 1) {
++			if (pinfo->msg_num > 1) {
++				pinfo->msgs++;
++				pinfo->state = AMBA_I2C_STATE_START_NEW;
++				pinfo->msg_num--;
++			} else {
++				if (pinfo->msg_index > pinfo->msgs->len - 1) {
++					goto amba_i2c_irq_read_stop;
++				} else {
++					pinfo->state = AMBA_I2C_STATE_READ_STOP;
++					ack_control |= IDC_CTRL_ACK;
++				}
++			}
++		}
++		break;
++	case AMBA_I2C_STATE_WRITE:
++amba_i2c_irq_write:
++		pinfo->state = AMBA_I2C_STATE_WRITE_WAIT_ACK;
++		amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
++			pinfo->msgs->buf[pinfo->msg_index]);
++		break;
++	case AMBA_I2C_STATE_WRITE_WAIT_ACK:
++		if (ambarella_i2c_check_ack(pinfo, &control_reg,
++			1) == IDC_CTRL_ACK) {
++			pinfo->state = AMBA_I2C_STATE_WRITE;
++			pinfo->msg_index++;
++
++			if (pinfo->msg_index >= pinfo->msgs->len) {
++				if (pinfo->msg_num > 1) {
++					pinfo->msgs++;
++					pinfo->state = AMBA_I2C_STATE_START_NEW;
++					pinfo->msg_num--;
++					goto amba_i2c_irq_start_new;
++				}
++				ambarella_i2c_stop(pinfo,
++					AMBA_I2C_STATE_IDLE, &ack_control);
++			} else {
++				goto amba_i2c_irq_write;
++			}
++		} else {
++			ack_control = control_reg;
++		}
++		break;
++	case AMBA_I2C_STATE_BULK_WRITE:
++		while (((status_reg & 0xF0) != 0x50) && ((status_reg & 0xF0) != 0x00)) {
++			cpu_relax();
++			status_reg = amba_readl(pinfo->regbase + IDC_STS_OFFSET);
++		};
++		if (pinfo->msg_num > 1) {
++			pinfo->msgs++;
++			pinfo->state = AMBA_I2C_STATE_START_NEW;
++			pinfo->msg_num--;
++			goto amba_i2c_irq_start_new;
++		}
++		ambarella_i2c_stop(pinfo, AMBA_I2C_STATE_IDLE, &ack_control);
++		goto amba_i2c_irq_exit;
++	default:
++		dev_err(pinfo->dev, "ambarella_i2c_irq in wrong state[0x%x]\n",
++			pinfo->state);
++		dev_err(pinfo->dev, "status_reg[0x%x]\n", status_reg);
++		dev_err(pinfo->dev, "control_reg[0x%x]\n", control_reg);
++		ack_control = IDC_CTRL_STOP | IDC_CTRL_ACK;
++		pinfo->state = AMBA_I2C_STATE_ERROR;
++		break;
++	}
++
++	amba_writel(pinfo->regbase + IDC_CTRL_OFFSET, ack_control);
++
++amba_i2c_irq_exit:
++	return IRQ_HANDLED;
++}
++
++static int ambarella_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
++	int num)
++{
++	struct ambarella_i2c_dev_info	*pinfo;
++	int				errorCode = -EPERM;
++	int				retryCount;
++	long				timeout;
++	int				i;
++
++	pinfo = (struct ambarella_i2c_dev_info *)i2c_get_adapdata(adap);
++
++	/* check data length for FIFO mode */
++	if (unlikely(pinfo->turbo_mode)) {
++		pinfo->msgs = msgs;
++		pinfo->msg_num = num;
++		for (i = 0 ; i < pinfo->msg_num; i++) {
++			if ((!(pinfo->msgs->flags & I2C_M_RD)) &&
++				(pinfo->msgs->len > IDC_FIFO_BUF_SIZE - 2)) {
++				dev_err(pinfo->dev,
++					"Turbo(FIFO) mode can only support <= "
++					"%d bytes writing, but message[%d]: %d bytes applied!\n",
++					IDC_FIFO_BUF_SIZE - 2, i, pinfo->msgs->len);
++
++				return -EPERM;
++			}
++			pinfo->msgs++;
++		}
++	}
++
++	down(&pinfo->system_event_sem);
++
++	for (retryCount = 0; retryCount < adap->retries; retryCount++) {
++		errorCode = 0;
++		if (pinfo->state != AMBA_I2C_STATE_IDLE)
++			ambarella_i2c_hw_init(pinfo);
++		pinfo->msgs = msgs;
++		pinfo->msg_num = num;
++
++		ambarella_i2c_start_current_msg(pinfo);
++		timeout = wait_event_timeout(pinfo->msg_wait,
++			pinfo->msg_num == 0, adap->timeout);
++		if (timeout <= 0) {
++			pinfo->state = AMBA_I2C_STATE_NO_ACK;
++		}
++		dev_dbg(pinfo->dev, "%ld jiffies left.\n", timeout);
++
++		if (pinfo->state != AMBA_I2C_STATE_IDLE) {
++			errorCode = -EBUSY;
++		} else {
++			break;
++		}
++	}
++
++	up(&pinfo->system_event_sem);
++
++	if (errorCode) {
++		if (pinfo->state == AMBA_I2C_STATE_NO_ACK) {
++			dev_err(pinfo->dev,
++				"No ACK from address 0x%x, %d:%d!\n",
++				pinfo->msg_addr, pinfo->msg_num,
++				pinfo->msg_index);
++		}
++		return errorCode;
++	}
++
++	return num;
++}
++
++static u32 ambarella_i2c_func(struct i2c_adapter *adap)
++{
++	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
++}
++
++static const struct i2c_algorithm ambarella_i2c_algo = {
++	.master_xfer	= ambarella_i2c_xfer,
++	.functionality	= ambarella_i2c_func,
++};
++
++static int ambarella_i2c_probe(struct platform_device *pdev)
++{
++	struct device_node 			*np = pdev->dev.of_node;
++	int					errorCode;
++	struct ambarella_i2c_dev_info		*pinfo;
++	struct i2c_adapter			*adap;
++	struct resource				*mem;
++	u32					i2c_class = 0;
++
++	pinfo = devm_kzalloc(&pdev->dev, sizeof(*pinfo), GFP_KERNEL);
++	if (pinfo == NULL) {
++		dev_err(&pdev->dev, "Out of memory!\n");
++		return -ENOMEM;
++	}
++	pinfo->dev = &pdev->dev;
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get I2C mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	pinfo->regbase = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
++	if (!pinfo->regbase) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	pinfo->irq = platform_get_irq(pdev, 0);
++	if (pinfo->irq < 0) {
++		dev_err(&pdev->dev, "no irq for i2c%d!\n", pdev->id);
++		return -ENODEV;
++	}
++
++	errorCode = of_property_read_u32(np, "amb,i2c-class", &i2c_class);
++	if (errorCode < 0) {
++		dev_err(&pdev->dev, "Get i2c_class failed!\n");
++		return -ENODEV;
++	}
++
++	i2c_class &= (I2C_CLASS_HWMON | I2C_CLASS_DDC | I2C_CLASS_SPD);
++	if (i2c_class == 0){
++		dev_err(&pdev->dev, "Invalid i2c_class (0x%x)!\n", i2c_class);
++		return -EINVAL;
++	}
++
++	errorCode = of_property_read_u32(np, "clock-frequency", &pinfo->clk_limit);
++	if (errorCode < 0) {
++		dev_err(&pdev->dev, "Get clock-frequenc failed!\n");
++		return -ENODEV;
++	}
++
++	if (pinfo->clk_limit < 1000 || pinfo->clk_limit > 400000)
++		pinfo->clk_limit = 100000;
++
++	errorCode = of_property_read_u32(np, "amb,duty-cycle", &pinfo->duty_cycle);
++	if (errorCode < 0) {
++		dev_dbg(&pdev->dev, "Missing duty-cycle, assuming 1:1!\n");
++		pinfo->duty_cycle = 0;
++	}
++
++	if (pinfo->duty_cycle > 2)
++		pinfo->duty_cycle = 2;
++
++	errorCode = of_property_read_u32(np, "amb,stretch-scl", &pinfo->stretch_scl);
++	if (errorCode < 0) {
++		dev_dbg(&pdev->dev, "Missing stretch-scl, assuming 1!\n");
++		pinfo->stretch_scl = 1;
++	}
++
++	/* check if using turbo mode */
++	if (of_find_property(pdev->dev.of_node, "amb,turbo-mode", NULL)) {
++		pinfo->turbo_mode = 1;
++		dev_info(&pdev->dev,"Turbo(FIFO) mode is used(ignore device ACK)!\n");
++	} else {
++		pinfo->turbo_mode = 0;
++	}
++
++	init_waitqueue_head(&pinfo->msg_wait);
++	sema_init(&pinfo->system_event_sem, 1);
++
++	ambarella_i2c_hw_init(pinfo);
++
++	platform_set_drvdata(pdev, pinfo);
++
++	errorCode = devm_request_irq(&pdev->dev, pinfo->irq, ambarella_i2c_irq,
++				IRQF_TRIGGER_RISING, dev_name(&pdev->dev), pinfo);
++	if (errorCode) {
++		dev_err(&pdev->dev, "Request IRQ failed!\n");
++		return errorCode;
++	}
++
++	adap = &pinfo->adap;
++	i2c_set_adapdata(adap, pinfo);
++	adap->owner = THIS_MODULE;
++	adap->dev.parent = &pdev->dev;
++	adap->dev.of_node = np;
++	adap->class = i2c_class;
++	strlcpy(adap->name, pdev->name, sizeof(adap->name));
++	adap->algo = &ambarella_i2c_algo;
++	adap->nr = of_alias_get_id(np, "i2c");
++	adap->retries = CONFIG_I2C_AMBARELLA_RETRIES;
++
++	errorCode = i2c_add_numbered_adapter(adap);
++	if (errorCode) {
++		dev_err(&pdev->dev, "Adding I2C adapter failed!\n");
++		return errorCode;
++	}
++
++	of_i2c_register_devices(adap);
++
++	pinfo->system_event.notifier_call = ambarella_i2c_system_event;
++	ambarella_register_event_notifier(&pinfo->system_event);
++
++	dev_info(&pdev->dev, "Ambarella I2C adapter[%d] probed!\n", adap->nr);
++
++	return 0;
++}
++
++static int ambarella_i2c_remove(struct platform_device *pdev)
++{
++	struct ambarella_i2c_dev_info *pinfo;
++	int errorCode = 0;
++
++	pinfo = platform_get_drvdata(pdev);
++	if (pinfo) {
++		ambarella_unregister_event_notifier(&pinfo->system_event);
++		i2c_del_adapter(&pinfo->adap);
++	}
++
++	dev_notice(&pdev->dev,
++		"Remove Ambarella Media Processor I2C adapter[%s] [%d].\n",
++		dev_name(&pinfo->adap.dev), errorCode);
++
++	return errorCode;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_i2c_suspend(struct device *dev)
++{
++	int				errorCode = 0;
++	struct platform_device		*pdev;
++	struct ambarella_i2c_dev_info	*pinfo;
++
++	pdev = to_platform_device(dev);
++	pinfo = platform_get_drvdata(pdev);
++	if (pinfo) {
++		down(&pinfo->system_event_sem);
++		disable_irq(pinfo->irq);
++	}
++
++	dev_dbg(&pdev->dev, "%s\n", __func__);
++
++	return errorCode;
++}
++
++static int ambarella_i2c_resume(struct device *dev)
++{
++	int				errorCode = 0;
++	struct platform_device		*pdev;
++	struct ambarella_i2c_dev_info	*pinfo;
++
++	pdev = to_platform_device(dev);
++	pinfo = platform_get_drvdata(pdev);
++	if (pinfo) {
++		ambarella_i2c_hw_init(pinfo);
++		enable_irq(pinfo->irq);
++		up(&pinfo->system_event_sem);
++	}
++
++	dev_dbg(&pdev->dev, "%s\n", __func__);
++
++	return errorCode;
++}
++
++static const struct dev_pm_ops ambarella_i2c_dev_pm_ops = {
++	.suspend_late = ambarella_i2c_suspend,
++	.resume_early = ambarella_i2c_resume,
++	.freeze = ambarella_i2c_suspend,
++	.thaw = ambarella_i2c_resume,
++};
++#endif
++
++static const struct of_device_id ambarella_i2c_of_match[] = {
++	{.compatible = "ambarella,i2c", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_i2c_of_match);
++
++static struct platform_driver ambarella_i2c_driver = {
++	.probe		= ambarella_i2c_probe,
++	.remove		= ambarella_i2c_remove,
++	.driver		= {
++		.name	= "ambarella-i2c",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_i2c_of_match,
++#ifdef CONFIG_PM
++		.pm	= &ambarella_i2c_dev_pm_ops,
++#endif
++	},
++};
++
++static int __init ambarella_i2c_init(void)
++{
++	return platform_driver_register(&ambarella_i2c_driver);
++}
++
++static void __exit ambarella_i2c_exit(void)
++{
++	platform_driver_unregister(&ambarella_i2c_driver);
++}
++
++subsys_initcall(ambarella_i2c_init);
++module_exit(ambarella_i2c_exit);
++
++MODULE_DESCRIPTION("Ambarella Media Processor I2C Bus Controller");
++MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
+index 4f40a10c..6a4316e4 100644
+--- a/drivers/iio/imu/Kconfig
++++ b/drivers/iio/imu/Kconfig
+@@ -38,3 +38,4 @@ config IIO_ADIS_LIB_BUFFER
+ 	  family.
+ 
+ source "drivers/iio/imu/inv_mpu6050/Kconfig"
++source "drivers/iio/imu/inv_mpu9250/Kconfig"
+diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
+index f2f56cea..8993e588 100644
+--- a/drivers/iio/imu/Makefile
++++ b/drivers/iio/imu/Makefile
+@@ -13,3 +13,4 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
+ obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
+ 
+ obj-y += inv_mpu6050/
++obj-y += inv_mpu9250/
+diff --git a/drivers/iio/imu/inv_mpu9250/Kconfig b/drivers/iio/imu/inv_mpu9250/Kconfig
+new file mode 100644
+index 00000000..eef999c3
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/Kconfig
+@@ -0,0 +1,30 @@
++#
++# inv-mpu9250 drivers for Invensense MPU devices and combos
++#
++
++config INV_MPU9250_IIO
++	tristate
++	select IIO_BUFFER
++	select IIO_TRIGGERED_BUFFER
++
++config INV_MPU9250_I2C
++	tristate "Invensense MPU9250 devices (I2C)"
++	depends on I2C_MUX
++	select INV_MPU9250_IIO
++	select REGMAP_I2C
++	help
++	  This driver supports the Invensense MPU9250 motion tracking
++	  devices over I2C.
++	  This driver can be built as a module. The module will be called
++	  inv-mpu9250-i2c.
++
++config INV_MPU9250_SPI
++	tristate "Invensense MPU9250 devices (SPI)"
++	depends on SPI_MASTER
++	select INV_MPU9250_IIO
++	select REGMAP_SPI
++	help
++	  This driver supports the Invensense MPU9250 motion tracking
++	  devices over SPI.
++	  This driver can be built as a module. The module will be called
++	  inv-mpu9250-spi.
+diff --git a/drivers/iio/imu/inv_mpu9250/Makefile b/drivers/iio/imu/inv_mpu9250/Makefile
+new file mode 100644
+index 00000000..88aa5f70
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/Makefile
+@@ -0,0 +1,12 @@
++#
++# Makefile for Invensense MPU9250 device.
++#
++
++obj-$(CONFIG_INV_MPU9250_IIO) += inv-mpu9250.o
++inv-mpu9250-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
++
++obj-$(CONFIG_INV_MPU9250_I2C) += inv-mpu9250-i2c.o
++inv-mpu9250-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
++
++obj-$(CONFIG_INV_MPU9250_SPI) += inv-mpu9250-spi.o
++inv-mpu9250-spi-objs := inv_mpu_spi.o inv_mpu_i2cmst.o
+\ No newline at end of file
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_acpi.c
+new file mode 100644
+index 00000000..f62b8bd9
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_acpi.c
+@@ -0,0 +1,213 @@
++/*
++ * inv_mpu_acpi: ACPI processing for creating client devices
++ * Copyright (c) 2015, Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ */
++
++#ifdef CONFIG_ACPI
++
++#include <linux/kernel.h>
++#include <linux/i2c.h>
++#include <linux/dmi.h>
++#include <linux/acpi.h>
++#include "inv_mpu_iio.h"
++
++enum inv_mpu_product_name {
++	INV_MPU_NOT_MATCHED,
++	INV_MPU_ASUS_T100TA,
++};
++
++static enum inv_mpu_product_name matched_product_name;
++
++static int __init asus_t100_matched(const struct dmi_system_id *d)
++{
++	matched_product_name = INV_MPU_ASUS_T100TA;
++
++	return 0;
++}
++
++static const struct dmi_system_id inv_mpu_dev_list[] = {
++	{
++	.callback = asus_t100_matched,
++	.ident = "Asus Transformer Book T100",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
++			DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
++		},
++	},
++	/* Add more matching tables here..*/
++	{}
++};
++
++static int asus_acpi_get_sensor_info(struct acpi_device *adev,
++				     struct i2c_client *client,
++				     struct i2c_board_info *info)
++{
++	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
++	int i;
++	acpi_status status;
++	union acpi_object *cpm;
++
++	status = acpi_evaluate_object(adev->handle, "CNF0", NULL, &buffer);
++	if (ACPI_FAILURE(status))
++		return -ENODEV;
++
++	cpm = buffer.pointer;
++	for (i = 0; i < cpm->package.count; ++i) {
++		union acpi_object *elem;
++		int j;
++
++		elem = &cpm->package.elements[i];
++		for (j = 0; j < elem->package.count; ++j) {
++			union acpi_object *sub_elem;
++
++			sub_elem = &elem->package.elements[j];
++			if (sub_elem->type == ACPI_TYPE_STRING)
++				strlcpy(info->type, sub_elem->string.pointer,
++					sizeof(info->type));
++			else if (sub_elem->type == ACPI_TYPE_INTEGER) {
++				if (sub_elem->integer.value != client->addr) {
++					info->addr = sub_elem->integer.value;
++					break; /* Not a MPU6500 primary */
++				}
++			}
++		}
++	}
++
++	kfree(buffer.pointer);
++
++	return cpm->package.count;
++}
++
++static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data)
++{
++	u32 *addr = data;
++
++	if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
++		struct acpi_resource_i2c_serialbus *sb;
++
++		sb = &ares->data.i2c_serial_bus;
++		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
++			if (*addr)
++				*addr |= (sb->slave_address << 16);
++			else
++				*addr = sb->slave_address;
++		}
++	}
++
++	/* Tell the ACPI core that we already copied this address */
++	return 1;
++}
++
++static int inv_mpu_process_acpi_config(struct i2c_client *client,
++				       unsigned short *primary_addr,
++				       unsigned short *secondary_addr)
++{
++	const struct acpi_device_id *id;
++	struct acpi_device *adev;
++	u32 i2c_addr = 0;
++	LIST_HEAD(resources);
++	int ret;
++
++	id = acpi_match_device(client->dev.driver->acpi_match_table,
++			       &client->dev);
++	if (!id)
++		return -ENODEV;
++
++	adev = ACPI_COMPANION(&client->dev);
++	if (!adev)
++		return -ENODEV;
++
++	ret = acpi_dev_get_resources(adev, &resources,
++				     acpi_i2c_check_resource, &i2c_addr);
++	if (ret < 0)
++		return ret;
++
++	acpi_dev_free_resource_list(&resources);
++	*primary_addr = i2c_addr & 0x0000ffff;
++	*secondary_addr = (i2c_addr & 0xffff0000) >> 16;
++
++	return 0;
++}
++
++int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
++{
++	struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
++
++	st->mux_client = NULL;
++	if (ACPI_HANDLE(&client->dev)) {
++		struct i2c_board_info info;
++		struct acpi_device *adev;
++		int ret = -1;
++
++		adev = ACPI_COMPANION(&client->dev);
++		memset(&info, 0, sizeof(info));
++
++		dmi_check_system(inv_mpu_dev_list);
++		switch (matched_product_name) {
++		case INV_MPU_ASUS_T100TA:
++			ret = asus_acpi_get_sensor_info(adev, client,
++							&info);
++			break;
++		/* Add more matched product processing here */
++		default:
++			break;
++		}
++
++		if (ret < 0) {
++			/* No matching DMI, so create device on INV6XX type */
++			unsigned short primary, secondary;
++
++			ret = inv_mpu_process_acpi_config(client, &primary,
++							  &secondary);
++			if (!ret && secondary) {
++				char *name;
++
++				info.addr = secondary;
++				strlcpy(info.type, dev_name(&adev->dev),
++					sizeof(info.type));
++				name = strchr(info.type, ':');
++				if (name)
++					*name = '\0';
++				strlcat(info.type, "-client",
++					sizeof(info.type));
++			} else
++				return 0; /* no secondary addr, which is OK */
++		}
++		st->mux_client = i2c_new_device(st->muxc->adapter[0], &info);
++		if (!st->mux_client)
++			return -ENODEV;
++	}
++
++	return 0;
++}
++
++void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
++{
++	struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
++
++	if (st->mux_client)
++		i2c_unregister_device(st->mux_client);
++}
++#else
++
++#include "inv_mpu_iio.h"
++
++int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
++{
++	return 0;
++}
++
++void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
++{
++}
++#endif
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_core.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_core.c
+new file mode 100644
+index 00000000..a2c8afb6
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_core.c
+@@ -0,0 +1,932 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/sysfs.h>
++#include <linux/jiffies.h>
++#include <linux/irq.h>
++#include <linux/regmap.h>
++#include <linux/interrupt.h>
++#include <linux/kfifo.h>
++#include <linux/spinlock.h>
++#include <linux/iio/iio.h>
++#include <linux/acpi.h>
++#include "inv_mpu_iio.h"
++
++/*
++ * this is the gyro scale translated from dynamic range plus/minus
++ * {250, 500, 1000, 2000} to rad/s
++ */
++static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724};
++
++/*
++ * this is the accel scale translated from dynamic range plus/minus
++ * {2, 4, 8, 16} to m/s^2
++ */
++static const int accel_scale[] = {598, 1196, 2392, 4785};
++
++static const struct inv_mpu6050_reg_map reg_set_6500 = {
++	.sample_rate_div	= INV_MPU6050_REG_SAMPLE_RATE_DIV,
++	.lpf                    = INV_MPU6050_REG_CONFIG,
++	.user_ctrl              = INV_MPU6050_REG_USER_CTRL,
++	.fifo_en                = INV_MPU6050_REG_FIFO_EN,
++	.gyro_config            = INV_MPU6050_REG_GYRO_CONFIG,
++	.accl_config            = INV_MPU6050_REG_ACCEL_CONFIG,
++	.fifo_count_h           = INV_MPU6050_REG_FIFO_COUNT_H,
++	.fifo_r_w               = INV_MPU6050_REG_FIFO_R_W,
++	.raw_gyro               = INV_MPU6050_REG_RAW_GYRO,
++	.raw_accl               = INV_MPU6050_REG_RAW_ACCEL,
++	.temperature            = INV_MPU6050_REG_TEMPERATURE,
++	.int_enable             = INV_MPU6050_REG_INT_ENABLE,
++	.pwr_mgmt_1             = INV_MPU6050_REG_PWR_MGMT_1,
++	.pwr_mgmt_2             = INV_MPU6050_REG_PWR_MGMT_2,
++	.int_pin_cfg		= INV_MPU6050_REG_INT_PIN_CFG,
++	.accl_offset		= INV_MPU6500_REG_ACCEL_OFFSET,
++	.gyro_offset		= INV_MPU6050_REG_GYRO_OFFSET,
++};
++
++static const struct inv_mpu6050_reg_map reg_set_6050 = {
++	.sample_rate_div	= INV_MPU6050_REG_SAMPLE_RATE_DIV,
++	.lpf                    = INV_MPU6050_REG_CONFIG,
++	.user_ctrl              = INV_MPU6050_REG_USER_CTRL,
++	.fifo_en                = INV_MPU6050_REG_FIFO_EN,
++	.gyro_config            = INV_MPU6050_REG_GYRO_CONFIG,
++	.accl_config            = INV_MPU6050_REG_ACCEL_CONFIG,
++	.fifo_count_h           = INV_MPU6050_REG_FIFO_COUNT_H,
++	.fifo_r_w               = INV_MPU6050_REG_FIFO_R_W,
++	.raw_gyro               = INV_MPU6050_REG_RAW_GYRO,
++	.raw_accl               = INV_MPU6050_REG_RAW_ACCEL,
++	.temperature            = INV_MPU6050_REG_TEMPERATURE,
++	.int_enable             = INV_MPU6050_REG_INT_ENABLE,
++	.pwr_mgmt_1             = INV_MPU6050_REG_PWR_MGMT_1,
++	.pwr_mgmt_2             = INV_MPU6050_REG_PWR_MGMT_2,
++	.int_pin_cfg		= INV_MPU6050_REG_INT_PIN_CFG,
++	.accl_offset		= INV_MPU6050_REG_ACCEL_OFFSET,
++	.gyro_offset		= INV_MPU6050_REG_GYRO_OFFSET,
++};
++
++static const struct inv_mpu6050_chip_config chip_config_6050 = {
++	.fsr = INV_MPU6050_FSR_2000DPS,
++	.lpf = INV_MPU6050_FILTER_20HZ,
++	.fifo_rate = INV_MPU6050_INIT_FIFO_RATE,
++	.gyro_fifo_enable = false,
++	.accl_fifo_enable = false,
++	.accl_fs = INV_MPU6050_FS_02G,
++};
++
++/* Indexed by enum inv_devices */
++static const struct inv_mpu6050_hw hw_info[] = {
++	{
++		.whoami = INV_MPU6050_WHOAMI_VALUE,
++		.name = "MPU6050",
++		.reg = &reg_set_6050,
++		.config = &chip_config_6050,
++	},
++	{
++		.whoami = INV_MPU6500_WHOAMI_VALUE,
++		.name = "MPU6500",
++		.reg = &reg_set_6500,
++		.config = &chip_config_6050,
++	},
++	{
++		.whoami = INV_MPU6000_WHOAMI_VALUE,
++		.name = "MPU6000",
++		.reg = &reg_set_6050,
++		.config = &chip_config_6050,
++	},
++	{
++		.whoami = INV_MPU9150_WHOAMI_VALUE,
++		.name = "MPU9150",
++		.reg = &reg_set_6050,
++		.config = &chip_config_6050,
++	},
++	{
++		.whoami = INV_MPU9250_WHOAMI_VALUE,
++		.name = "MPU9250",
++		.reg = &reg_set_6500,
++		.config = &chip_config_6050,
++	},
++};
++
++int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
++{
++	unsigned int d, mgmt_1;
++	int result;
++	/*
++	 * switch clock needs to be careful. Only when gyro is on, can
++	 * clock source be switched to gyro. Otherwise, it must be set to
++	 * internal clock
++	 */
++	if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) {
++		result = regmap_read(st->map, st->reg->pwr_mgmt_1, &mgmt_1);
++		if (result)
++			return result;
++
++		mgmt_1 &= ~INV_MPU6050_BIT_CLK_MASK;
++	}
++
++	if ((mask == INV_MPU6050_BIT_PWR_GYRO_STBY) && (!en)) {
++		/*
++		 * turning off gyro requires switch to internal clock first.
++		 * Then turn off gyro engine
++		 */
++		mgmt_1 |= INV_CLK_INTERNAL;
++		result = regmap_write(st->map, st->reg->pwr_mgmt_1, mgmt_1);
++		if (result)
++			return result;
++	}
++
++	result = regmap_read(st->map, st->reg->pwr_mgmt_2, &d);
++	if (result)
++		return result;
++	if (en)
++		d &= ~mask;
++	else
++		d |= mask;
++	result = regmap_write(st->map, st->reg->pwr_mgmt_2, d);
++	if (result)
++		return result;
++
++	if (en) {
++		/* Wait for output stabilize */
++		msleep(INV_MPU6050_TEMP_UP_TIME);
++		if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) {
++			/* switch internal clock to PLL */
++			mgmt_1 |= INV_CLK_PLL;
++			result = regmap_write(st->map,
++					      st->reg->pwr_mgmt_1, mgmt_1);
++			if (result)
++				return result;
++		}
++	}
++
++	return 0;
++}
++
++int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
++{
++	int result = 0;
++
++	if (power_on) {
++		/* Already under indio-dev->mlock mutex */
++		if (!st->powerup_count)
++			result = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
++		if (!result)
++			st->powerup_count++;
++	} else {
++		st->powerup_count--;
++		if (!st->powerup_count)
++			result = regmap_write(st->map, st->reg->pwr_mgmt_1,
++					      INV_MPU6050_BIT_SLEEP);
++	}
++
++	if (result)
++		return result;
++
++	if (power_on)
++		usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
++			     INV_MPU6050_REG_UP_TIME_MAX);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(inv_mpu6050_set_power_itg);
++
++/**
++ *  inv_mpu6050_init_config() - Initialize hardware, disable FIFO.
++ *
++ *  Initial configuration:
++ *  FSR: ± 2000DPS
++ *  DLPF: 20Hz
++ *  FIFO rate: 50Hz
++ *  Clock source: Gyro PLL
++ */
++static int inv_mpu6050_init_config(struct iio_dev *indio_dev)
++{
++	int result;
++	u8 d;
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++	result = inv_mpu6050_set_power_itg(st, true);
++	if (result)
++		return result;
++	d = (INV_MPU6050_FSR_2000DPS << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
++	result = regmap_write(st->map, st->reg->gyro_config, d);
++	if (result)
++		return result;
++
++	d = INV_MPU6050_FILTER_20HZ;
++	result = regmap_write(st->map, st->reg->lpf, d);
++	if (result)
++		return result;
++
++	d = INV_MPU6050_ONE_K_HZ / INV_MPU6050_INIT_FIFO_RATE - 1;
++	result = regmap_write(st->map, st->reg->sample_rate_div, d);
++	if (result)
++		return result;
++
++	d = (INV_MPU6050_FS_02G << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
++	result = regmap_write(st->map, st->reg->accl_config, d);
++	if (result)
++		return result;
++
++	memcpy(&st->chip_config, hw_info[st->chip_type].config,
++	       sizeof(struct inv_mpu6050_chip_config));
++	result = inv_mpu6050_set_power_itg(st, false);
++
++	return result;
++}
++
++static int inv_mpu6050_sensor_set(struct inv_mpu6050_state  *st, int reg,
++				int axis, int val)
++{
++	int ind, result;
++	__be16 d = cpu_to_be16(val);
++
++	ind = (axis - IIO_MOD_X) * 2;
++	result = regmap_bulk_write(st->map, reg + ind, (u8 *)&d, 2);
++	if (result)
++		return -EINVAL;
++
++	return 0;
++}
++
++static int inv_mpu6050_sensor_show(struct inv_mpu6050_state  *st, int reg,
++				   int axis, int *val)
++{
++	int ind, result;
++	__be16 d;
++
++	ind = (axis - IIO_MOD_X) * 2;
++	result = regmap_bulk_read(st->map, reg + ind, (u8 *)&d, 2);
++	if (result)
++		return -EINVAL;
++	*val = (short)be16_to_cpup(&d);
++
++	return IIO_VAL_INT;
++}
++
++static int
++inv_mpu6050_read_raw(struct iio_dev *indio_dev,
++		     struct iio_chan_spec const *chan,
++		     int *val, int *val2, long mask)
++{
++	struct inv_mpu6050_state  *st = iio_priv(indio_dev);
++	int ret = 0;
++
++	switch (mask) {
++	case IIO_CHAN_INFO_RAW:
++	{
++		int result;
++
++		ret = IIO_VAL_INT;
++		result = 0;
++		mutex_lock(&indio_dev->mlock);
++		if (!st->chip_config.enable) {
++			result = inv_mpu6050_set_power_itg(st, true);
++			if (result)
++				goto error_read_raw;
++		}
++		/* when enable is on, power is already on */
++		switch (chan->type) {
++		case IIO_ANGL_VEL:
++			if (!st->chip_config.gyro_fifo_enable ||
++			    !st->chip_config.enable) {
++				result = inv_mpu6050_switch_engine(st, true,
++						INV_MPU6050_BIT_PWR_GYRO_STBY);
++				if (result)
++					goto error_read_raw;
++			}
++			ret = inv_mpu6050_sensor_show(st, st->reg->raw_gyro,
++						      chan->channel2, val);
++			if (!st->chip_config.gyro_fifo_enable ||
++			    !st->chip_config.enable) {
++				result = inv_mpu6050_switch_engine(st, false,
++						INV_MPU6050_BIT_PWR_GYRO_STBY);
++				if (result)
++					goto error_read_raw;
++			}
++			break;
++		case IIO_ACCEL:
++			if (!st->chip_config.accl_fifo_enable ||
++			    !st->chip_config.enable) {
++				result = inv_mpu6050_switch_engine(st, true,
++						INV_MPU6050_BIT_PWR_ACCL_STBY);
++				if (result)
++					goto error_read_raw;
++			}
++			ret = inv_mpu6050_sensor_show(st, st->reg->raw_accl,
++						      chan->channel2, val);
++			if (!st->chip_config.accl_fifo_enable ||
++			    !st->chip_config.enable) {
++				result = inv_mpu6050_switch_engine(st, false,
++						INV_MPU6050_BIT_PWR_ACCL_STBY);
++				if (result)
++					goto error_read_raw;
++			}
++			break;
++		case IIO_TEMP:
++			if (!st->chip_config.enable) {
++				result = inv_mpu6050_switch_engine(st, true,
++                                                INV_MPU6050_BIT_PWR_TEMP_STBY);
++                                if (result)
++                                        goto error_read_raw;
++                        }
++			/* wait for stablization */
++			msleep(INV_MPU6050_SENSOR_UP_TIME);
++			ret = inv_mpu6050_sensor_show(st, st->reg->temperature,
++						IIO_MOD_X, val);
++			if (!st->chip_config.enable) {
++                                result = inv_mpu6050_switch_engine(st, false,
++                                                INV_MPU6050_BIT_PWR_TEMP_STBY);
++                                if (result)
++                                        goto error_read_raw;
++                        }
++			break;
++		default:
++			ret = -EINVAL;
++			break;
++		}
++error_read_raw:
++		if (!st->chip_config.enable)
++			result |= inv_mpu6050_set_power_itg(st, false);
++		mutex_unlock(&indio_dev->mlock);
++		if (result)
++			return result;
++
++		return ret;
++	}
++	case IIO_CHAN_INFO_SCALE:
++		switch (chan->type) {
++		case IIO_ANGL_VEL:
++			*val  = 0;
++			*val2 = gyro_scale_6050[st->chip_config.fsr];
++
++			return IIO_VAL_INT_PLUS_NANO;
++		case IIO_ACCEL:
++			*val = 0;
++			*val2 = accel_scale[st->chip_config.accl_fs];
++
++			return IIO_VAL_INT_PLUS_MICRO;
++		case IIO_TEMP:
++			*val = 0;
++			*val2 = INV_MPU6050_TEMP_SCALE;
++
++			return IIO_VAL_INT_PLUS_MICRO;
++		default:
++			return -EINVAL;
++		}
++	case IIO_CHAN_INFO_OFFSET:
++		switch (chan->type) {
++		case IIO_TEMP:
++			*val = INV_MPU6050_TEMP_OFFSET;
++
++			return IIO_VAL_INT;
++		default:
++			return -EINVAL;
++		}
++	case IIO_CHAN_INFO_CALIBBIAS:
++		switch (chan->type) {
++		case IIO_ANGL_VEL:
++			ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset,
++						chan->channel2, val);
++			return IIO_VAL_INT;
++		case IIO_ACCEL:
++			ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset,
++						chan->channel2, val);
++			return IIO_VAL_INT;
++
++		default:
++			return -EINVAL;
++		}
++	default:
++		return -EINVAL;
++	}
++}
++
++static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val)
++{
++	int result, i;
++	u8 d;
++
++	for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
++		if (gyro_scale_6050[i] == val) {
++			d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
++			result = regmap_write(st->map, st->reg->gyro_config, d);
++			if (result)
++				return result;
++
++			st->chip_config.fsr = i;
++			return 0;
++		}
++	}
++
++	return -EINVAL;
++}
++
++static int inv_write_raw_get_fmt(struct iio_dev *indio_dev,
++				 struct iio_chan_spec const *chan, long mask)
++{
++	switch (mask) {
++	case IIO_CHAN_INFO_SCALE:
++		switch (chan->type) {
++		case IIO_ANGL_VEL:
++			return IIO_VAL_INT_PLUS_NANO;
++		default:
++			return IIO_VAL_INT_PLUS_MICRO;
++		}
++	default:
++		return IIO_VAL_INT_PLUS_MICRO;
++	}
++
++	return -EINVAL;
++}
++
++static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val)
++{
++	int result, i;
++	u8 d;
++
++	for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
++		if (accel_scale[i] == val) {
++			d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
++			result = regmap_write(st->map, st->reg->accl_config, d);
++			if (result)
++				return result;
++
++			st->chip_config.accl_fs = i;
++			return 0;
++		}
++	}
++
++	return -EINVAL;
++}
++
++static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
++				 struct iio_chan_spec const *chan,
++				 int val, int val2, long mask)
++{
++	struct inv_mpu6050_state  *st = iio_priv(indio_dev);
++	int result;
++
++	mutex_lock(&indio_dev->mlock);
++	/*
++	 * we should only update scale when the chip is disabled, i.e.
++	 * not running
++	 */
++	if (st->chip_config.enable) {
++		result = -EBUSY;
++		goto error_write_raw;
++	}
++	result = inv_mpu6050_set_power_itg(st, true);
++	if (result)
++		goto error_write_raw;
++
++	switch (mask) {
++	case IIO_CHAN_INFO_SCALE:
++		switch (chan->type) {
++		case IIO_ANGL_VEL:
++			result = inv_mpu6050_write_gyro_scale(st, val2);
++			break;
++		case IIO_ACCEL:
++			result = inv_mpu6050_write_accel_scale(st, val2);
++			break;
++		default:
++			result = -EINVAL;
++			break;
++		}
++		break;
++	case IIO_CHAN_INFO_CALIBBIAS:
++		switch (chan->type) {
++		case IIO_ANGL_VEL:
++			result = inv_mpu6050_sensor_set(st,
++							st->reg->gyro_offset,
++							chan->channel2, val);
++			break;
++		case IIO_ACCEL:
++			result = inv_mpu6050_sensor_set(st,
++							st->reg->accl_offset,
++							chan->channel2, val);
++			break;
++		default:
++			result = -EINVAL;
++		}
++	default:
++		result = -EINVAL;
++		break;
++	}
++
++error_write_raw:
++	result |= inv_mpu6050_set_power_itg(st, false);
++	mutex_unlock(&indio_dev->mlock);
++
++	return result;
++}
++
++/**
++ *  inv_mpu6050_set_lpf() - set low pass filer based on fifo rate.
++ *
++ *                  Based on the Nyquist principle, the sampling rate must
++ *                  exceed twice of the bandwidth of the signal, or there
++ *                  would be alising. This function basically search for the
++ *                  correct low pass parameters based on the fifo rate, e.g,
++ *                  sampling frequency.
++ */
++static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
++{
++	const int hz[] = {188, 98, 42, 20, 10, 5};
++	const int d[] = {INV_MPU6050_FILTER_188HZ, INV_MPU6050_FILTER_98HZ,
++			INV_MPU6050_FILTER_42HZ, INV_MPU6050_FILTER_20HZ,
++			INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ};
++	int i, h, result;
++	u8 data;
++
++	h = (rate >> 1);
++	i = 0;
++	while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
++		i++;
++	data = d[i];
++	result = regmap_write(st->map, st->reg->lpf, data);
++	if (result)
++		return result;
++	st->chip_config.lpf = data;
++
++	return 0;
++}
++
++/**
++ * inv_mpu6050_fifo_rate_store() - Set fifo rate.
++ */
++static ssize_t
++inv_mpu6050_fifo_rate_store(struct device *dev, struct device_attribute *attr,
++			    const char *buf, size_t count)
++{
++	s32 fifo_rate;
++	u8 d;
++	int result;
++	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++	if (kstrtoint(buf, 10, &fifo_rate))
++		return -EINVAL;
++	if (fifo_rate < INV_MPU6050_MIN_FIFO_RATE ||
++	    fifo_rate > INV_MPU6050_MAX_FIFO_RATE)
++		return -EINVAL;
++	if (fifo_rate == st->chip_config.fifo_rate)
++		return count;
++
++	mutex_lock(&indio_dev->mlock);
++	if (st->chip_config.enable) {
++		result = -EBUSY;
++		goto fifo_rate_fail;
++	}
++	result = inv_mpu6050_set_power_itg(st, true);
++	if (result)
++		goto fifo_rate_fail;
++
++	d = INV_MPU6050_ONE_K_HZ / fifo_rate - 1;
++	result = regmap_write(st->map, st->reg->sample_rate_div, d);
++	if (result)
++		goto fifo_rate_fail;
++	st->chip_config.fifo_rate = fifo_rate;
++
++	result = inv_mpu6050_set_lpf(st, fifo_rate);
++	if (result)
++		goto fifo_rate_fail;
++
++fifo_rate_fail:
++	result |= inv_mpu6050_set_power_itg(st, false);
++	mutex_unlock(&indio_dev->mlock);
++	if (result)
++		return result;
++
++	return count;
++}
++
++/**
++ * inv_fifo_rate_show() - Get the current sampling rate.
++ */
++static ssize_t
++inv_fifo_rate_show(struct device *dev, struct device_attribute *attr,
++		   char *buf)
++{
++	struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev));
++
++	return sprintf(buf, "%d\n", st->chip_config.fifo_rate);
++}
++
++/**
++ * inv_attr_show() - calling this function will show current
++ *                    parameters.
++ */
++static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr,
++			     char *buf)
++{
++	struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev));
++	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
++	const char **m;
++
++	switch (this_attr->address) {
++	/*
++	 * In MPU6050, the two matrix are the same because gyro and accel
++	 * are integrated in one chip
++	 */
++	case ATTR_GYRO_MATRIX:
++	case ATTR_ACCL_MATRIX:
++		m = st->orientation.rotation;
++
++		return sprintf(buf, "%s, %s, %s; %s, %s, %s; %s, %s, %s\n",
++			m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
++	default:
++		return -EINVAL;
++	}
++}
++
++/**
++ * inv_mpu6050_validate_trigger() - validate_trigger callback for invensense
++ *                                  MPU6050 device.
++ * @indio_dev: The IIO device
++ * @trig: The new trigger
++ *
++ * Returns: 0 if the 'trig' matches the trigger registered by the MPU6050
++ * device, -EINVAL otherwise.
++ */
++static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev,
++					struct iio_trigger *trig)
++{
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++	if (st->trig != trig)
++		return -EINVAL;
++
++	return 0;
++}
++
++#define INV_MPU6050_CHAN(_type, _channel2, _index)                    \
++	{                                                             \
++		.type = _type,                                        \
++		.modified = 1,                                        \
++		.channel2 = _channel2,                                \
++		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
++		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	      \
++				      BIT(IIO_CHAN_INFO_CALIBBIAS),   \
++		.scan_index = _index,                                 \
++		.scan_type = {                                        \
++				.sign = 's',                          \
++				.realbits = 16,                       \
++				.storagebits = 16,                    \
++				.shift = 0,                           \
++				.endianness = IIO_BE,                 \
++			     },                                       \
++	}
++
++static const struct iio_chan_spec inv_mpu_channels[] = {
++	IIO_CHAN_SOFT_TIMESTAMP(INV_MPU6050_SCAN_TIMESTAMP),
++	/*
++	 * Note that temperature should only be via polled reading only,
++	 * not the final scan elements output.
++	 */
++	{
++		.type = IIO_TEMP,
++		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
++				| BIT(IIO_CHAN_INFO_OFFSET)
++				| BIT(IIO_CHAN_INFO_SCALE),
++		.scan_index = -1,
++	},
++	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
++	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
++	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
++
++	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
++	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
++	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
++};
++
++/* constant IIO attribute */
++static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
++static IIO_CONST_ATTR(in_anglvel_scale_available,
++					  "0.000133090 0.000266181 0.000532362 0.001064724");
++static IIO_CONST_ATTR(in_accel_scale_available,
++					  "0.000598 0.001196 0.002392 0.004785");
++static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
++	inv_mpu6050_fifo_rate_store);
++
++/* Deprecated: kept for userspace backward compatibility. */
++static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
++	ATTR_GYRO_MATRIX);
++static IIO_DEVICE_ATTR(in_accel_matrix, S_IRUGO, inv_attr_show, NULL,
++	ATTR_ACCL_MATRIX);
++
++static struct attribute *inv_attributes[] = {
++	&iio_dev_attr_in_gyro_matrix.dev_attr.attr,  /* deprecated */
++	&iio_dev_attr_in_accel_matrix.dev_attr.attr, /* deprecated */
++	&iio_dev_attr_sampling_frequency.dev_attr.attr,
++	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
++	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
++	&iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
++	NULL,
++};
++
++static const struct attribute_group inv_attribute_group = {
++	.attrs = inv_attributes
++};
++
++static const struct iio_info mpu_info = {
++	.driver_module = THIS_MODULE,
++	.read_raw = &inv_mpu6050_read_raw,
++	.write_raw = &inv_mpu6050_write_raw,
++	.write_raw_get_fmt = &inv_write_raw_get_fmt,
++	.attrs = &inv_attribute_group,
++	.validate_trigger = inv_mpu6050_validate_trigger,
++};
++
++/**
++ *  inv_check_and_setup_chip() - check and setup chip.
++ */
++static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
++{
++	int result;
++	unsigned int regval;
++
++	st->hw  = &hw_info[st->chip_type];
++	st->reg = hw_info[st->chip_type].reg;
++
++	/* reset to make sure previous state are not there */
++	result = regmap_write(st->map, st->reg->pwr_mgmt_1,
++			      INV_MPU6050_BIT_H_RESET);
++	if (result)
++		return result;
++	msleep(INV_MPU6050_POWER_UP_TIME);
++
++	/* check chip self-identification */
++	result = regmap_read(st->map, INV_MPU6050_REG_WHOAMI, &regval);
++	if (result)
++		return result;
++	if (regval != st->hw->whoami) {
++		dev_warn(st->dev,
++				"whoami mismatch got %#02x expected %#02hhx for %s\n",
++				regval, st->hw->whoami, st->hw->name);
++	}
++
++	/*
++	 * toggle power state. After reset, the sleep bit could be on
++	 * or off depending on the OTP settings. Toggling power would
++	 * make it in a definite state as well as making the hardware
++	 * state align with the software state
++	 */
++	result = inv_mpu6050_set_power_itg(st, false);
++	if (result)
++		return result;
++	result = inv_mpu6050_set_power_itg(st, true);
++	if (result)
++		return result;
++
++	result = inv_mpu6050_switch_engine(st, false,
++					   INV_MPU6050_BIT_PWR_ACCL_STBY);
++	if (result)
++		return result;
++	result = inv_mpu6050_switch_engine(st, false,
++					   INV_MPU6050_BIT_PWR_GYRO_STBY);
++	if (result)
++		return result;
++
++	return 0;
++}
++
++int inv_mpu_core_probe(struct device *dev, struct regmap *regmap, int irq, const char *name,
++		int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type)
++{
++	struct inv_mpu6050_state *st;
++	struct iio_dev *indio_dev;
++	int result;
++
++	indio_dev = iio_device_alloc(sizeof(*st));
++	if (!indio_dev)
++		return -ENOMEM;
++
++	BUILD_BUG_ON(ARRAY_SIZE(hw_info) != INV_NUM_PARTS);
++	if (chip_type < 0 || chip_type >= INV_NUM_PARTS) {
++		dev_err(dev, "Bad invensense chip_type=%d name=%s\n",
++				chip_type, name);
++		return -ENODEV;
++	}
++	st = iio_priv(indio_dev);
++	st->chip_type = chip_type;
++	st->powerup_count = 0;
++	st->irq = irq;
++	st->map = regmap;
++	st->dev = dev;
++
++	result = of_property_read_string_array(dev->of_node,
++			"mount-matrix", st->orientation.rotation,
++			ARRAY_SIZE(st->orientation.rotation));
++
++	if (result != ARRAY_SIZE(st->orientation.rotation)) {
++		dev_err(dev, "Failed to retrieve mounting matrix %d\n", result);
++		return result;
++	}
++
++	/* power is turned on inside check chip type*/
++	result = inv_check_and_setup_chip(st);
++	if (result)
++		return result;
++
++	if (inv_mpu_bus_setup)
++		inv_mpu_bus_setup(indio_dev);
++
++	result = inv_mpu6050_init_config(indio_dev);
++	if (result) {
++		dev_err(dev, "Could not initialize device.\n");
++		return result;
++	}
++
++	dev_set_drvdata(dev, indio_dev);
++	indio_dev->dev.parent = dev;
++	/* name will be NULL when enumerated via ACPI */
++	if (name)
++		indio_dev->name = name;
++	else
++		indio_dev->name = dev_name(dev);
++	indio_dev->channels = inv_mpu_channels;
++	indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
++
++	indio_dev->info = &mpu_info;
++	indio_dev->modes = INDIO_BUFFER_TRIGGERED;
++
++	result = iio_triggered_buffer_setup(indio_dev,
++					    inv_mpu6050_irq_handler,
++					    inv_mpu6050_read_fifo,
++					    NULL);
++	if (result) {
++		dev_err(dev, "configure buffer fail %d\n", result);
++		return result;
++	}
++	result = inv_mpu6050_probe_trigger(indio_dev);
++	if (result) {
++		dev_err(dev, "trigger probe fail %d\n", result);
++		goto out_unreg_ring;
++	}
++
++	INIT_KFIFO(st->timestamps);
++	spin_lock_init(&st->time_stamp_lock);
++	result = iio_device_register(indio_dev);
++	if (result) {
++		dev_err(dev, "IIO register fail %d\n", result);
++		goto out_remove_trigger;
++	}
++
++	return 0;
++
++out_remove_trigger:
++	inv_mpu6050_remove_trigger(st);
++out_unreg_ring:
++	iio_triggered_buffer_cleanup(indio_dev);
++	return result;
++}
++EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
++
++int inv_mpu_core_remove(struct device  *dev)
++{
++	struct iio_dev *indio_dev = dev_get_drvdata(dev);
++
++	iio_device_unregister(indio_dev);
++	inv_mpu6050_remove_trigger(iio_priv(indio_dev));
++	iio_triggered_buffer_cleanup(indio_dev);
++	iio_device_free(indio_dev);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(inv_mpu_core_remove);
++
++#ifdef CONFIG_PM_SLEEP
++
++static int inv_mpu_resume(struct device *dev)
++{
++	return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), true);
++}
++
++static int inv_mpu_suspend(struct device *dev)
++{
++	return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), false);
++}
++#endif /* CONFIG_PM_SLEEP */
++
++SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
++EXPORT_SYMBOL_GPL(inv_mpu_pmops);
++
++MODULE_AUTHOR("Invensense Corporation");
++MODULE_DESCRIPTION("Invensense device MPU6050 driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2c.c
+new file mode 100644
+index 00000000..6b44d292
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2c.c
+@@ -0,0 +1,201 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++
++#include <linux/acpi.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/iio/iio.h>
++#include <linux/module.h>
++#include "inv_mpu_iio.h"
++
++static const struct regmap_config inv_mpu_regmap_config = {
++	.reg_bits = 8,
++	.val_bits = 8,
++};
++
++static int inv_mpu6050_select_bypass(struct i2c_mux_core *muxc, u32 chan_id)
++{
++	struct iio_dev *indio_dev = i2c_mux_priv(muxc);
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	int ret = 0;
++
++	/* Use the same mutex which was used everywhere to protect power-op */
++	mutex_lock(&indio_dev->mlock);
++	if (!st->powerup_count) {
++		ret = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
++		if (ret)
++			goto write_error;
++
++		usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
++			     INV_MPU6050_REG_UP_TIME_MAX);
++	}
++	if (!ret) {
++		st->powerup_count++;
++		ret = regmap_write(st->map, st->reg->int_pin_cfg,
++				   INV_MPU6050_INT_PIN_CFG |
++				   INV_MPU6050_BIT_BYPASS_EN);
++	}
++write_error:
++	mutex_unlock(&indio_dev->mlock);
++
++	return ret;
++}
++
++static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id)
++{
++	struct iio_dev *indio_dev = i2c_mux_priv(muxc);
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++	mutex_lock(&indio_dev->mlock);
++	/* It doesn't really mattter, if any of the calls fails */
++	regmap_write(st->map, st->reg->int_pin_cfg, INV_MPU6050_INT_PIN_CFG);
++	st->powerup_count--;
++	if (!st->powerup_count)
++		regmap_write(st->map, st->reg->pwr_mgmt_1,
++			     INV_MPU6050_BIT_SLEEP);
++	mutex_unlock(&indio_dev->mlock);
++
++	return 0;
++}
++
++static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id)
++{
++	const struct acpi_device_id *id;
++
++	id = acpi_match_device(dev->driver->acpi_match_table, dev);
++	if (!id)
++		return NULL;
++
++	*chip_id = (int)id->driver_data;
++
++	return dev_name(dev);
++}
++
++/**
++ *  inv_mpu_probe() - probe function.
++ *  @client:          i2c client.
++ *  @id:              i2c device id.
++ *
++ *  Returns 0 on success, a negative error code otherwise.
++ */
++static int inv_mpu_probe(struct i2c_client *client,
++			 const struct i2c_device_id *id)
++{
++	struct inv_mpu6050_state *st;
++	int result, chip_type;
++	struct regmap *regmap;
++	const char *name;
++
++	if (!i2c_check_functionality(client->adapter,
++				     I2C_FUNC_SMBUS_I2C_BLOCK))
++		return -EOPNOTSUPP;
++
++	if (id) {
++		chip_type = (int)id->driver_data;
++		name = id->name;
++	} else if (ACPI_HANDLE(&client->dev)) {
++		name = inv_mpu_match_acpi_device(&client->dev, &chip_type);
++		if (!name)
++			return -ENODEV;
++	} else {
++		return -ENOSYS;
++	}
++
++	regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
++	if (IS_ERR(regmap)) {
++		dev_err(&client->dev, "Failed to register i2c regmap %d\n",
++			(int)PTR_ERR(regmap));
++		return PTR_ERR(regmap);
++	}
++
++	result = inv_mpu_core_probe(&client->dev, regmap, client->irq, name,
++				    NULL, chip_type);
++	if (result < 0)
++		return result;
++
++	st = iio_priv(dev_get_drvdata(&client->dev));
++	st->muxc = i2c_mux_alloc(client->adapter, &client->dev,
++				 1, 0, I2C_MUX_LOCKED,
++				 inv_mpu6050_select_bypass,
++				 inv_mpu6050_deselect_bypass);
++	if (!st->muxc) {
++		result = -ENOMEM;
++		goto out_unreg_device;
++	}
++	st->muxc->priv = dev_get_drvdata(&client->dev);
++	result = i2c_mux_add_adapter(st->muxc, 0, 0, 0);
++	if (result)
++		goto out_unreg_device;
++
++	result = inv_mpu_acpi_create_mux_client(client);
++	if (result)
++		goto out_del_mux;
++
++	return 0;
++
++out_del_mux:
++	i2c_mux_del_adapters(st->muxc);
++out_unreg_device:
++	inv_mpu_core_remove(&client->dev);
++	return result;
++}
++
++static int inv_mpu_remove(struct i2c_client *client)
++{
++	struct iio_dev *indio_dev = i2c_get_clientdata(client);
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++	inv_mpu_acpi_delete_mux_client(client);
++	i2c_mux_del_adapters(st->muxc);
++
++	return inv_mpu_core_remove(&client->dev);
++}
++
++/*
++ * device id table is used to identify what device can be
++ * supported by this driver
++ */
++static const struct i2c_device_id inv_mpu_id[] = {
++	{"mpu6050", INV_MPU6050},
++	{"mpu6500", INV_MPU6500},
++	{"mpu9150", INV_MPU9150},
++	{"mpu9250", INV_MPU9250},
++	{}
++};
++
++MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
++
++static const struct acpi_device_id inv_acpi_match[] = {
++	{"INVN6500", INV_MPU6500},
++	{ },
++};
++
++MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
++
++static struct i2c_driver inv_mpu_driver = {
++	.probe		=	inv_mpu_probe,
++	.remove		=	inv_mpu_remove,
++	.id_table	=	inv_mpu_id,
++	.driver = {
++		.acpi_match_table = ACPI_PTR(inv_acpi_match),
++		.name	=	"inv-mpu6050-i2c",
++		.pm     =       &inv_mpu_pmops,
++	},
++};
++
++module_i2c_driver(inv_mpu_driver);
++
++MODULE_AUTHOR("Invensense Corporation");
++MODULE_DESCRIPTION("Invensense device MPU6050 driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_i2cmst.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2cmst.c
+new file mode 100644
+index 00000000..1fa45305
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2cmst.c
+@@ -0,0 +1,182 @@
++/*
++* Copyright (C) 2016 Ambarella, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/of_i2c.h>
++#include <linux/iio/iio.h>
++#include "inv_mpu_iio.h"
++
++int inv_mpu_i2cmst_read_data(struct inv_mpu6050_state *st,
++		u16 addr, u8 command, int size, union i2c_smbus_data *data)
++{
++	unsigned int d, num;
++	void *buf;
++	int result;
++
++	result = inv_mpu6050_set_power_itg(st, true);
++	if (result)
++		return result;
++
++	switch (size) {
++	case I2C_SMBUS_BYTE_DATA:
++		num = 1;
++		buf = &data->byte;
++		break;
++	case I2C_SMBUS_WORD_DATA:
++		num = 2;
++		buf = &data->word;
++		break;
++	case I2C_SMBUS_I2C_BLOCK_DATA:
++		num = data->block[0];
++		buf = &data->block[1];
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	d = INV_MPU6050_BIT_I2C_SLV0_EN | num;
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_CTRL, d);
++	if (result)
++		return result;
++
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_REG, command);
++	if (result)
++		return result;
++
++	d = INV_MPU6050_BIT_I2C_SLV0_RNW | addr;
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_ADDR, d);
++	if (result)
++		return result;
++
++	d = 1000 / st->chip_config.fifo_rate;
++	msleep(d + d / 2);
++
++	result = regmap_bulk_read(st->map, INV_MPU6050_REG_EXT_SENS_DATA, buf, num);
++	if (result)
++		return result;
++
++	result = inv_mpu6050_set_power_itg(st, false);
++	if (result)
++		return result;
++
++	return 0;
++}
++
++int inv_mpu_i2cmst_write_data(struct inv_mpu6050_state *st,
++		u16 addr, u8 command, int size, union i2c_smbus_data *data)
++{
++	unsigned int d;
++	int result;
++
++	if (size != I2C_SMBUS_BYTE_DATA) {
++		dev_err(&st->adap->dev, "funky write size %d\n", size);
++		return -EINVAL;
++	}
++
++	result = inv_mpu6050_set_power_itg(st, true);
++	if (result)
++		return result;
++
++	d = INV_MPU6050_BIT_I2C_SLV0_EN | 1; /* only one byte allowed to write */
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_CTRL, d);
++	if (result)
++		return result;
++
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_REG, command);
++	if (result)
++		return result;
++
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_DO, data->byte);
++	if (result)
++		return result;
++
++	result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_ADDR, addr);
++	if (result)
++		return result;
++
++	d = 1000 / st->chip_config.fifo_rate;
++	msleep(d + d / 2);
++
++	result = inv_mpu6050_set_power_itg(st, false);
++	if (result)
++		return result;
++
++	return 0;
++}
++
++static int inv_mpu_i2cmst_xfer(struct i2c_adapter *adap, u16 addr,
++		unsigned short flags, char rw, u8 command,
++		int size, union i2c_smbus_data *data)
++{
++	struct inv_mpu6050_state *st = i2c_get_adapdata(adap);
++	int ret = -EINVAL;
++
++	if (rw == I2C_SMBUS_WRITE)
++		ret = inv_mpu_i2cmst_write_data(st, addr, command, size, data);
++	else if (rw == I2C_SMBUS_READ)
++		ret = inv_mpu_i2cmst_read_data(st, addr, command, size, data);
++
++	return ret;
++}
++
++static u32 inv_mpu_i2cmst_func(struct i2c_adapter *adap)
++{
++	return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_READ_I2C_BLOCK;
++}
++
++static const struct i2c_algorithm inv_mpu_i2cmst_algo = {
++	.smbus_xfer	= inv_mpu_i2cmst_xfer,
++	.functionality	= inv_mpu_i2cmst_func,
++};
++
++int inv_mpu_i2cmst_probe(struct iio_dev *indio_dev)
++{
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	struct i2c_adapter *adap;
++	int ret;
++
++	adap = devm_kzalloc(&indio_dev->dev, sizeof(*adap), GFP_KERNEL);
++	if (!adap)
++		return -ENOMEM;
++
++	adap->owner = THIS_MODULE;
++	adap->class = I2C_CLASS_HWMON;
++	strlcpy(adap->name, "INV MPU I2CMST adapter", sizeof(adap->name));
++	adap->algo = &inv_mpu_i2cmst_algo;
++	adap->dev.parent = &indio_dev->dev;
++	adap->dev.of_node = indio_dev->dev.of_node;
++
++	i2c_set_adapdata(adap, st);
++	st->adap = adap;
++
++	ret = i2c_add_adapter(adap);
++	if (ret < 0) {
++		dev_err(&indio_dev->dev, "failed to add I2C master: %d\n", ret);
++		return ret;
++	}
++
++	of_i2c_register_devices(adap);
++
++	return 0;
++}
++
++void inv_mpu_i2cmst_remove(struct iio_dev *indio_dev)
++{
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	i2c_del_adapter(st->adap);
++}
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Invensense MPU9250 I2C Master driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu9250/inv_mpu_iio.h
+new file mode 100644
+index 00000000..4a6b3602
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_iio.h
+@@ -0,0 +1,315 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++#include <linux/i2c.h>
++#include <linux/i2c-mux.h>
++#include <linux/kfifo.h>
++#include <linux/spinlock.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/buffer.h>
++#include <linux/regmap.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/kfifo_buf.h>
++#include <linux/iio/trigger.h>
++#include <linux/iio/triggered_buffer.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/platform_data/invensense_mpu6050.h>
++
++/**
++ *  struct inv_mpu6050_reg_map - Notable registers.
++ *  @sample_rate_div:	Divider applied to gyro output rate.
++ *  @lpf:		Configures internal low pass filter.
++ *  @user_ctrl:		Enables/resets the FIFO.
++ *  @fifo_en:		Determines which data will appear in FIFO.
++ *  @gyro_config:	gyro config register.
++ *  @accl_config:	accel config register
++ *  @fifo_count_h:	Upper byte of FIFO count.
++ *  @fifo_r_w:		FIFO register.
++ *  @raw_gyro:		Address of first gyro register.
++ *  @raw_accl:		Address of first accel register.
++ *  @temperature:	temperature register
++ *  @int_enable:	Interrupt enable register.
++ *  @pwr_mgmt_1:	Controls chip's power state and clock source.
++ *  @pwr_mgmt_2:	Controls power state of individual sensors.
++ *  @int_pin_cfg;	Controls interrupt pin configuration.
++ *  @accl_offset:	Controls the accelerometer calibration offset.
++ *  @gyro_offset:	Controls the gyroscope calibration offset.
++ */
++struct inv_mpu6050_reg_map {
++	u8 sample_rate_div;
++	u8 lpf;
++	u8 user_ctrl;
++	u8 fifo_en;
++	u8 gyro_config;
++	u8 accl_config;
++	u8 fifo_count_h;
++	u8 fifo_r_w;
++	u8 raw_gyro;
++	u8 raw_accl;
++	u8 temperature;
++	u8 int_enable;
++	u8 pwr_mgmt_1;
++	u8 pwr_mgmt_2;
++	u8 int_pin_cfg;
++	u8 accl_offset;
++	u8 gyro_offset;
++};
++
++/*device enum */
++enum inv_devices {
++	INV_MPU6050,
++	INV_MPU6500,
++	INV_MPU6000,
++	INV_MPU9150,
++	INV_MPU9250,
++	INV_NUM_PARTS
++};
++
++/**
++ *  struct inv_mpu6050_chip_config - Cached chip configuration data.
++ *  @fsr:		Full scale range.
++ *  @lpf:		Digital low pass filter frequency.
++ *  @accl_fs:		accel full scale range.
++ *  @enable:		master enable state.
++ *  @accl_fifo_enable:	enable accel data output
++ *  @gyro_fifo_enable:	enable gyro data output
++ *  @fifo_rate:		FIFO update rate.
++ */
++struct inv_mpu6050_chip_config {
++	unsigned int fsr:2;
++	unsigned int lpf:3;
++	unsigned int accl_fs:2;
++	unsigned int enable:1;
++	unsigned int accl_fifo_enable:1;
++	unsigned int gyro_fifo_enable:1;
++	u16 fifo_rate;
++};
++
++/**
++ *  struct inv_mpu6050_hw - Other important hardware information.
++ *  @whoami:	Self identification byte from WHO_AM_I register
++ *  @name:      name of the chip.
++ *  @reg:   register map of the chip.
++ *  @config:    configuration of the chip.
++ */
++struct inv_mpu6050_hw {
++	u8 whoami;
++	u8 *name;
++	const struct inv_mpu6050_reg_map *reg;
++	const struct inv_mpu6050_chip_config *config;
++};
++
++/*
++ *  struct inv_mpu6050_state - Driver state variables.
++ *  @TIMESTAMP_FIFO_SIZE: fifo size for timestamp.
++ *  @trig:              IIO trigger.
++ *  @chip_config:	Cached attribute information.
++ *  @reg:		Map of important registers.
++ *  @hw:		Other hardware-specific information.
++ *  @chip_type:		chip type.
++ *  @time_stamp_lock:	spin lock to time stamp.
++ *  @orientation:	sensor chip orientation relative to main hardware.
++ *  @timestamps:        kfifo queue to store time stamp.
++ *  @map		regmap pointer.
++ *  @irq		interrupt number.
++ */
++struct inv_mpu6050_state {
++#define TIMESTAMP_FIFO_SIZE 16
++	struct iio_trigger  *trig;
++	struct inv_mpu6050_chip_config chip_config;
++	const struct inv_mpu6050_reg_map *reg;
++	const struct inv_mpu6050_hw *hw;
++	struct i2c_adapter *adap;
++	enum   inv_devices chip_type;
++	spinlock_t time_stamp_lock;
++	struct i2c_mux_core *muxc;
++	struct i2c_client *mux_client;
++	unsigned int powerup_count;
++	struct iio_mount_matrix orientation;
++	DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
++	struct regmap *map;
++	struct device *dev;
++	int irq;
++};
++
++/*register and associated bit definition*/
++#define INV_MPU6050_REG_ACCEL_OFFSET        0x06
++#define INV_MPU6050_REG_GYRO_OFFSET         0x13
++
++#define INV_MPU6050_REG_SAMPLE_RATE_DIV     0x19
++#define INV_MPU6050_REG_CONFIG              0x1A
++#define INV_MPU6050_REG_GYRO_CONFIG         0x1B
++#define INV_MPU6050_REG_ACCEL_CONFIG        0x1C
++
++#define INV_MPU6050_REG_FIFO_EN             0x23
++#define INV_MPU6050_BIT_ACCEL_OUT           0x08
++#define INV_MPU6050_BITS_GYRO_OUT           0x70
++
++#define INV_MPU6050_REG_I2C_MST_CTRL        0x24
++#define INV_MPU6050_BIT_WAIT_FOR_ES         0x40
++#define INV_MPU6050_BIT_I2C_MST_CLK         0x0d
++
++#define INV_MPU6050_REG_I2C_SLV0_ADDR       0x25
++#define INV_MPU6050_BIT_I2C_SLV0_RNW        0x80
++
++#define INV_MPU6050_REG_I2C_SLV0_REG        0x26
++
++#define INV_MPU6050_REG_I2C_SLV0_CTRL       0x27
++#define INV_MPU6050_BIT_I2C_SLV0_EN         0x80
++
++#define INV_MPU6050_REG_INT_ENABLE          0x38
++#define INV_MPU6050_BIT_DATA_RDY_EN         0x01
++#define INV_MPU6050_BIT_DMP_INT_EN          0x02
++
++#define INV_MPU6050_REG_RAW_ACCEL           0x3B
++#define INV_MPU6050_REG_TEMPERATURE         0x41
++#define INV_MPU6050_REG_RAW_GYRO            0x43
++
++#define INV_MPU6050_REG_EXT_SENS_DATA       0x49
++
++#define INV_MPU6050_REG_I2C_SLV0_DO         0x63
++
++#define INV_MPU6050_REG_USER_CTRL           0x6A
++#define INV_MPU6050_BIT_FIFO_RST            0x04
++#define INV_MPU6050_BIT_DMP_RST             0x08
++#define INV_MPU6050_BIT_I2C_MST_EN          0x20
++#define INV_MPU6050_BIT_FIFO_EN             0x40
++#define INV_MPU6050_BIT_DMP_EN              0x80
++#define INV_MPU6050_BIT_I2C_IF_DIS          0x10
++
++#define INV_MPU6050_REG_PWR_MGMT_1          0x6B
++#define INV_MPU6050_BIT_H_RESET             0x80
++#define INV_MPU6050_BIT_SLEEP               0x40
++#define INV_MPU6050_BIT_CLK_MASK            0x7
++
++#define INV_MPU6050_REG_PWR_MGMT_2          0x6C
++#define INV_MPU6050_BIT_PWR_ACCL_STBY       0x38
++#define INV_MPU6050_BIT_PWR_GYRO_STBY       0x07
++#define INV_MPU6050_BIT_PWR_TEMP_STBY       0x01
++
++#define INV_MPU6050_REG_FIFO_COUNT_H        0x72
++#define INV_MPU6050_REG_FIFO_R_W            0x74
++
++#define INV_MPU6050_BYTES_PER_3AXIS_SENSOR   6
++#define INV_MPU6050_FIFO_COUNT_BYTE          2
++#define INV_MPU6050_FIFO_THRESHOLD           500
++
++/* mpu6500 registers */
++#define INV_MPU6500_REG_ACCEL_OFFSET        0x77
++
++/* delay time in milliseconds */
++#define INV_MPU6050_POWER_UP_TIME            100
++#define INV_MPU6050_TEMP_UP_TIME             100
++#define INV_MPU6050_SENSOR_UP_TIME           30
++
++/* delay time in microseconds */
++#define INV_MPU6050_REG_UP_TIME_MIN          5000
++#define INV_MPU6050_REG_UP_TIME_MAX          10000
++
++#define INV_MPU6050_TEMP_OFFSET	             12421
++#define INV_MPU6050_TEMP_SCALE               2941
++#define INV_MPU6050_MAX_GYRO_FS_PARAM        3
++#define INV_MPU6050_MAX_ACCL_FS_PARAM        3
++#define INV_MPU6050_THREE_AXIS               3
++#define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT    3
++#define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT    3
++
++/* 6 + 6 round up and plus 8 */
++#define INV_MPU6050_OUTPUT_DATA_SIZE         24
++
++#define INV_MPU6050_REG_INT_PIN_CFG	0x37
++#define INV_MPU6050_BIT_BYPASS_EN	0x2
++#define INV_MPU6050_INT_PIN_CFG		0
++
++/* init parameters */
++#define INV_MPU6050_INIT_FIFO_RATE           50
++#define INV_MPU6050_TIME_STAMP_TOR           5
++#define INV_MPU6050_MAX_FIFO_RATE            1000
++#define INV_MPU6050_MIN_FIFO_RATE            4
++#define INV_MPU6050_ONE_K_HZ                 1000
++
++#define INV_MPU6050_REG_WHOAMI			117
++
++#define INV_MPU6000_WHOAMI_VALUE		0x68
++#define INV_MPU6050_WHOAMI_VALUE		0x68
++#define INV_MPU6500_WHOAMI_VALUE		0x70
++#define INV_MPU9150_WHOAMI_VALUE		0x68
++#define INV_MPU9250_WHOAMI_VALUE		0x71
++
++/* scan element definition */
++enum inv_mpu6050_scan {
++	INV_MPU6050_SCAN_ACCL_X,
++	INV_MPU6050_SCAN_ACCL_Y,
++	INV_MPU6050_SCAN_ACCL_Z,
++	INV_MPU6050_SCAN_GYRO_X,
++	INV_MPU6050_SCAN_GYRO_Y,
++	INV_MPU6050_SCAN_GYRO_Z,
++	INV_MPU6050_SCAN_TIMESTAMP,
++};
++
++enum inv_mpu6050_filter_e {
++	INV_MPU6050_FILTER_256HZ_NOLPF2 = 0,
++	INV_MPU6050_FILTER_188HZ,
++	INV_MPU6050_FILTER_98HZ,
++	INV_MPU6050_FILTER_42HZ,
++	INV_MPU6050_FILTER_20HZ,
++	INV_MPU6050_FILTER_10HZ,
++	INV_MPU6050_FILTER_5HZ,
++	INV_MPU6050_FILTER_2100HZ_NOLPF,
++	NUM_MPU6050_FILTER
++};
++
++/* IIO attribute address */
++enum INV_MPU6050_IIO_ATTR_ADDR {
++	ATTR_GYRO_MATRIX,
++	ATTR_ACCL_MATRIX,
++};
++
++enum inv_mpu6050_accl_fs_e {
++	INV_MPU6050_FS_02G = 0,
++	INV_MPU6050_FS_04G,
++	INV_MPU6050_FS_08G,
++	INV_MPU6050_FS_16G,
++	NUM_ACCL_FSR
++};
++
++enum inv_mpu6050_fsr_e {
++	INV_MPU6050_FSR_250DPS = 0,
++	INV_MPU6050_FSR_500DPS,
++	INV_MPU6050_FSR_1000DPS,
++	INV_MPU6050_FSR_2000DPS,
++	NUM_MPU6050_FSR
++};
++
++enum inv_mpu6050_clock_sel_e {
++	INV_CLK_INTERNAL = 0,
++	INV_CLK_PLL,
++	NUM_CLK
++};
++
++irqreturn_t inv_mpu6050_irq_handler(int irq, void *p);
++irqreturn_t inv_mpu6050_read_fifo(int irq, void *p);
++int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev);
++void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st);
++int inv_reset_fifo(struct iio_dev *indio_dev);
++int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask);
++int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
++int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
++int inv_mpu_acpi_create_mux_client(struct i2c_client *client);
++void inv_mpu_acpi_delete_mux_client(struct i2c_client *client);
++int inv_mpu_core_probe(struct device *dev, struct regmap *regmap,
++		int irq, const char *name,
++		int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type);
++int inv_mpu_core_remove(struct device *dev);
++int inv_mpu_i2cmst_probe(struct iio_dev *indio_dev);
++void inv_mpu_i2cmst_remove(struct iio_dev *indio_dev);
++extern const struct dev_pm_ops inv_mpu_pmops;
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_ring.c
+new file mode 100644
+index 00000000..919662d6
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_ring.c
+@@ -0,0 +1,196 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/sysfs.h>
++#include <linux/jiffies.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/kfifo.h>
++#include <linux/poll.h>
++#include "inv_mpu_iio.h"
++
++static void inv_clear_kfifo(struct inv_mpu6050_state *st)
++{
++	unsigned long flags;
++
++	/* take the spin lock sem to avoid interrupt kick in */
++	spin_lock_irqsave(&st->time_stamp_lock, flags);
++	kfifo_reset(&st->timestamps);
++	spin_unlock_irqrestore(&st->time_stamp_lock, flags);
++}
++
++int inv_reset_fifo(struct iio_dev *indio_dev)
++{
++	int result;
++	u8 d;
++	struct inv_mpu6050_state  *st = iio_priv(indio_dev);
++
++	/* disable interrupt */
++	result = regmap_write(st->map, st->reg->int_enable, 0);
++	if (result) {
++		dev_err(st->dev, "int_enable failed %d\n",
++			result);
++		return result;
++	}
++	/* disable the sensor output to FIFO */
++	result = regmap_write(st->map, st->reg->fifo_en, 0);
++	if (result)
++		goto reset_fifo_fail;
++	/* disable fifo reading */
++	result = regmap_update_bits(st->map, st->reg->user_ctrl,
++				INV_MPU6050_BIT_FIFO_EN, 0);
++	if (result)
++		goto reset_fifo_fail;
++
++	/* reset FIFO*/
++	result = regmap_update_bits(st->map, st->reg->user_ctrl,
++				INV_MPU6050_BIT_FIFO_RST, INV_MPU6050_BIT_FIFO_RST);
++	if (result)
++		goto reset_fifo_fail;
++
++	/* clear timestamps fifo */
++	inv_clear_kfifo(st);
++
++	/* enable interrupt */
++	if (st->chip_config.accl_fifo_enable ||
++	    st->chip_config.gyro_fifo_enable) {
++		result = regmap_write(st->map, st->reg->int_enable,
++				      INV_MPU6050_BIT_DATA_RDY_EN);
++		if (result)
++			return result;
++	}
++	/* enable FIFO reading and I2C master interface*/
++	result = regmap_update_bits(st->map, st->reg->user_ctrl,
++				INV_MPU6050_BIT_FIFO_EN, INV_MPU6050_BIT_FIFO_EN);
++	if (result)
++		goto reset_fifo_fail;
++	/* enable sensor output to FIFO */
++	d = 0;
++	if (st->chip_config.gyro_fifo_enable)
++		d |= INV_MPU6050_BITS_GYRO_OUT;
++	if (st->chip_config.accl_fifo_enable)
++		d |= INV_MPU6050_BIT_ACCEL_OUT;
++	result = regmap_write(st->map, st->reg->fifo_en, d);
++	if (result)
++		goto reset_fifo_fail;
++
++	return 0;
++
++reset_fifo_fail:
++	dev_err(st->dev, "reset fifo failed %d\n", result);
++	result = regmap_write(st->map, st->reg->int_enable,
++			      INV_MPU6050_BIT_DATA_RDY_EN);
++
++	return result;
++}
++
++/**
++ * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
++ */
++irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
++{
++	struct iio_poll_func *pf = p;
++	struct iio_dev *indio_dev = pf->indio_dev;
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	s64 timestamp;
++
++	timestamp = iio_get_time_ns();
++	kfifo_in_spinlocked(&st->timestamps, &timestamp, 1,
++			    &st->time_stamp_lock);
++
++	return IRQ_WAKE_THREAD;
++}
++
++/**
++ * inv_mpu6050_read_fifo() - Transfer data from hardware FIFO to KFIFO.
++ */
++irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
++{
++	struct iio_poll_func *pf = p;
++	struct iio_dev *indio_dev = pf->indio_dev;
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	size_t bytes_per_datum;
++	int result;
++	u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
++	u16 fifo_count;
++	s64 timestamp;
++	u64 *tmp;
++
++	mutex_lock(&indio_dev->mlock);
++	if (!(st->chip_config.accl_fifo_enable |
++		st->chip_config.gyro_fifo_enable))
++		goto end_session;
++	bytes_per_datum = 0;
++	if (st->chip_config.accl_fifo_enable)
++		bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
++
++	if (st->chip_config.gyro_fifo_enable)
++		bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
++
++	/*
++	 * read fifo_count register to know how many bytes inside FIFO
++	 * right now
++	 */
++	result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data,
++				  INV_MPU6050_FIFO_COUNT_BYTE);
++	if (result)
++		goto end_session;
++	fifo_count = be16_to_cpup((__be16 *)(&data[0]));
++	if (fifo_count < bytes_per_datum)
++		goto end_session;
++	/* fifo count can't be odd number, if it is odd, reset fifo*/
++	if (fifo_count & 1)
++		goto flush_fifo;
++	if (fifo_count >  INV_MPU6050_FIFO_THRESHOLD)
++		goto flush_fifo;
++	/* Timestamp mismatch. */
++	if (kfifo_len(&st->timestamps) >
++	    fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
++		goto flush_fifo;
++	while (fifo_count >= bytes_per_datum) {
++		result = regmap_bulk_read(st->map, st->reg->fifo_r_w,
++					  data, bytes_per_datum);
++		if (result)
++			goto flush_fifo;
++
++		result = kfifo_out(&st->timestamps, &timestamp, 1);
++		/* when there is no timestamp, put timestamp as 0 */
++		if (result == 0)
++			timestamp = 0;
++
++		tmp = (u64 *)data;
++		tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
++		result = iio_push_to_buffers(indio_dev, data);
++		if (result)
++			goto flush_fifo;
++		fifo_count -= bytes_per_datum;
++	}
++
++end_session:
++	mutex_unlock(&indio_dev->mlock);
++	iio_trigger_notify_done(indio_dev->trig);
++
++	return IRQ_HANDLED;
++
++flush_fifo:
++	/* Flush HW and SW FIFOs. */
++	inv_reset_fifo(indio_dev);
++	mutex_unlock(&indio_dev->mlock);
++	iio_trigger_notify_done(indio_dev->trig);
++
++	return IRQ_HANDLED;
++}
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_spi.c
+new file mode 100644
+index 00000000..1f6b6afd
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_spi.c
+@@ -0,0 +1,132 @@
++/*
++* Copyright (C) 2015 Intel Corporation Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++#include <linux/module.h>
++#include <linux/acpi.h>
++#include <linux/spi/spi.h>
++#include <linux/regmap.h>
++#include <linux/iio/iio.h>
++#include "inv_mpu_iio.h"
++
++static const struct regmap_config inv_mpu_regmap_config = {
++	.reg_bits = 8,
++	.val_bits = 8,
++};
++
++static int inv_mpu_i2c_disable(struct iio_dev *indio_dev)
++{
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	int ret = 0;
++
++	ret = inv_mpu6050_set_power_itg(st, true);
++	if (ret)
++		return ret;
++
++	ret = regmap_write(st->map, INV_MPU6050_REG_USER_CTRL,
++			   INV_MPU6050_BIT_I2C_IF_DIS | INV_MPU6050_BIT_I2C_MST_EN);
++	if (ret) {
++		inv_mpu6050_set_power_itg(st, false);
++		return ret;
++	}
++
++	ret = regmap_write(st->map, INV_MPU6050_REG_I2C_MST_CTRL,
++			   INV_MPU6050_BIT_I2C_MST_CLK);
++	if (ret) {
++		inv_mpu6050_set_power_itg(st, false);
++		return ret;
++	}
++
++	return inv_mpu6050_set_power_itg(st, false);
++}
++
++static int inv_mpu_probe(struct spi_device *spi)
++{
++	struct regmap *regmap;
++	const struct spi_device_id *spi_id;
++	const struct acpi_device_id *acpi_id;
++	const char *name = NULL;
++	enum inv_devices chip_type;
++	int ret;
++
++	if ((spi_id = spi_get_device_id(spi))) {
++		chip_type = (enum inv_devices)spi_id->driver_data;
++		name = spi_id->name;
++	} else if ((acpi_id = acpi_match_device(spi->dev.driver->acpi_match_table, &spi->dev))) {
++		chip_type = (enum inv_devices)acpi_id->driver_data;
++	} else {
++		return -ENODEV;
++	}
++
++	regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
++	if (IS_ERR(regmap)) {
++		dev_err(&spi->dev, "Failed to register spi regmap %d\n",
++			(int)PTR_ERR(regmap));
++		return PTR_ERR(regmap);
++	}
++
++	ret = inv_mpu_core_probe(&spi->dev, regmap, spi->irq, name,
++				  inv_mpu_i2c_disable, chip_type);
++	if (ret < 0)
++		return ret;
++
++	ret = inv_mpu_i2cmst_probe(dev_get_drvdata(&spi->dev));
++	if (ret < 0) {
++		dev_err(&spi->dev, "i2c master probe fail %d\n", ret);
++		inv_mpu_core_remove(&spi->dev);
++		return ret;
++	}
++
++	return 0;
++}
++
++static int inv_mpu_remove(struct spi_device *spi)
++{
++	inv_mpu_i2cmst_remove(dev_get_drvdata(&spi->dev));
++	return inv_mpu_core_remove(&spi->dev);
++}
++
++/*
++ * device id table is used to identify what device can be
++ * supported by this driver
++ */
++static const struct spi_device_id inv_mpu_id[] = {
++	{"mpu6000", INV_MPU6000},
++	{"mpu6500", INV_MPU6500},
++	{"mpu9150", INV_MPU9150},
++	{"mpu9250", INV_MPU9250},
++	{}
++};
++
++MODULE_DEVICE_TABLE(spi, inv_mpu_id);
++
++static const struct acpi_device_id inv_acpi_match[] = {
++	{"INVN6000", INV_MPU6000},
++	{ },
++};
++MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
++
++static struct spi_driver inv_mpu_driver = {
++	.probe		=	inv_mpu_probe,
++	.remove		=	inv_mpu_remove,
++	.id_table	=	inv_mpu_id,
++	.driver = {
++		.acpi_match_table = ACPI_PTR(inv_acpi_match),
++		.name	=	"inv-mpu6000-spi",
++		.pm     =       &inv_mpu_pmops,
++	},
++};
++
++module_spi_driver(inv_mpu_driver);
++
++MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
++MODULE_DESCRIPTION("Invensense device MPU6000 driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_trigger.c
+new file mode 100644
+index 00000000..cca1c242
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_trigger.c
+@@ -0,0 +1,148 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*/
++
++#include "inv_mpu_iio.h"
++
++static void inv_scan_query(struct iio_dev *indio_dev)
++{
++	struct inv_mpu6050_state  *st = iio_priv(indio_dev);
++
++	st->chip_config.gyro_fifo_enable =
++		test_bit(INV_MPU6050_SCAN_GYRO_X,
++			 indio_dev->active_scan_mask) ||
++		test_bit(INV_MPU6050_SCAN_GYRO_Y,
++			 indio_dev->active_scan_mask) ||
++		test_bit(INV_MPU6050_SCAN_GYRO_Z,
++			 indio_dev->active_scan_mask);
++
++	st->chip_config.accl_fifo_enable =
++		test_bit(INV_MPU6050_SCAN_ACCL_X,
++			 indio_dev->active_scan_mask) ||
++		test_bit(INV_MPU6050_SCAN_ACCL_Y,
++			 indio_dev->active_scan_mask) ||
++		test_bit(INV_MPU6050_SCAN_ACCL_Z,
++			 indio_dev->active_scan_mask);
++}
++
++/**
++ *  inv_mpu6050_set_enable() - enable chip functions.
++ *  @indio_dev:	Device driver instance.
++ *  @enable: enable/disable
++ */
++static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
++{
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++	int result;
++
++	if (enable) {
++		result = inv_mpu6050_set_power_itg(st, true);
++		if (result)
++			return result;
++		inv_scan_query(indio_dev);
++		if (st->chip_config.gyro_fifo_enable) {
++			result = inv_mpu6050_switch_engine(st, true,
++					INV_MPU6050_BIT_PWR_GYRO_STBY);
++			if (result)
++				return result;
++		}
++		if (st->chip_config.accl_fifo_enable) {
++			result = inv_mpu6050_switch_engine(st, true,
++					INV_MPU6050_BIT_PWR_ACCL_STBY);
++			if (result)
++				return result;
++		}
++		result = inv_reset_fifo(indio_dev);
++		if (result)
++			return result;
++	} else {
++		result = regmap_write(st->map, st->reg->fifo_en, 0);
++		if (result)
++			return result;
++
++		result = regmap_write(st->map, st->reg->int_enable, 0);
++		if (result)
++			return result;
++
++		result = regmap_update_bits(st->map, st->reg->user_ctrl,
++					INV_MPU6050_BIT_FIFO_EN, 0);
++		if (result)
++			return result;
++
++		result = inv_mpu6050_switch_engine(st, false,
++					INV_MPU6050_BIT_PWR_GYRO_STBY);
++		if (result)
++			return result;
++
++		result = inv_mpu6050_switch_engine(st, false,
++					INV_MPU6050_BIT_PWR_ACCL_STBY);
++		if (result)
++			return result;
++		result = inv_mpu6050_set_power_itg(st, false);
++		if (result)
++			return result;
++	}
++	st->chip_config.enable = enable;
++
++	return 0;
++}
++
++/**
++ * inv_mpu_data_rdy_trigger_set_state() - set data ready interrupt state
++ * @trig: Trigger instance
++ * @state: Desired trigger state
++ */
++static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig,
++					      bool state)
++{
++	return inv_mpu6050_set_enable(iio_trigger_get_drvdata(trig), state);
++}
++
++static const struct iio_trigger_ops inv_mpu_trigger_ops = {
++	.owner = THIS_MODULE,
++	.set_trigger_state = &inv_mpu_data_rdy_trigger_set_state,
++};
++
++int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
++{
++	int ret;
++	struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++	st->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id);
++	if (!st->trig)
++		return -ENOMEM;
++
++	ret = devm_request_irq(&indio_dev->dev, st->irq,
++			       &iio_trigger_generic_data_rdy_poll,
++			       IRQF_TRIGGER_RISING,
++			       "inv_mpu",
++			       st->trig);
++	if (ret)
++		return ret;
++
++	st->trig->dev.parent = st->dev;
++	st->trig->ops = &inv_mpu_trigger_ops;
++	iio_trigger_set_drvdata(st->trig, indio_dev);
++
++	ret = iio_trigger_register(st->trig);
++	if (ret)
++		return ret;
++
++	indio_dev->trig = iio_trigger_get(st->trig);
++
++	return 0;
++}
++
++void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st)
++{
++	iio_trigger_unregister(st->trig);
++}
+diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
+index bd1cfb66..6cd03f3a 100644
+--- a/drivers/iio/magnetometer/Kconfig
++++ b/drivers/iio/magnetometer/Kconfig
+@@ -7,9 +7,11 @@ config AK8975
+ 	tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
+ 	depends on I2C
+ 	depends on GPIOLIB
++	select IIO_BUFFER
++	select IIO_TRIGGERED_BUFFER
+ 	help
+-	  Say yes here to build support for Asahi Kasei AK8975 3-Axis
+-	  Magnetometer.
++	  Say yes here to build support for Asahi Kasei AK8975, AK8963,
++	  AK09911 or AK09912 3-Axis Magnetometer.
+ 
+ 	  To compile this driver as a module, choose M here: the module
+ 	  will be called ak8975.
+diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
+index 53f82900..1cf7c6e3 100644
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -24,14 +24,23 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/i2c.h>
++#include <linux/interrupt.h>
+ #include <linux/err.h>
+ #include <linux/mutex.h>
+ #include <linux/delay.h>
+-
++#include <linux/bitops.h>
+ #include <linux/gpio.h>
++#include <linux/of_gpio.h>
++#include <linux/acpi.h>
++#include <linux/regulator/consumer.h>
+ 
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
++#include <linux/iio/buffer.h>
++#include <linux/iio/trigger.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/iio/triggered_buffer.h>
++
+ /*
+  * Register definitions, as well as various shifts and masks to get at the
+  * individual fields of the registers.
+@@ -61,10 +70,10 @@
+ #define AK8975_REG_CNTL			0x0A
+ #define AK8975_REG_CNTL_MODE_SHIFT	0
+ #define AK8975_REG_CNTL_MODE_MASK	(0xF << AK8975_REG_CNTL_MODE_SHIFT)
+-#define AK8975_REG_CNTL_MODE_POWER_DOWN	0
+-#define AK8975_REG_CNTL_MODE_ONCE	1
+-#define AK8975_REG_CNTL_MODE_SELF_TEST	8
+-#define AK8975_REG_CNTL_MODE_FUSE_ROM	0xF
++#define AK8975_REG_CNTL_MODE_POWER_DOWN	0x00
++#define AK8975_REG_CNTL_MODE_ONCE	0x01
++#define AK8975_REG_CNTL_MODE_SELF_TEST	0x08
++#define AK8975_REG_CNTL_MODE_FUSE_ROM	0x0F
+ 
+ #define AK8975_REG_RSVC			0x0B
+ #define AK8975_REG_ASTC			0x0C
+@@ -77,51 +86,443 @@
+ 
+ #define AK8975_MAX_REGS			AK8975_REG_ASAZ
+ 
++/*
++ * AK09912 Register definitions
++ */
++#define AK09912_REG_WIA1		0x00
++#define AK09912_REG_WIA2		0x01
++#define AK09912_DEVICE_ID		0x04
++#define AK09911_DEVICE_ID		0x05
++
++#define AK09911_REG_INFO1		0x02
++#define AK09911_REG_INFO2		0x03
++
++#define AK09912_REG_ST1			0x10
++
++#define AK09912_REG_ST1_DRDY_SHIFT	0
++#define AK09912_REG_ST1_DRDY_MASK	(1 << AK09912_REG_ST1_DRDY_SHIFT)
++
++#define AK09912_REG_HXL			0x11
++#define AK09912_REG_HXH			0x12
++#define AK09912_REG_HYL			0x13
++#define AK09912_REG_HYH			0x14
++#define AK09912_REG_HZL			0x15
++#define AK09912_REG_HZH			0x16
++#define AK09912_REG_TMPS		0x17
++
++#define AK09912_REG_ST2			0x18
++#define AK09912_REG_ST2_HOFL_SHIFT	3
++#define AK09912_REG_ST2_HOFL_MASK	(1 << AK09912_REG_ST2_HOFL_SHIFT)
++
++#define AK09912_REG_CNTL1		0x30
++
++#define AK09912_REG_CNTL2		0x31
++#define AK09912_REG_CNTL_MODE_POWER_DOWN	0x00
++#define AK09912_REG_CNTL_MODE_ONCE	0x01
++#define AK09912_REG_CNTL_MODE_SELF_TEST	0x10
++#define AK09912_REG_CNTL_MODE_FUSE_ROM	0x1F
++#define AK09912_REG_CNTL2_MODE_SHIFT	0
++#define AK09912_REG_CNTL2_MODE_MASK	(0x1F << AK09912_REG_CNTL2_MODE_SHIFT)
++
++#define AK09912_REG_CNTL3		0x32
++
++#define AK09912_REG_TS1			0x33
++#define AK09912_REG_TS2			0x34
++#define AK09912_REG_TS3			0x35
++#define AK09912_REG_I2CDIS		0x36
++#define AK09912_REG_TS4			0x37
++
++#define AK09912_REG_ASAX		0x60
++#define AK09912_REG_ASAY		0x61
++#define AK09912_REG_ASAZ		0x62
++
++#define AK09912_MAX_REGS		AK09912_REG_ASAZ
++
+ /*
+  * Miscellaneous values.
+  */
+ #define AK8975_MAX_CONVERSION_TIMEOUT	500
+ #define AK8975_CONVERSION_DONE_POLL_TIME 10
++#define AK8975_DATA_READY_TIMEOUT	((100*HZ)/1000)
++
++/*
++ * Precalculate scale factor (in Gauss units) for each axis and
++ * store in the device data.
++ *
++ * This scale factor is axis-dependent, and is derived from 3 calibration
++ * factors ASA(x), ASA(y), and ASA(z).
++ *
++ * These ASA values are read from the sensor device at start of day, and
++ * cached in the device context struct.
++ *
++ * Adjusting the flux value with the sensitivity adjustment value should be
++ * done via the following formula:
++ *
++ * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
++ * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
++ * is the resultant adjusted value.
++ *
++ * We reduce the formula to:
++ *
++ * Hadj = H * (ASA + 128) / 256
++ *
++ * H is in the range of -4096 to 4095.  The magnetometer has a range of
++ * +-1229uT.  To go from the raw value to uT is:
++ *
++ * HuT = H * 1229/4096, or roughly, 3/10.
++ *
++ * Since 1uT = 0.01 gauss, our final scale factor becomes:
++ *
++ * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
++ * Hadj = H * ((ASA + 128) * 0.003) / 256
++ *
++ * Since ASA doesn't change, we cache the resultant scale factor into the
++ * device context in ak8975_setup().
++ *
++ * Given we use IIO_VAL_INT_PLUS_MICRO bit when displaying the scale, we
++ * multiply the stored scale value by 1e6.
++ */
++static long ak8975_raw_to_gauss(u16 data)
++{
++	return (((long)data + 128) * 3000) / 256;
++}
++
++/*
++ * For AK8963 and AK09911, same calculation, but the device is less sensitive:
++ *
++ * H is in the range of +-8190.  The magnetometer has a range of
++ * +-4912uT.  To go from the raw value to uT is:
++ *
++ * HuT = H * 4912/8190, or roughly, 6/10, instead of 3/10.
++ */
++
++static long ak8963_09911_raw_to_gauss(u16 data)
++{
++	return (((long)data + 128) * 6000) / 256;
++}
++
++/*
++ * For AK09912, same calculation, except the device is more sensitive:
++ *
++ * H is in the range of -32752 to 32752.  The magnetometer has a range of
++ * +-4912uT.  To go from the raw value to uT is:
++ *
++ * HuT = H * 4912/32752, or roughly, 3/20, instead of 3/10.
++ */
++static long ak09912_raw_to_gauss(u16 data)
++{
++	return (((long)data + 128) * 1500) / 256;
++}
++
++/* Compatible Asahi Kasei Compass parts */
++enum asahi_compass_chipset {
++	AK8975,
++	AK8963,
++	AK09911,
++	AK09912,
++	AK_MAX_TYPE
++};
++
++enum ak_ctrl_reg_addr {
++	ST1,
++	ST2,
++	CNTL,
++	ASA_BASE,
++	MAX_REGS,
++	REGS_END,
++};
++
++enum ak_ctrl_reg_mask {
++	ST1_DRDY,
++	ST2_HOFL,
++	ST2_DERR,
++	CNTL_MODE,
++	MASK_END,
++};
++
++enum ak_ctrl_mode {
++	POWER_DOWN,
++	MODE_ONCE,
++	SELF_TEST,
++	FUSE_ROM,
++	MODE_END,
++};
++
++struct ak_def {
++	enum asahi_compass_chipset type;
++	long (*raw_to_gauss)(u16 data);
++	u16 range;
++	u8 ctrl_regs[REGS_END];
++	u8 ctrl_masks[MASK_END];
++	u8 ctrl_modes[MODE_END];
++	u8 data_regs[3];
++};
++
++static const struct ak_def ak_def_array[AK_MAX_TYPE] = {
++	{
++		.type = AK8975,
++		.raw_to_gauss = ak8975_raw_to_gauss,
++		.range = 4096,
++		.ctrl_regs = {
++			AK8975_REG_ST1,
++			AK8975_REG_ST2,
++			AK8975_REG_CNTL,
++			AK8975_REG_ASAX,
++			AK8975_MAX_REGS},
++		.ctrl_masks = {
++			AK8975_REG_ST1_DRDY_MASK,
++			AK8975_REG_ST2_HOFL_MASK,
++			AK8975_REG_ST2_DERR_MASK,
++			AK8975_REG_CNTL_MODE_MASK},
++		.ctrl_modes = {
++			AK8975_REG_CNTL_MODE_POWER_DOWN,
++			AK8975_REG_CNTL_MODE_ONCE,
++			AK8975_REG_CNTL_MODE_SELF_TEST,
++			AK8975_REG_CNTL_MODE_FUSE_ROM},
++		.data_regs = {
++			AK8975_REG_HXL,
++			AK8975_REG_HYL,
++			AK8975_REG_HZL},
++	},
++	{
++		.type = AK8963,
++		.raw_to_gauss = ak8963_09911_raw_to_gauss,
++		.range = 8190,
++		.ctrl_regs = {
++			AK8975_REG_ST1,
++			AK8975_REG_ST2,
++			AK8975_REG_CNTL,
++			AK8975_REG_ASAX,
++			AK8975_MAX_REGS},
++		.ctrl_masks = {
++			AK8975_REG_ST1_DRDY_MASK,
++			AK8975_REG_ST2_HOFL_MASK,
++			0,
++			AK8975_REG_CNTL_MODE_MASK},
++		.ctrl_modes = {
++			AK8975_REG_CNTL_MODE_POWER_DOWN,
++			AK8975_REG_CNTL_MODE_ONCE,
++			AK8975_REG_CNTL_MODE_SELF_TEST,
++			AK8975_REG_CNTL_MODE_FUSE_ROM},
++		.data_regs = {
++			AK8975_REG_HXL,
++			AK8975_REG_HYL,
++			AK8975_REG_HZL},
++	},
++	{
++		.type = AK09911,
++		.raw_to_gauss = ak8963_09911_raw_to_gauss,
++		.range = 8192,
++		.ctrl_regs = {
++			AK09912_REG_ST1,
++			AK09912_REG_ST2,
++			AK09912_REG_CNTL2,
++			AK09912_REG_ASAX,
++			AK09912_MAX_REGS},
++		.ctrl_masks = {
++			AK09912_REG_ST1_DRDY_MASK,
++			AK09912_REG_ST2_HOFL_MASK,
++			0,
++			AK09912_REG_CNTL2_MODE_MASK},
++		.ctrl_modes = {
++			AK09912_REG_CNTL_MODE_POWER_DOWN,
++			AK09912_REG_CNTL_MODE_ONCE,
++			AK09912_REG_CNTL_MODE_SELF_TEST,
++			AK09912_REG_CNTL_MODE_FUSE_ROM},
++		.data_regs = {
++			AK09912_REG_HXL,
++			AK09912_REG_HYL,
++			AK09912_REG_HZL},
++	},
++	{
++		.type = AK09912,
++		.raw_to_gauss = ak09912_raw_to_gauss,
++		.range = 32752,
++		.ctrl_regs = {
++			AK09912_REG_ST1,
++			AK09912_REG_ST2,
++			AK09912_REG_CNTL2,
++			AK09912_REG_ASAX,
++			AK09912_MAX_REGS},
++		.ctrl_masks = {
++			AK09912_REG_ST1_DRDY_MASK,
++			AK09912_REG_ST2_HOFL_MASK,
++			0,
++			AK09912_REG_CNTL2_MODE_MASK},
++		.ctrl_modes = {
++			AK09912_REG_CNTL_MODE_POWER_DOWN,
++			AK09912_REG_CNTL_MODE_ONCE,
++			AK09912_REG_CNTL_MODE_SELF_TEST,
++			AK09912_REG_CNTL_MODE_FUSE_ROM},
++		.data_regs = {
++			AK09912_REG_HXL,
++			AK09912_REG_HYL,
++			AK09912_REG_HZL},
++	}
++};
+ 
+ /*
+  * Per-instance context data for the device.
+  */
+ struct ak8975_data {
+ 	struct i2c_client	*client;
+-	struct attribute_group	attrs;
++	const struct ak_def	*def;
+ 	struct mutex		lock;
+ 	u8			asa[3];
+ 	long			raw_to_gauss[3];
+-	u8			reg_cache[AK8975_MAX_REGS];
+ 	int			eoc_gpio;
++	int			eoc_irq;
++	wait_queue_head_t	data_ready_queue;
++	unsigned long		flags;
++	u8			cntl_cache;
++	struct iio_mount_matrix orientation;
++	struct regulator	*vdd;
+ };
+ 
+-static const int ak8975_index_to_reg[] = {
+-	AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL,
+-};
++/* Enable attached power regulator if any. */
++static int ak8975_power_on(struct i2c_client *client)
++{
++	const struct iio_dev *indio_dev = i2c_get_clientdata(client);
++	struct ak8975_data *data = iio_priv(indio_dev);
++	int ret;
++
++	data->vdd = devm_regulator_get(&client->dev, "vdd");
++	if (IS_ERR_OR_NULL(data->vdd)) {
++		ret = PTR_ERR(data->vdd);
++		if (ret == -ENODEV)
++			ret = 0;
++	} else {
++		ret = regulator_enable(data->vdd);
++	}
++
++	if (ret)
++		dev_err(&client->dev, "failed to enable Vdd supply: %d\n", ret);
++	return ret;
++}
++
++/* Disable attached power regulator if any. */
++static void ak8975_power_off(const struct i2c_client *client)
++{
++	const struct iio_dev *indio_dev = i2c_get_clientdata(client);
++	const struct ak8975_data *data = iio_priv(indio_dev);
++
++	if (!IS_ERR_OR_NULL(data->vdd))
++		regulator_disable(data->vdd);
++}
+ 
+ /*
+- * Helper function to write to the I2C device's registers.
++ * Return 0 if the i2c device is the one we expect.
++ * return a negative error number otherwise
+  */
+-static int ak8975_write_data(struct i2c_client *client,
+-			     u8 reg, u8 val, u8 mask, u8 shift)
++static int ak8975_who_i_am(struct i2c_client *client,
++			   enum asahi_compass_chipset type)
++{
++	u8 wia_val[2];
++	int ret;
++
++	/*
++	 * Signature for each device:
++	 * Device   |  WIA1      |  WIA2
++	 * AK09912  |  DEVICE_ID |  AK09912_DEVICE_ID
++	 * AK09911  |  DEVICE_ID |  AK09911_DEVICE_ID
++	 * AK8975   |  DEVICE_ID |  NA
++	 * AK8963   |  DEVICE_ID |  NA
++	 */
++	ret = i2c_smbus_read_i2c_block_data(client, AK09912_REG_WIA1,
++					    2, wia_val);
++	if (ret < 0) {
++		dev_err(&client->dev, "Error reading WIA\n");
++		return ret;
++	}
++
++	if (wia_val[0] != AK8975_DEVICE_ID)
++		return -ENODEV;
++
++	switch (type) {
++	case AK8975:
++	case AK8963:
++		return 0;
++	case AK09911:
++		if (wia_val[1] == AK09911_DEVICE_ID)
++			return 0;
++		break;
++	case AK09912:
++		if (wia_val[1] == AK09912_DEVICE_ID)
++			return 0;
++		break;
++	default:
++		dev_err(&client->dev, "Type %d unknown\n", type);
++	}
++	return -ENODEV;
++}
++
++/*
++ * Helper function to write to CNTL register.
++ */
++static int ak8975_set_mode(struct ak8975_data *data, enum ak_ctrl_mode mode)
+ {
+-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+-	struct ak8975_data *data = iio_priv(indio_dev);
+ 	u8 regval;
+ 	int ret;
+ 
+-	regval = (data->reg_cache[reg] & ~mask) | (val << shift);
+-	ret = i2c_smbus_write_byte_data(client, reg, regval);
++	regval = (data->cntl_cache & ~data->def->ctrl_masks[CNTL_MODE]) |
++		 data->def->ctrl_modes[mode];
++	ret = i2c_smbus_write_byte_data(data->client,
++					data->def->ctrl_regs[CNTL], regval);
+ 	if (ret < 0) {
+-		dev_err(&client->dev, "Write to device fails status %x\n", ret);
+ 		return ret;
+ 	}
+-	data->reg_cache[reg] = regval;
++	data->cntl_cache = regval;
++	/* After mode change wait atleast 100us */
++	usleep_range(100, 500);
+ 
+ 	return 0;
+ }
+ 
++/*
++ * Handle data ready irq
++ */
++static irqreturn_t ak8975_irq_handler(int irq, void *data)
++{
++	struct ak8975_data *ak8975 = data;
++
++	set_bit(0, &ak8975->flags);
++	wake_up(&ak8975->data_ready_queue);
++
++	return IRQ_HANDLED;
++}
++
++/*
++ * Install data ready interrupt handler
++ */
++static int ak8975_setup_irq(struct ak8975_data *data)
++{
++	struct i2c_client *client = data->client;
++	int rc;
++	int irq;
++
++	init_waitqueue_head(&data->data_ready_queue);
++	clear_bit(0, &data->flags);
++	if (client->irq)
++		irq = client->irq;
++	else
++		irq = gpio_to_irq(data->eoc_gpio);
++
++	rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler,
++			      IRQF_TRIGGER_RISING | IRQF_ONESHOT,
++			      dev_name(&client->dev), data);
++	if (rc < 0) {
++		dev_err(&client->dev,
++			"irq %d request failed, (gpio %d): %d\n",
++			irq, data->eoc_gpio, rc);
++		return rc;
++	}
++
++	data->eoc_irq = irq;
++
++	return rc;
++}
++
++
+ /*
+  * Perform some start-of-day setup, including reading the asa calibration
+  * values and caching them.
+@@ -130,34 +531,18 @@ static int ak8975_setup(struct i2c_client *client)
+ {
+ 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ 	struct ak8975_data *data = iio_priv(indio_dev);
+-	u8 device_id;
+ 	int ret;
+ 
+-	/* Confirm that the device we're talking to is really an AK8975. */
+-	ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
+-	if (ret < 0) {
+-		dev_err(&client->dev, "Error reading WIA\n");
+-		return ret;
+-	}
+-	device_id = ret;
+-	if (device_id != AK8975_DEVICE_ID) {
+-		dev_err(&client->dev, "Device ak8975 not found\n");
+-		return -ENODEV;
+-	}
+-
+ 	/* Write the fused rom access mode. */
+-	ret = ak8975_write_data(client,
+-				AK8975_REG_CNTL,
+-				AK8975_REG_CNTL_MODE_FUSE_ROM,
+-				AK8975_REG_CNTL_MODE_MASK,
+-				AK8975_REG_CNTL_MODE_SHIFT);
++	ret = ak8975_set_mode(data, FUSE_ROM);
+ 	if (ret < 0) {
+ 		dev_err(&client->dev, "Error in setting fuse access mode\n");
+ 		return ret;
+ 	}
+ 
+ 	/* Get asa data and store in the device data. */
+-	ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX,
++	ret = i2c_smbus_read_i2c_block_data(client,
++					    data->def->ctrl_regs[ASA_BASE],
+ 					    3, data->asa);
+ 	if (ret < 0) {
+ 		dev_err(&client->dev, "Not able to read asa data\n");
+@@ -165,54 +550,24 @@ static int ak8975_setup(struct i2c_client *client)
+ 	}
+ 
+ 	/* After reading fuse ROM data set power-down mode */
+-	ret = ak8975_write_data(client,
+-				AK8975_REG_CNTL,
+-				AK8975_REG_CNTL_MODE_POWER_DOWN,
+-				AK8975_REG_CNTL_MODE_MASK,
+-				AK8975_REG_CNTL_MODE_SHIFT);
++	ret = ak8975_set_mode(data, POWER_DOWN);
+ 	if (ret < 0) {
+ 		dev_err(&client->dev, "Error in setting power-down mode\n");
+ 		return ret;
+ 	}
+ 
+-/*
+- * Precalculate scale factor (in Gauss units) for each axis and
+- * store in the device data.
+- *
+- * This scale factor is axis-dependent, and is derived from 3 calibration
+- * factors ASA(x), ASA(y), and ASA(z).
+- *
+- * These ASA values are read from the sensor device at start of day, and
+- * cached in the device context struct.
+- *
+- * Adjusting the flux value with the sensitivity adjustment value should be
+- * done via the following formula:
+- *
+- * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
+- *
+- * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
+- * is the resultant adjusted value.
+- *
+- * We reduce the formula to:
+- *
+- * Hadj = H * (ASA + 128) / 256
+- *
+- * H is in the range of -4096 to 4095.  The magnetometer has a range of
+- * +-1229uT.  To go from the raw value to uT is:
+- *
+- * HuT = H * 1229/4096, or roughly, 3/10.
+- *
+- * Since 1uT = 100 gauss, our final scale factor becomes:
+- *
+- * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
+- * Hadj = H * ((ASA + 128) * 30 / 256
+- *
+- * Since ASA doesn't change, we cache the resultant scale factor into the
+- * device context in ak8975_setup().
+- */
+-	data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
+-	data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
+-	data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
++	if (data->eoc_gpio > 0 || client->irq > 0) {
++		ret = ak8975_setup_irq(data);
++		if (ret < 0) {
++			dev_err(&client->dev,
++				"Error setting data ready interrupt\n");
++			return ret;
++		}
++	}
++
++	data->raw_to_gauss[0] = data->def->raw_to_gauss(data->asa[0]);
++	data->raw_to_gauss[1] = data->def->raw_to_gauss(data->asa[1]);
++	data->raw_to_gauss[2] = data->def->raw_to_gauss(data->asa[2]);
+ 
+ 	return 0;
+ }
+@@ -235,7 +590,7 @@ static int wait_conversion_complete_gpio(struct ak8975_data *data)
+ 		return -EINVAL;
+ 	}
+ 
+-	ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
++	ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST1]);
+ 	if (ret < 0)
+ 		dev_err(&client->dev, "Error in reading ST1\n");
+ 
+@@ -252,7 +607,8 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
+ 	/* Wait for the conversion to complete. */
+ 	while (timeout_ms) {
+ 		msleep(AK8975_CONVERSION_DONE_POLL_TIME);
+-		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
++		ret = i2c_smbus_read_byte_data(client,
++					       data->def->ctrl_regs[ST1]);
+ 		if (ret < 0) {
+ 			dev_err(&client->dev, "Error in reading ST1\n");
+ 			return ret;
+@@ -266,69 +622,89 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
+ 		dev_err(&client->dev, "Conversion timeout happened\n");
+ 		return -EINVAL;
+ 	}
++
+ 	return read_status;
+ }
+ 
+-/*
+- * Emits the raw flux value for the x, y, or z axis.
+- */
+-static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
++/* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */
++static int wait_conversion_complete_interrupt(struct ak8975_data *data)
+ {
+-	struct ak8975_data *data = iio_priv(indio_dev);
+-	struct i2c_client *client = data->client;
+ 	int ret;
+ 
+-	mutex_lock(&data->lock);
++	ret = wait_event_timeout(data->data_ready_queue,
++				 test_bit(0, &data->flags),
++				 AK8975_DATA_READY_TIMEOUT);
++	clear_bit(0, &data->flags);
+ 
++	return ret > 0 ? 0 : -ETIME;
++}
++
++static int ak8975_start_read_axis(struct ak8975_data *data,
++				  const struct i2c_client *client)
++{
+ 	/* Set up the device for taking a sample. */
+-	ret = ak8975_write_data(client,
+-				AK8975_REG_CNTL,
+-				AK8975_REG_CNTL_MODE_ONCE,
+-				AK8975_REG_CNTL_MODE_MASK,
+-				AK8975_REG_CNTL_MODE_SHIFT);
++	int ret = ak8975_set_mode(data, MODE_ONCE);
++
+ 	if (ret < 0) {
+ 		dev_err(&client->dev, "Error in setting operating mode\n");
+-		goto exit;
++		return ret;
+ 	}
+ 
+ 	/* Wait for the conversion to complete. */
+-	if (gpio_is_valid(data->eoc_gpio))
++	if (data->eoc_irq)
++		ret = wait_conversion_complete_interrupt(data);
++	else if (gpio_is_valid(data->eoc_gpio))
+ 		ret = wait_conversion_complete_gpio(data);
+ 	else
+ 		ret = wait_conversion_complete_polled(data);
+ 	if (ret < 0)
+-		goto exit;
++		return ret;
+ 
+-	if (ret & AK8975_REG_ST1_DRDY_MASK) {
+-		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
++	/* This will be executed only for non-interrupt based waiting case */
++	if (ret & data->def->ctrl_masks[ST1_DRDY]) {
++		ret = i2c_smbus_read_byte_data(client,
++					       data->def->ctrl_regs[ST2]);
+ 		if (ret < 0) {
+ 			dev_err(&client->dev, "Error in reading ST2\n");
+-			goto exit;
++			return ret;
+ 		}
+-		if (ret & (AK8975_REG_ST2_DERR_MASK |
+-			   AK8975_REG_ST2_HOFL_MASK)) {
++		if (ret & (data->def->ctrl_masks[ST2_DERR] |
++			   data->def->ctrl_masks[ST2_HOFL])) {
+ 			dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
+-			ret = -EINVAL;
+-			goto exit;
++			return -EINVAL;
+ 		}
+ 	}
+ 
+-	/* Read the flux value from the appropriate register
+-	   (the register is specified in the iio device attributes). */
+-	ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]);
+-	if (ret < 0) {
+-		dev_err(&client->dev, "Read axis data fails\n");
++	return 0;
++}
++
++/* Retrieve raw flux value for one of the x, y, or z axis.  */
++static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
++{
++	struct ak8975_data *data = iio_priv(indio_dev);
++	const struct i2c_client *client = data->client;
++	const struct ak_def *def = data->def;
++	int ret;
++
++	mutex_lock(&data->lock);
++
++	ret = ak8975_start_read_axis(data, client);
++	if (ret)
++		goto exit;
++
++	ret = i2c_smbus_read_word_data(client, def->data_regs[index]);
++	if (ret < 0)
+ 		goto exit;
+-	}
+ 
+ 	mutex_unlock(&data->lock);
+ 
+ 	/* Clamp to valid range. */
+-	*val = clamp_t(s16, ret, -4096, 4095);
++	*val = clamp_t(s16, ret, -def->range, def->range);
+ 	return IIO_VAL_INT;
+ 
+ exit:
+ 	mutex_unlock(&data->lock);
++	dev_err(&client->dev, "Error in reading axis\n");
+ 	return ret;
+ }
+ 
+@@ -343,12 +719,34 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
+ 	case IIO_CHAN_INFO_RAW:
+ 		return ak8975_read_axis(indio_dev, chan->address, val);
+ 	case IIO_CHAN_INFO_SCALE:
+-		*val = data->raw_to_gauss[chan->address];
+-		return IIO_VAL_INT;
++		*val = 0;
++		*val2 = data->raw_to_gauss[chan->address];
++		return IIO_VAL_INT_PLUS_MICRO;
+ 	}
+ 	return -EINVAL;
+ }
+ 
++static ssize_t ak8975_attr_show(struct device *dev, struct device_attribute *attr,
++			     char *buf)
++{
++	struct ak8975_data *data = iio_priv(dev_to_iio_dev(dev));
++	const char **m = data->orientation.rotation;
++
++	return sprintf(buf, "%s, %s, %s; %s, %s, %s; %s, %s, %s\n",
++		m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
++}
++
++static IIO_DEVICE_ATTR(in_mount_matrix, S_IRUGO, ak8975_attr_show, NULL, 0);
++
++static struct attribute *ak8975_attributes[] = {
++	&iio_dev_attr_in_mount_matrix.dev_attr.attr,
++	NULL,
++};
++
++static const struct attribute_group ak8975_attribute_group = {
++	.attrs = ak8975_attributes
++};
++
+ #define AK8975_CHANNEL(axis, index)					\
+ 	{								\
+ 		.type = IIO_MAGN,					\
+@@ -357,16 +755,104 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
+ 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
+ 			     BIT(IIO_CHAN_INFO_SCALE),			\
+ 		.address = index,					\
++		.scan_index = index,					\
++		.scan_type = {						\
++			.sign = 's',					\
++			.realbits = 16,					\
++			.storagebits = 16,				\
++			.endianness = IIO_CPU				\
++		},							\
+ 	}
+ 
+ static const struct iio_chan_spec ak8975_channels[] = {
+ 	AK8975_CHANNEL(X, 0), AK8975_CHANNEL(Y, 1), AK8975_CHANNEL(Z, 2),
++	IIO_CHAN_SOFT_TIMESTAMP(3),
+ };
+ 
++static const unsigned long ak8975_scan_masks[] = { 0x7, 0 };
++
+ static const struct iio_info ak8975_info = {
+ 	.read_raw = &ak8975_read_raw,
+ 	.driver_module = THIS_MODULE,
++	.attrs = &ak8975_attribute_group,
++};
++
++static const struct acpi_device_id ak_acpi_match[] = {
++	{"AK8975", AK8975},
++	{"AK8963", AK8963},
++	{"INVN6500", AK8963},
++	{"AK09911", AK09911},
++	{"AK09912", AK09912},
++	{ },
+ };
++MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
++
++static const char *ak8975_match_acpi_device(struct device *dev,
++					    enum asahi_compass_chipset *chipset)
++{
++	const struct acpi_device_id *id;
++
++	id = acpi_match_device(dev->driver->acpi_match_table, dev);
++	if (!id)
++		return NULL;
++	*chipset = (int)id->driver_data;
++
++	return dev_name(dev);
++}
++
++static void ak8975_fill_buffer(struct iio_dev *indio_dev)
++{
++	struct ak8975_data *data = iio_priv(indio_dev);
++	const struct i2c_client *client = data->client;
++	const struct ak_def *def = data->def;
++	int ret;
++	s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */
++	u64 *tmp;
++
++	mutex_lock(&data->lock);
++
++	ret = ak8975_start_read_axis(data, client);
++	if (ret)
++		goto unlock;
++
++	/*
++	 * For each axis, read the flux value from the appropriate register
++	 * (the register is specified in the iio device attributes).
++	 */
++	ret = i2c_smbus_read_i2c_block_data(client,
++							def->data_regs[0],
++							3 * sizeof(buff[0]),
++							(u8 *)buff);
++	if (ret < 0)
++		goto unlock;
++
++	mutex_unlock(&data->lock);
++
++	/* Clamp to valid range. */
++	buff[0] = clamp_t(s16, le16_to_cpu(buff[0]), -def->range, def->range);
++	buff[1] = clamp_t(s16, le16_to_cpu(buff[1]), -def->range, def->range);
++	buff[2] = clamp_t(s16, le16_to_cpu(buff[2]), -def->range, def->range);
++
++	tmp = (u64 *)buff;
++	tmp[1] = iio_get_time_ns();
++	iio_push_to_buffers(indio_dev, (void *)buff);
++
++	return;
++
++unlock:
++	mutex_unlock(&data->lock);
++	dev_err(&client->dev, "Error in reading axes block\n");
++}
++
++static irqreturn_t ak8975_handle_trigger(int irq, void *p)
++{
++	const struct iio_poll_func *pf = p;
++	struct iio_dev *indio_dev = pf->indio_dev;
++
++	ak8975_fill_buffer(indio_dev);
++	iio_trigger_notify_done(indio_dev->trig);
++	return IRQ_HANDLED;
++}
+ 
+ static int ak8975_probe(struct i2c_client *client,
+ 			const struct i2c_device_id *id)
+@@ -375,81 +861,139 @@ static int ak8975_probe(struct i2c_client *client,
+ 	struct iio_dev *indio_dev;
+ 	int eoc_gpio;
+ 	int err;
++	const char *name = NULL;
++	enum asahi_compass_chipset chipset = AK_MAX_TYPE;
+ 
+ 	/* Grab and set up the supplied GPIO. */
+-	if (client->dev.platform_data == NULL)
+-		eoc_gpio = -1;
++	if (client->dev.of_node)
++		eoc_gpio = of_get_gpio(client->dev.of_node, 0);
+ 	else
+-		eoc_gpio = *(int *)(client->dev.platform_data);
++		eoc_gpio = -1;
++
++	if (eoc_gpio == -EPROBE_DEFER)
++		return -EPROBE_DEFER;
+ 
+ 	/* We may not have a GPIO based IRQ to scan, that is fine, we will
+ 	   poll if so */
+ 	if (gpio_is_valid(eoc_gpio)) {
+-		err = gpio_request_one(eoc_gpio, GPIOF_IN, "ak_8975");
++		err = devm_gpio_request_one(&client->dev, eoc_gpio,
++							GPIOF_IN, "ak_8975");
+ 		if (err < 0) {
+ 			dev_err(&client->dev,
+ 				"failed to request GPIO %d, error %d\n",
+ 							eoc_gpio, err);
+-			goto exit;
++			return err;
+ 		}
+ 	}
+ 
+ 	/* Register with IIO */
+ 	indio_dev = iio_device_alloc(sizeof(*data));
+-	if (indio_dev == NULL) {
+-		err = -ENOMEM;
+-		goto exit_gpio;
+-	}
++	if (indio_dev == NULL)
++		return -ENOMEM;
++
+ 	data = iio_priv(indio_dev);
+ 	i2c_set_clientdata(client, indio_dev);
++
++	data->client = client;
++	data->eoc_gpio = eoc_gpio;
++	data->eoc_irq = 0;
++
++
++	err = of_property_read_string_array(client->dev.of_node,
++			"mount-matrix", data->orientation.rotation,
++			ARRAY_SIZE(data->orientation.rotation));
++
++	if (err != ARRAY_SIZE(data->orientation.rotation)) {
++		dev_err(&client->dev, "Failed to retrieve mounting matrix %d\n", err);
++		return err;
++	}
++
++	/* id will be NULL when enumerated via ACPI */
++	if (id) {
++		chipset = (enum asahi_compass_chipset)(id->driver_data);
++		name = id->name;
++	} else if (ACPI_HANDLE(&client->dev)) {
++		name = ak8975_match_acpi_device(&client->dev, &chipset);
++		if (!name)
++			return -ENODEV;
++	} else
++		return -ENOSYS;
++
++	if (chipset >= AK_MAX_TYPE) {
++		dev_err(&client->dev, "AKM device type unsupported: %d\n",
++			chipset);
++		return -ENODEV;
++	}
++
++	data->def = &ak_def_array[chipset];
++
++	err = ak8975_power_on(client);
++	if (err)
++		return err;
++
++	err = ak8975_who_i_am(client, data->def->type);
++	if (err < 0) {
++		dev_err(&client->dev, "Unexpected device\n");
++		goto power_off;
++	}
++	dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
++
+ 	/* Perform some basic start-of-day setup of the device. */
+ 	err = ak8975_setup(client);
+ 	if (err < 0) {
+-		dev_err(&client->dev, "AK8975 initialization fails\n");
+-		goto exit_free_iio;
++		dev_err(&client->dev, "%s initialization fails\n", name);
++		goto power_off;
+ 	}
+ 
+-	data->client = client;
+ 	mutex_init(&data->lock);
+-	data->eoc_gpio = eoc_gpio;
+ 	indio_dev->dev.parent = &client->dev;
+ 	indio_dev->channels = ak8975_channels;
+ 	indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
+ 	indio_dev->info = &ak8975_info;
++	indio_dev->available_scan_masks = ak8975_scan_masks;
+ 	indio_dev->modes = INDIO_DIRECT_MODE;
++	indio_dev->name = name;
++
++	err = iio_triggered_buffer_setup(indio_dev, NULL, ak8975_handle_trigger,
++					 NULL);
++	if (err) {
++		dev_err(&client->dev, "triggered buffer setup failed\n");
++		goto power_off;
++	}
+ 
+ 	err = iio_device_register(indio_dev);
+-	if (err < 0)
+-		goto exit_free_iio;
++	if (err) {
++		dev_err(&client->dev, "device register failed\n");
++		goto cleanup_buffer;
++	}
+ 
+ 	return 0;
+ 
+-exit_free_iio:
+-	iio_device_free(indio_dev);
+-exit_gpio:
+-	if (gpio_is_valid(eoc_gpio))
+-		gpio_free(eoc_gpio);
+-exit:
++cleanup_buffer:
++	iio_triggered_buffer_cleanup(indio_dev);
++power_off:
++	ak8975_power_off(client);
+ 	return err;
+ }
+ 
+ static int ak8975_remove(struct i2c_client *client)
+ {
+ 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+-	struct ak8975_data *data = iio_priv(indio_dev);
+ 
+ 	iio_device_unregister(indio_dev);
+-
+-	if (gpio_is_valid(data->eoc_gpio))
+-		gpio_free(data->eoc_gpio);
+-
++	iio_triggered_buffer_cleanup(indio_dev);
+ 	iio_device_free(indio_dev);
++	ak8975_power_off(client);
+ 
+ 	return 0;
+ }
+ 
+ static const struct i2c_device_id ak8975_id[] = {
+-	{"ak8975", 0},
++	{"ak8975", AK8975},
++	{"ak8963", AK8963},
++	{"AK8963", AK8963},
++	{"ak09911", AK09911},
++	{"ak09912", AK09912},
+ 	{}
+ };
+ 
+@@ -458,14 +1002,21 @@ MODULE_DEVICE_TABLE(i2c, ak8975_id);
+ static const struct of_device_id ak8975_of_match[] = {
+ 	{ .compatible = "asahi-kasei,ak8975", },
+ 	{ .compatible = "ak8975", },
+-	{ }
++	{ .compatible = "asahi-kasei,ak8963", },
++	{ .compatible = "ak8963", },
++	{ .compatible = "asahi-kasei,ak09911", },
++	{ .compatible = "ak09911", },
++	{ .compatible = "asahi-kasei,ak09912", },
++	{ .compatible = "ak09912", },
++	{}
+ };
+ MODULE_DEVICE_TABLE(of, ak8975_of_match);
+ 
+ static struct i2c_driver ak8975_driver = {
+ 	.driver = {
+ 		.name	= "ak8975",
+-		.of_match_table = ak8975_of_match,
++		.of_match_table = of_match_ptr(ak8975_of_match),
++		.acpi_match_table = ACPI_PTR(ak_acpi_match),
+ 	},
+ 	.probe		= ak8975_probe,
+ 	.remove		= ak8975_remove,
+diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
+index bb698e1f..5e4807de 100644
+--- a/drivers/input/misc/Kconfig
++++ b/drivers/input/misc/Kconfig
+@@ -93,6 +93,18 @@ config INPUT_BMA150
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called bma150.
+ 
++config INPUT_AMBARELLA_IR
++	tristate "Support Ambarella Soc IR"
++	default n
++	help
++	  Say Y here if your Ambarella Boards have Keys with IR.
++
++config INPUT_AMBARELLA_ADC
++	tristate "Support Ambarella Soc ADC"
++	default n
++	help
++	  Say Y here if your Ambarella Boards have Keys with ADC.
++
+ config INPUT_PCSPKR
+ 	tristate "PC Speaker support"
+ 	depends on PCSPKR_PLATFORM
+diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
+index d7fc17f1..f05e676e 100644
+--- a/drivers/input/misc/Makefile
++++ b/drivers/input/misc/Makefile
+@@ -13,6 +13,10 @@ obj-$(CONFIG_INPUT_AD714X_SPI)		+= ad714x-spi.o
+ obj-$(CONFIG_INPUT_ADXL34X)		+= adxl34x.o
+ obj-$(CONFIG_INPUT_ADXL34X_I2C)		+= adxl34x-i2c.o
+ obj-$(CONFIG_INPUT_ADXL34X_SPI)		+= adxl34x-spi.o
++
++obj-$(CONFIG_INPUT_AMBARELLA_IR)	+= ambarella_input_ir.o
++obj-$(CONFIG_INPUT_AMBARELLA_ADC)	+= ambarella_input_adc.o
++
+ obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
+ obj-$(CONFIG_INPUT_ARIZONA_HAPTICS)	+= arizona-haptics.o
+ obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
+diff --git a/drivers/input/misc/ambarella_input_adc.c b/drivers/input/misc/ambarella_input_adc.c
+new file mode 100644
+index 00000000..bd980486
+--- /dev/null
++++ b/drivers/input/misc/ambarella_input_adc.c
+@@ -0,0 +1,280 @@
++/*
++ * drivers/input/misc/ambarella_input_adc.c
++ *
++ * Author: Qiao Wang <qwang@ambarella.com>
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ *  @History        ::
++ *      Date        Name             Comments
++ *      07/16/2014  Bing-Liang Hu    irq or polling depend on adc irq support
++ *      07/21/2014  Cao Rongrong     re-design the mechanism with ADC
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/input.h>
++#include <linux/slab.h>
++#include <linux/of.h>
++#include <plat/adc.h>
++
++struct ambadc_keymap {
++	u32 key_code;
++	u32 channel : 4;
++	u32 low_level : 12;
++	u32 high_level : 12;
++};
++
++struct ambarella_adckey {
++	struct input_dev *input;
++	struct ambadc_client *adc_client;
++
++	struct ambadc_keymap *keymap;
++	u32 key_num;
++	u32 key_saved[ADC_NUM_CHANNELS]; /* save the key currently pressed */
++	u32 print_key : 1;
++};
++
++static void ambarella_adckey_filter_out(struct ambadc_client *client,
++		struct ambadc_keymap *keymap)
++{
++	/* we expect the adc level which is out of current key's range. */
++	ambarella_adc_set_threshold(client,
++		keymap->channel, keymap->low_level, keymap->high_level);
++}
++
++static int ambarella_adckey_callback(struct ambadc_client *client,
++		u32 ch, u32 level)
++{
++	struct ambarella_adckey *adckey;
++	struct ambadc_keymap *keymap;
++	struct input_dev *input;
++	u32 i;
++
++	adckey = dev_get_drvdata(client->dev);
++	if(adckey == NULL)
++		return -EAGAIN;
++
++	keymap = adckey->keymap;
++	input = adckey->input;
++
++	for (i = 0; i < adckey->key_num; i++, keymap++) {
++		if (ch != keymap->channel
++			|| level < keymap->low_level
++			|| level > keymap->high_level)
++			continue;
++
++		if (adckey->key_saved[ch] == KEY_RESERVED
++			&& keymap->key_code != KEY_RESERVED) {
++			input_report_key(input, keymap->key_code, 1);
++			input_sync(input);
++			adckey->key_saved[ch] = keymap->key_code;
++			ambarella_adckey_filter_out(client, keymap);
++
++			if (adckey->print_key) {
++				dev_info(&input->dev, "key[%d:%d] pressed %d\n",
++					ch, adckey->key_saved[ch], level);
++			}
++			break;
++		} else if (adckey->key_saved[ch] != KEY_RESERVED
++			&& keymap->key_code == KEY_RESERVED) {
++			input_report_key(input, adckey->key_saved[ch], 0);
++			input_sync(input);
++			adckey->key_saved[ch] = KEY_RESERVED;
++			ambarella_adckey_filter_out(client, keymap);
++
++			if (adckey->print_key) {
++				dev_info(&input->dev, "key[%d:%d] released %d\n",
++					ch, adckey->key_saved[ch], level);
++			}
++			break;
++		}
++	}
++
++	return 0;
++}
++
++static int ambarella_adckey_of_parse(struct platform_device *pdev,
++		struct ambarella_adckey *adckey)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct ambadc_keymap *keymap;
++	const __be32 *prop;
++	u32 propval, i, size;
++
++	adckey->print_key = !!of_find_property(np, "amb,print-key", NULL);
++
++	prop = of_get_property(np, "amb,keymap", &size);
++	if (!prop || size % (sizeof(__be32) * 2)) {
++		dev_err(&pdev->dev, "Invalid keymap!\n");
++		return -ENOENT;
++	}
++
++	/* cells is 2 for each keymap */
++	size /= sizeof(__be32) * 2;
++	adckey->key_num = size;
++
++	adckey->keymap = devm_kzalloc(&pdev->dev,
++			sizeof(struct ambadc_keymap) * size, GFP_KERNEL);
++	if (adckey->keymap == NULL){
++		dev_err(&pdev->dev, "No memory for keymap!\n");
++		return -ENOMEM;
++	}
++
++	keymap = adckey->keymap;
++
++	for (i = 0; i < adckey->key_num; i++, keymap++) {
++		propval = be32_to_cpup(prop + i * 2);
++		keymap->low_level = propval & 0xfff;
++		keymap->high_level = (propval >> 16) & 0xfff;
++		keymap->channel = propval >> 28;
++		if (keymap->channel >= ADC_NUM_CHANNELS) {
++			dev_err(&pdev->dev, "Invalid channel: %d\n", keymap->channel);
++			return -EINVAL;
++		}
++
++		propval = be32_to_cpup(prop + i * 2 + 1);
++		keymap->key_code = propval;
++
++		if (keymap->key_code == KEY_RESERVED)
++			ambarella_adckey_filter_out(adckey->adc_client, keymap);
++
++		input_set_capability(adckey->input, EV_KEY, keymap->key_code);
++	}
++
++	for (i = 0; i < ADC_NUM_CHANNELS; i++)
++		adckey->key_saved[i] = KEY_RESERVED;
++
++	return 0;
++}
++
++static int ambarella_adckey_probe(struct platform_device *pdev)
++{
++	struct ambarella_adckey *adckey;
++	struct input_dev *input;
++	int rval = 0;
++
++	adckey = devm_kzalloc(&pdev->dev,
++			     sizeof(struct ambarella_adckey),
++			     GFP_KERNEL);
++	if (!adckey) {
++		dev_err(&pdev->dev, "Failed to allocate adckey!\n");
++		return -ENOMEM;
++	}
++
++	input = input_allocate_device();
++	if (!input) {
++		dev_err(&pdev->dev, "input_allocate_device fail!\n");
++		return -ENOMEM;
++	}
++
++	input->name = "AmbADCkey";
++	input->phys = "ambadckey/input0";
++	input->id.bustype = BUS_HOST;
++	input->dev.parent = &pdev->dev;
++
++	rval = input_register_device(input);
++	if (rval < 0) {
++		dev_err(&pdev->dev, "Register input_dev failed!\n");
++		goto adckey_probe_err0;
++	}
++
++	adckey->input = input;
++
++	adckey->adc_client = ambarella_adc_register_client(&pdev->dev,
++					AMBADC_CONTINUOUS,
++					ambarella_adckey_callback);
++	if (!adckey->adc_client) {
++		dev_err(&pdev->dev, "Register adc client failed!\n");
++		goto adckey_probe_err1;
++	}
++
++	rval = ambarella_adckey_of_parse(pdev, adckey);
++	if (rval < 0)
++		goto adckey_probe_err2;
++
++	platform_set_drvdata(pdev, adckey);
++
++	dev_info(&pdev->dev, "ADC key input driver probed!\n");
++
++	return 0;
++
++adckey_probe_err2:
++	ambarella_adc_unregister_client(adckey->adc_client);
++adckey_probe_err1:
++	input_unregister_device(adckey->input);
++adckey_probe_err0:
++	input_free_device(input);
++	return rval;
++}
++
++static int ambarella_adckey_remove(struct platform_device *pdev)
++{
++	struct ambarella_adckey *adckey;
++	int rval = 0;
++
++	adckey = platform_get_drvdata(pdev);
++
++	ambarella_adc_unregister_client(adckey->adc_client);
++	input_unregister_device(adckey->input);
++	input_free_device(adckey->input);
++
++	dev_info(&pdev->dev, "Remove Ambarella ADC Key driver.\n");
++
++	return rval;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_adckey_suspend(struct platform_device *pdev,
++		pm_message_t state)
++{
++	return 0;
++}
++
++static int ambarella_adckey_resume(struct platform_device *pdev)
++{
++	return 0;
++}
++#endif
++
++static const struct of_device_id ambarella_adckey_dt_ids[] = {
++	{.compatible = "ambarella,input_adckey", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_adckey_dt_ids);
++
++static struct platform_driver ambarella_adckey_driver = {
++	.probe		= ambarella_adckey_probe,
++	.remove		= ambarella_adckey_remove,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_adckey_suspend,
++	.resume		= ambarella_adckey_resume,
++#endif
++	.driver		= {
++		.name	= "ambarella-adckey",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_adckey_dt_ids,
++	},
++};
++
++module_platform_driver(ambarella_adckey_driver);
++
++MODULE_AUTHOR("Bing-Liang Hu <blhu@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella ADC key Driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/input/misc/ambarella_input_ir.c b/drivers/input/misc/ambarella_input_ir.c
+new file mode 100644
+index 00000000..966090cc
+--- /dev/null
++++ b/drivers/input/misc/ambarella_input_ir.c
+@@ -0,0 +1,504 @@
++/*
++ * drivers/input/misc/ambarella_input_ir.c
++ *
++ * Author: Qiao Wang <qwang@ambarella.com>
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/slab.h>
++#include <linux/clk.h>
++#include <linux/of.h>
++#include <plat/ir.h>
++
++#define MAX_IR_BUFFER			512
++#define HW_FIFO_BUFFER			48
++
++struct ambarella_ir_keymap {
++	u32 key_code;
++	u32 key_raw;
++};
++
++struct ambarella_ir_frame_info {
++	u32				frame_head_size;
++	u32				frame_data_size;
++	u32				frame_end_size;
++	u32				frame_repeat_head_size;
++};
++
++struct ambarella_ir_info {
++	struct input_dev		*input;
++	unsigned char __iomem 		*regbase;
++	unsigned int			irq;
++
++	int (*ir_parse)(struct ambarella_ir_info *pirinfo, u32 *uid);
++	int				ir_pread;
++	int				ir_pwrite;
++	u16				tick_buf[MAX_IR_BUFFER];
++	struct ambarella_ir_frame_info 	frame_info;
++	u32				frame_data_to_received;
++
++
++	struct ambarella_ir_keymap	*keymap;
++	u32				key_num;
++
++	u32				protocol;
++	u32				print_key : 1;
++};
++
++/* ========================================================================= */
++static u16 ambarella_ir_read_data(
++	struct ambarella_ir_info *pirinfo, int pointer)
++{
++	BUG_ON(pointer < 0);
++	BUG_ON(pointer >= MAX_IR_BUFFER);
++	BUG_ON(pointer == pirinfo->ir_pwrite);
++
++	return pirinfo->tick_buf[pointer];
++}
++
++static int ambarella_ir_get_tick_size(struct ambarella_ir_info *pirinfo)
++{
++	int				size = 0;
++
++	if (pirinfo->ir_pread > pirinfo->ir_pwrite)
++		size = MAX_IR_BUFFER - pirinfo->ir_pread + pirinfo->ir_pwrite;
++	else
++		size = pirinfo->ir_pwrite - pirinfo->ir_pread;
++
++	return size;
++}
++
++void ambarella_ir_inc_read_ptr(struct ambarella_ir_info *pirinfo)
++{
++	BUG_ON(pirinfo->ir_pread == pirinfo->ir_pwrite);
++
++	pirinfo->ir_pread++;
++	if (pirinfo->ir_pread >= MAX_IR_BUFFER)
++		pirinfo->ir_pread = 0;
++}
++
++void ambarella_ir_move_read_ptr(struct ambarella_ir_info *pirinfo, int offset)
++{
++	for (; offset > 0; offset--) {
++		ambarella_ir_inc_read_ptr(pirinfo);
++	}
++}
++
++/* ========================================================================= */
++#include "ambarella_ir_nec.c"
++#include "ambarella_ir_sony.c"
++#include "ambarella_ir_philips.c"
++#include "ambarella_ir_panasonic.c"
++
++/* ========================================================================= */
++static int ambarella_input_report_ir(struct ambarella_ir_info *pirinfo, u32 uid)
++{
++	struct ambarella_ir_keymap *keymap = pirinfo->keymap;
++	struct input_dev *input = pirinfo->input;
++	int i;
++
++	for (i = 0; i < pirinfo->key_num; i++, keymap++) {
++		if (keymap->key_raw == uid) {
++			input_report_key(input, keymap->key_code, 1);
++			input_sync(input);
++			input_report_key(input, keymap->key_code, 0);
++			input_sync(input);
++			if(pirinfo->print_key)
++				dev_info(&input->dev, "IR_KEY [%d]\n", keymap->key_code);
++			break;
++		}
++	}
++
++	return 0;
++}
++
++static inline void ambarella_ir_write_data(struct ambarella_ir_info *pirinfo,
++	u16 val)
++{
++	BUG_ON(pirinfo->ir_pwrite < 0);
++	BUG_ON(pirinfo->ir_pwrite >= MAX_IR_BUFFER);
++
++	pirinfo->tick_buf[pirinfo->ir_pwrite] = val;
++
++	pirinfo->ir_pwrite++;
++
++	if (pirinfo->ir_pwrite >= MAX_IR_BUFFER)
++		pirinfo->ir_pwrite = 0;
++}
++
++static inline int ambarella_ir_update_buffer(struct ambarella_ir_info *pirinfo)
++{
++	int				count;
++	int				size;
++
++	count = amba_readl(pirinfo->regbase + IR_STATUS_OFFSET);
++	dev_dbg(&pirinfo->input->dev, "size we got is [%d]\n", count);
++	for (; count > 0; count--) {
++		ambarella_ir_write_data(pirinfo,
++			amba_readl(pirinfo->regbase + IR_DATA_OFFSET));
++	}
++	size = ambarella_ir_get_tick_size(pirinfo);
++
++	return size;
++}
++
++static irqreturn_t ambarella_ir_irq(int irq, void *devid)
++{
++	struct ambarella_ir_info *pirinfo;
++	u32 ctrl_val, uid, edges;
++	int rval;
++
++	pirinfo = (struct ambarella_ir_info *)devid;
++
++	BUG_ON(pirinfo->ir_pread < 0);
++	BUG_ON(pirinfo->ir_pread >= MAX_IR_BUFFER);
++
++	ctrl_val = amba_readl(pirinfo->regbase + IR_CONTROL_OFFSET);
++	if (ctrl_val & IR_CONTROL_FIFO_OV) {
++		while (amba_readl(pirinfo->regbase + IR_STATUS_OFFSET) > 0)
++			amba_readl(pirinfo->regbase + IR_DATA_OFFSET);
++
++		amba_setbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
++					IR_CONTROL_FIFO_OV);
++
++		dev_err(&pirinfo->input->dev,
++			"IR_CONTROL_FIFO_OV overflow\n");
++
++		goto ambarella_ir_irq_exit;
++	}
++
++	ambarella_ir_update_buffer(pirinfo);
++
++	if(!pirinfo->ir_parse)
++		goto ambarella_ir_irq_exit;
++
++	rval = pirinfo->ir_parse(pirinfo, &uid);
++
++	if (rval == 0) {
++		/* yes, we find the key */
++		if(pirinfo->print_key)
++			dev_info(&pirinfo->input->dev, "uid = 0x%08x\n", uid);
++		ambarella_input_report_ir(pirinfo, uid);
++	}
++
++	pirinfo->frame_data_to_received = pirinfo->frame_info.frame_data_size +
++		pirinfo->frame_info.frame_head_size;
++	pirinfo->frame_data_to_received -= ambarella_ir_get_tick_size(pirinfo);
++
++	if (pirinfo->frame_data_to_received <= HW_FIFO_BUFFER) {
++		edges = pirinfo->frame_data_to_received;
++		pirinfo->frame_data_to_received = 0;
++	} else {// > HW_FIFO_BUFFER
++		edges = HW_FIFO_BUFFER;
++		pirinfo->frame_data_to_received -= HW_FIFO_BUFFER;
++	}
++
++	dev_dbg(&pirinfo->input->dev,
++		"line[%d],frame_data_to_received[%d]\n", __LINE__, edges);
++	amba_clrbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
++		IR_CONTROL_INTLEV(0x3F));
++	amba_setbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
++		IR_CONTROL_INTLEV(edges));
++
++ambarella_ir_irq_exit:
++	amba_writel(pirinfo->regbase + IR_CONTROL_OFFSET,
++		(amba_readl(pirinfo->regbase + IR_CONTROL_OFFSET) |
++		IR_CONTROL_LEVINT));
++
++	return IRQ_HANDLED;
++}
++
++void ambarella_ir_enable(struct ambarella_ir_info *pirinfo)
++{
++	u32 edges;
++
++	pirinfo->frame_data_to_received = pirinfo->frame_info.frame_head_size
++		+ pirinfo->frame_info.frame_data_size;
++
++	BUG_ON(pirinfo->frame_data_to_received > MAX_IR_BUFFER);
++
++	if (pirinfo->frame_data_to_received > HW_FIFO_BUFFER) {
++		edges = HW_FIFO_BUFFER;
++		pirinfo->frame_data_to_received -= HW_FIFO_BUFFER;
++	} else {
++		edges = pirinfo->frame_data_to_received;
++		pirinfo->frame_data_to_received = 0;
++	}
++	amba_writel(pirinfo->regbase + IR_CONTROL_OFFSET, IR_CONTROL_RESET);
++	amba_setbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
++		IR_CONTROL_ENB | IR_CONTROL_INTLEV(edges) | IR_CONTROL_INTENB);
++
++	enable_irq(pirinfo->irq);
++}
++
++void ambarella_ir_disable(struct ambarella_ir_info *pirinfo)
++{
++	disable_irq(pirinfo->irq);
++}
++
++void ambarella_ir_set_protocol(struct ambarella_ir_info *pirinfo,
++	enum ambarella_ir_protocol protocol_id)
++{
++	memset(pirinfo->tick_buf, 0x0, sizeof(pirinfo->tick_buf));
++	pirinfo->ir_pread  = 0;
++	pirinfo->ir_pwrite = 0;
++
++	switch (protocol_id) {
++	case AMBA_IR_PROTOCOL_NEC:
++		dev_notice(&pirinfo->input->dev,
++			"Protocol NEC[%d]\n", protocol_id);
++		pirinfo->ir_parse = ambarella_ir_nec_parse;
++		ambarella_ir_get_nec_info(&pirinfo->frame_info);
++		break;
++	case AMBA_IR_PROTOCOL_PANASONIC:
++		dev_notice(&pirinfo->input->dev,
++			"Protocol PANASONIC[%d]\n", protocol_id);
++		pirinfo->ir_parse = ambarella_ir_panasonic_parse;
++		ambarella_ir_get_panasonic_info(&pirinfo->frame_info);
++		break;
++	case AMBA_IR_PROTOCOL_SONY:
++		dev_notice(&pirinfo->input->dev,
++			"Protocol SONY[%d]\n", protocol_id);
++		pirinfo->ir_parse = ambarella_ir_sony_parse;
++		ambarella_ir_get_sony_info(&pirinfo->frame_info);
++		break;
++	case AMBA_IR_PROTOCOL_PHILIPS:
++		dev_notice(&pirinfo->input->dev,
++			"Protocol PHILIPS[%d]\n", protocol_id);
++		pirinfo->ir_parse = ambarella_ir_philips_parse;
++		ambarella_ir_get_philips_info(&pirinfo->frame_info);
++		break;
++	default:
++		dev_notice(&pirinfo->input->dev,
++			"Protocol default NEC[%d]\n", protocol_id);
++		pirinfo->ir_parse = ambarella_ir_nec_parse;
++		ambarella_ir_get_nec_info(&pirinfo->frame_info);
++		break;
++	}
++}
++
++static void ambarella_ir_init(struct ambarella_ir_info *pirinfo)
++{
++	ambarella_ir_disable(pirinfo);
++
++	clk_set_rate(clk_get(NULL, "gclk_ir"), 13000);
++
++	ambarella_ir_set_protocol(pirinfo, pirinfo->protocol);
++
++	ambarella_ir_enable(pirinfo);
++}
++
++static int ambarella_ir_of_parse(struct platform_device *pdev,
++					struct ambarella_ir_info *pirinfo)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct ambarella_ir_keymap *keymap;
++	const __be32 *prop;
++	int rval, i, size;
++
++	rval = of_property_read_u32(np, "amb,protocol", &pirinfo->protocol);
++	if (rval < 0 || pirinfo->protocol >= AMBA_IR_PROTOCOL_END)
++		pirinfo->protocol = AMBA_IR_PROTOCOL_NEC;
++
++	pirinfo->print_key = !!of_find_property(np, "amb,print-key", NULL);
++
++	prop = of_get_property(np, "amb,keymap", &size);
++	if (!prop || size % (sizeof(__be32) * 2)) {
++		dev_err(&pdev->dev, "Invalid keymap!\n");
++		return -ENOENT;
++	}
++
++	/* cells is 2 for each keymap */
++	size /= sizeof(__be32) * 2;
++
++	pirinfo->key_num = size;
++	pirinfo->keymap = devm_kzalloc(&pdev->dev,
++			sizeof(struct ambarella_ir_keymap) * size, GFP_KERNEL);
++	if (pirinfo->keymap == NULL){
++		dev_err(&pdev->dev, "No memory!\n");
++		return -ENOMEM;
++	}
++
++	keymap = pirinfo->keymap;
++	for (i = 0; i < size; i++) {
++		keymap->key_raw = be32_to_cpup(prop + i * 2);
++		keymap->key_code = be32_to_cpup(prop + i * 2 + 1);
++		input_set_capability(pirinfo->input, EV_KEY, keymap->key_code);
++		keymap++;
++	}
++
++	return 0;
++}
++
++static int ambarella_ir_probe(struct platform_device *pdev)
++{
++	struct ambarella_ir_info *pirinfo;
++	struct input_dev *input;
++	struct resource *mem;
++	int retval;
++
++	pirinfo = devm_kzalloc(&pdev->dev,
++			sizeof(struct ambarella_ir_info), GFP_KERNEL);
++	if (!pirinfo) {
++		dev_err(&pdev->dev, "Failed to allocate pirinfo!\n");
++		return -ENOMEM;
++	}
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	pirinfo->regbase = devm_ioremap(&pdev->dev,
++					mem->start, resource_size(mem));
++	if (!pirinfo->regbase) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	pirinfo->irq = platform_get_irq(pdev, 0);
++	if (pirinfo->irq < 0) {
++		dev_err(&pdev->dev, "Get irq failed!\n");
++		return -ENXIO;
++	}
++
++	input = input_allocate_device();
++	if (!input) {
++		dev_err(&pdev->dev, "input_allocate_device fail!\n");
++		return -ENOMEM;
++	}
++
++	input->name = "AmbIR";
++	input->phys = "ambir/input0";
++	input->id.bustype = BUS_HOST;
++
++	retval = input_register_device(input);
++	if (retval) {
++		dev_err(&pdev->dev, "Register input_dev failed!\n");
++		goto ir_err0;
++	}
++
++	pirinfo->input = input;
++
++	retval = ambarella_ir_of_parse(pdev, pirinfo);
++	if (retval)
++		goto ir_err1;
++
++	platform_set_drvdata(pdev, pirinfo);
++
++	retval = devm_request_irq(&pdev->dev, pirinfo->irq,
++			ambarella_ir_irq, IRQF_TRIGGER_HIGH,
++			dev_name(&pdev->dev), pirinfo);
++	if (retval < 0) {
++		dev_err(&pdev->dev, "Request IRQ failed!\n");
++		goto ir_err1;
++	}
++
++	ambarella_ir_init(pirinfo);
++
++	dev_notice(&pdev->dev, "IR Host Controller probed!\n");
++
++	return 0;
++
++ir_err1:
++	input_unregister_device(input);
++ir_err0:
++	input_free_device(input);
++	return retval;
++}
++
++static int ambarella_ir_remove(struct platform_device *pdev)
++{
++	struct ambarella_ir_info *pirinfo;
++	int retval = 0;
++
++	pirinfo = platform_get_drvdata(pdev);
++
++	input_unregister_device(pirinfo->input);
++	input_free_device(pirinfo->input);
++
++	dev_notice(&pdev->dev, "Remove Ambarella IR Host Controller.\n");
++
++	return retval;
++}
++
++#if (defined CONFIG_PM)
++static int ambarella_ir_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	int					retval = 0;
++	struct ambarella_ir_info		*pirinfo;
++
++	pirinfo = platform_get_drvdata(pdev);
++
++	disable_irq(pirinfo->irq);
++	amba_clrbitsl(pirinfo->regbase + IR_CONTROL_OFFSET, IR_CONTROL_INTENB);
++
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++		__func__, retval, state.event);
++	return retval;
++}
++
++static int ambarella_ir_resume(struct platform_device *pdev)
++{
++	int					retval = 0;
++	struct ambarella_ir_info		*pirinfo;
++
++	pirinfo = platform_get_drvdata(pdev);
++
++	clk_set_rate(clk_get(NULL, "gclk_ir"), 13000);
++	ambarella_ir_enable(pirinfo);
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, retval);
++
++	return retval;
++}
++#endif
++
++static const struct of_device_id ambarella_ir_dt_ids[] = {
++	{.compatible = "ambarella,ir", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_ir_dt_ids);
++
++static struct platform_driver ambarella_ir_driver = {
++	.probe		= ambarella_ir_probe,
++	.remove		= ambarella_ir_remove,
++#if (defined CONFIG_PM)
++	.suspend	= ambarella_ir_suspend,
++	.resume		= ambarella_ir_resume,
++#endif
++	.driver		= {
++		.name	= "ambarella-ir",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_ir_dt_ids,
++	},
++};
++
++module_platform_driver(ambarella_ir_driver);
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella IR Input Driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/input/misc/ambarella_ir_nec.c b/drivers/input/misc/ambarella_ir_nec.c
+new file mode 100644
+index 00000000..937c7b97
+--- /dev/null
++++ b/drivers/input/misc/ambarella_ir_nec.c
+@@ -0,0 +1,338 @@
++/*
++ * drivers/input/misc/ambarella_ir_nec.c
++ *
++ * History:
++ *      2007/03/28 - [Dragon Chiang] created file
++ *	2009/03/10 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++
++/**
++ * Pulse-Width-Coded Signals vary the length of pulses to code the information.
++ * In this case if the pulse width is short (approximately 550us) it
++ * corresponds to a logical zero or a low. If the pulse width is long
++ * (approximately 2200us) it corresponds to a logical one or a high.
++ *
++ *         +--+  +--+  +----+  +----+
++ *         |  |  |  |  |    |  |    |
++ *      ---+  +--+  +--+    +--+    +---
++ *          0     0      1       1
++ */
++
++/* NEC - APEX - HITACHI - PIONEER */
++#define NEC_DEFAULT_FREQUENCY		36000	/* 36KHz */
++#define NEC_DEFAULT_SMALLER_TIME	560	/* T, 560 microseconds. */
++
++/** bit 0 [1120us]
++ *      ---+    +----+
++ *         |    |    |
++ *         +----+    +---
++ *           -T   +T
++ */
++
++/** bit 1 [2240us]
++ *      ---+    +------------+
++ *         |    |            |
++ *         +----+            +---
++ *           -T      +3T
++ */
++
++/** start [13.3ms]
++ *      ---+                                +---------------+
++ *         |                                |               |
++ *         +--------------------------------+               +---
++ *                     -16T(9ms)              +7.5T(4.2ms)
++ */
++
++/** Subsequent Frame [11.3ms]
++ *      ---+                                +--------+  +---
++ *         |                                |        |  |
++ *         +--------------------------------+        +--+
++ *                     -16T(9ms)            +4T(2.2ms)
++ */
++
++#define NEC_LEADER_LOW_UPBOUND		123	/* default 9ms   */
++#define NEC_LEADER_LOW_LOWBOUND		113
++#define NEC_LEADER_HIGH_UPBOUND		63	/* default 4.2ms */
++#define NEC_LEADER_HIGH_LOWBOUND	52
++
++#define SAM_LEADER_LOW_UPBOUND		64	/* default 4.5ms */
++#define SAM_LEADER_LOW_LOWBOUND		50
++#define SAM_LEADER_HIGH_UPBOUND		64	/* default 4.5ms */
++#define SAM_LEADER_HIGH_LOWBOUND	50
++
++#define NEC_REPEAT_LOW_UPBOUND		123	/* default 9ms   */
++#define NEC_REPEAT_LOW_LOWBOUND		113
++#define NEC_REPEAT_HIGH_UPBOUND		33	/* default 2.2ms */
++#define NEC_REPEAT_HIGH_LOWBOUND	23
++
++#define NEC_DATA_LOW_UPBOUND		12	/* default 560us  */
++#define NEC_DATA_LOW_LOWBOUND		1
++#define NEC_DATA_0_HIGH_UPBOUND		12	/* default 560us  */
++#define NEC_DATA_0_HIGH_LOWBOUND	1
++#define NEC_DATA_1_HIGH_UPBOUND		26	/* default 1680us */
++#define NEC_DATA_1_HIGH_LOWBOUND	15
++
++/**
++ * Check the waveform data is leader code or not.
++ */
++static int ambarella_ir_nec_pulse_leader_code(struct ambarella_ir_info *pinfo)
++{
++	int				check_sam = 0;
++
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < NEC_LEADER_LOW_UPBOUND)  &&
++	    (val > NEC_LEADER_LOW_LOWBOUND)) {
++	} else {
++		if ((val < SAM_LEADER_LOW_UPBOUND)  &&
++		    (val > SAM_LEADER_LOW_LOWBOUND)) {
++		    check_sam = 1;
++		} else {
++			return 0;
++		}
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if (check_sam) {
++		if ((val < SAM_LEADER_HIGH_UPBOUND) &&
++		    (val > SAM_LEADER_HIGH_LOWBOUND) )
++			return 1;
++		else
++			return 0;
++	} else {
++		if ((val < NEC_LEADER_HIGH_UPBOUND) &&
++		    (val > NEC_LEADER_HIGH_LOWBOUND) )
++			return 1;
++		else
++			return 0;
++	}
++}
++
++static int ambarella_ir_nec_find_head(struct ambarella_ir_info *pinfo)
++{
++	int i, val = 0;
++
++	i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
++
++	while(i--) {
++		if(ambarella_ir_nec_pulse_leader_code(pinfo)) {
++			dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
++			val = 1;
++			break;
++		} else {
++			dev_dbg(&pinfo->input->dev, "didn't  find leader code, i [%d]\n", i);
++			ambarella_ir_move_read_ptr(pinfo, 1);
++		}
++	}
++
++	return val ;
++}
++/**
++ * Check the waveform data is subsequent code or not.
++ */
++static int ambarella_ir_nec_pulse_subsequent_code(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < NEC_REPEAT_LOW_UPBOUND)  &&
++	    (val > NEC_REPEAT_LOW_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if ((val < NEC_REPEAT_HIGH_UPBOUND) &&
++	    (val > NEC_REPEAT_HIGH_LOWBOUND) )
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_nec_find_subsequent(struct ambarella_ir_info *pinfo)
++{
++	int i, val = 0;
++
++	i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
++
++	while(i--) {
++		if(ambarella_ir_nec_pulse_subsequent_code(pinfo)) {
++			dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
++			val = 1;
++			break;
++		} else {
++			dev_dbg(&pinfo->input->dev, "didn't  find leader code, i [%d]\n", i);
++			ambarella_ir_move_read_ptr(pinfo, 1);
++		}
++	}
++
++	return val ;
++}
++
++/**
++ * Check the waveform data is 0 bit or not.
++ */
++static int ambarella_ir_nec_pulse_code_0(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++	if ((val < NEC_DATA_LOW_UPBOUND)  &&
++	    (val > NEC_DATA_LOW_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if ((val < NEC_DATA_0_HIGH_UPBOUND) &&
++	    (val > NEC_DATA_0_HIGH_LOWBOUND) )
++		return 1;
++	else
++		return 0;
++}
++
++/**
++ * Check the waveform data is 1 bit or not.
++ */
++static int ambarella_ir_nec_pulse_code_1(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < NEC_DATA_LOW_UPBOUND)  &&
++	    (val > NEC_DATA_LOW_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if ((val < NEC_DATA_1_HIGH_UPBOUND) &&
++	    (val > NEC_DATA_1_HIGH_LOWBOUND) )
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_nec_pulse_data_translate(struct ambarella_ir_info *pinfo, u8 * data)
++{
++	int i;
++	*data = 0;
++
++	for (i = 7; i >= 0; i--) {
++		if (ambarella_ir_nec_pulse_code_0(pinfo)) {
++
++		} else if (ambarella_ir_nec_pulse_code_1(pinfo)) {
++			*data |= 1 << i;
++		} else {
++			dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match\n", i);
++			return -1;
++		}
++		ambarella_ir_move_read_ptr(pinfo, 2);
++	}
++
++	return 0;
++}
++
++static int ambarella_ir_nec_pulse_decode(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	u8 addr = 0, inv_addr = 0, data = 0, inv_data = 0;
++	int rval;
++
++	/* Then follows 32 bits of data, broken down in 4 bytes of 8 bits. */
++
++	/* The first 8 bits is the Address. */
++	rval = ambarella_ir_nec_pulse_data_translate(pinfo, &addr);
++	if (rval < 0)
++		return rval;
++
++	/* The second 8 bits is the Address Complement. */
++	rval = ambarella_ir_nec_pulse_data_translate(pinfo, &inv_addr);
++	if (rval < 0)
++		return rval;
++
++	/* The third 8 bits is the data. */
++	rval = ambarella_ir_nec_pulse_data_translate(pinfo, &data);
++	if (rval < 0)
++		return rval;
++
++	/* The fourth 8 bits is the data Complement. */
++	rval = ambarella_ir_nec_pulse_data_translate(pinfo, &inv_data);
++	if (rval < 0)
++		return rval;
++
++	dev_dbg(&pinfo->input->dev, "addr\tinv_addr\tdata\tinv_data\n");
++	dev_dbg(&pinfo->input->dev, "0x%x\t0x%x\t\t0x%x\t0x%x\n", addr, inv_addr, data, inv_data);
++
++	*uid = (addr << 24) | (inv_addr << 16) | (data << 8) | inv_data;
++
++	return 0;
++}
++
++int ambarella_ir_nec_parse(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	int				rval;
++	int				cur_ptr = pinfo->ir_pread;
++
++	if ((ambarella_ir_nec_find_head(pinfo) || (ambarella_ir_nec_find_subsequent(pinfo)))
++		&& ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
++		+ pinfo->frame_info.frame_head_size) {
++
++		dev_dbg(&pinfo->input->dev, "go to decode statge\n");
++		ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
++		rval = ambarella_ir_nec_pulse_decode(pinfo, uid);
++	} else {
++		return -1;
++	}
++
++	if (rval >= 0) {
++		dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
++		return 0;
++	}
++
++	return (-1);
++}
++
++void ambarella_ir_get_nec_info(struct ambarella_ir_frame_info *pframe_info)
++{
++	pframe_info->frame_head_size = 2;
++	pframe_info->frame_data_size = 64;
++	pframe_info->frame_end_size = 1;
++	pframe_info->frame_repeat_head_size = 4;
++}
++
+diff --git a/drivers/input/misc/ambarella_ir_panasonic.c b/drivers/input/misc/ambarella_ir_panasonic.c
+new file mode 100644
+index 00000000..0a8aa0fa
+--- /dev/null
++++ b/drivers/input/misc/ambarella_ir_panasonic.c
+@@ -0,0 +1,267 @@
++/*
++ * drivers/input/misc/ambarella_ir_panasonic.c
++ *
++ * History:
++ *      2007/03/28 - [Dragon Chiang] created file
++ *	2009/03/10 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++
++/**
++ * Pulse-Width-Coded Signals vary the length of pulses to code the information.
++ * In this case if the pulse width is short (approximately 550us) it
++ * corresponds to a logical zero or a low. If the pulse width is long
++ * (approximately 2200us) it corresponds to a logical one or a high.
++ *
++ *         +--+  +--+  +----+  +----+
++ *         |  |  |  |  |    |  |    |
++ *      ---+  +--+  +--+    +--+    +---
++ *          0     0      1       1
++ */
++
++#define PANASONIC_DEFAULT_FREQUENCY	38000	/* 38KHz */
++
++/* T = 420 �gs to approx 424 �gs in the USA and Canada */
++/* T = 454 �gs to approx 460 �gs in Europe and others  */
++#define PANASONIC_DEFAULT_SMALLER_TIME	454	/* T, 450 microseconds. */
++
++/** bit 0
++ *         +----+    +---
++ *         |    |    |
++ *      ---+    +----+
++ *           2T   2T
++ */
++
++/** bit 1
++ *         +----+            +---
++ *         |    |            |
++ *      ---+    +------------+
++ *           2T       6T
++ */
++
++/** start
++ *         +--------------------------------+                +---
++ *         |                                |                |
++ *      ---+                                +----------------+
++ *                         16T                      8T
++ */
++
++#define PANASONIC_LEADER_HIGH_UPBOUND	50
++#define PANASONIC_LEADER_HIGH_LOWBOUND	42
++#define PANASONIC_LEADER_LOW_UPBOUND	26
++#define PANASONIC_LEADER_LOW_LOWBOUND	18
++
++#define PANASONIC_DATA_HIGH_UPBOUND	9
++#define PANASONIC_DATA_HIGH_LOWBOUND	1
++#define PANASONIC_DATA_0_LOW_UPBOUND	9
++#define PANASONIC_DATA_0_LOW_LOWBOUND	1
++#define PANASONIC_DATA_1_LOW_UPBOUND	20
++#define PANASONIC_DATA_1_LOW_LOWBOUND	12
++
++static int ambarella_ir_panasonic_pulse_leader_code(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < PANASONIC_LEADER_HIGH_UPBOUND)  &&
++	    (val > PANASONIC_LEADER_HIGH_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if ((val < PANASONIC_LEADER_LOW_UPBOUND) &&
++	    (val > PANASONIC_LEADER_LOW_LOWBOUND) )
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_panasonic_find_head(struct ambarella_ir_info *pinfo)
++{
++	int i, val = 0;
++
++	i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
++
++	while(i--) {
++		if(ambarella_ir_panasonic_pulse_leader_code(pinfo)) {
++			dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
++			val = 1;
++			break;
++		} else {
++			dev_dbg(&pinfo->input->dev, "didn't  find leader code, i [%d]\n", i);
++			ambarella_ir_move_read_ptr(pinfo, 1);
++		}
++	}
++
++	return val ;
++}
++
++static int ambarella_ir_panasonic_pulse_code_0(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++	if ((val < PANASONIC_DATA_HIGH_UPBOUND)  &&
++	    (val > PANASONIC_DATA_HIGH_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if ((val < PANASONIC_DATA_0_LOW_UPBOUND) &&
++	    (val > PANASONIC_DATA_0_LOW_LOWBOUND) )
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_panasonic_pulse_code_1(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < PANASONIC_DATA_HIGH_UPBOUND)  &&
++	    (val > PANASONIC_DATA_HIGH_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++	}
++
++	if ((val < PANASONIC_DATA_1_LOW_UPBOUND) &&
++	    (val > PANASONIC_DATA_1_LOW_LOWBOUND) )
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_panasonic_pulse_data_translate(struct ambarella_ir_info *pinfo, u8 * data)
++{
++	int i;
++
++	*data = 0;
++
++	for (i = 7; i >= 0; i--) {
++		if (ambarella_ir_panasonic_pulse_code_0(pinfo)) {
++
++		} else if (ambarella_ir_panasonic_pulse_code_1(pinfo)) {
++			*data |= 1 << i;
++		} else {
++			dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match",
++				  pinfo->ir_pread);
++			return -1;
++		}
++		ambarella_ir_move_read_ptr(pinfo, 2);
++	}
++
++	return 0;
++}
++
++static int ambarella_ir_panasonic_pulse_decode(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	u8 addr0 = 0, addr1 = 0, data0 = 0, data1 = 0, data2 = 0, data3 = 0;
++	int rval;
++
++	/* Then follows 22 bits of data, broken down in 4 bytes of 8 bits. */
++
++	/* The first 8 bits is the Address 0. */
++	rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &addr0);
++	if (rval < 0)
++		return rval;
++
++	/* The second 8 bits is the Address 1. */
++	rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &addr1);
++	if (rval < 0)
++		return rval;
++
++	/* The third 8 bits is the data 0. */
++	rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data0);
++	if (rval < 0)
++		return rval;
++
++	/* The third 8 bits is the data 1. */
++	rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data1);
++	if (rval < 0)
++		return rval;
++
++	/* The third 8 bits is the data 2. */
++	rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data2);
++	if (rval < 0)
++		return rval;
++
++	/* The third 8 bits is the data 3. */
++	rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data3);
++	if (rval < 0)
++		return rval;
++
++	dev_dbg(&pinfo->input->dev, "\taddr0\taddr1\tdata0\tdata1\tdata2\tdata3");
++	dev_dbg(&pinfo->input->dev, "\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\n",
++			addr0, addr1, data0, data1, data2, data3);
++
++	*uid = (data0 << 24) | (data1 << 16) | (data2 << 8) | data3;
++
++	return 0;
++}
++
++int ambarella_ir_panasonic_parse(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	int				rval;
++	int				cur_ptr = pinfo->ir_pread;
++
++	if (ambarella_ir_panasonic_find_head(pinfo)
++		&& ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
++		+ pinfo->frame_info.frame_head_size) {
++
++		dev_dbg(&pinfo->input->dev, "go to decode statge\n");
++		ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
++		rval = ambarella_ir_panasonic_pulse_decode(pinfo, uid);
++	} else {
++		return -1;
++	}
++
++	if (rval >= 0) {
++		dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
++		return 0;
++	}
++
++	return (-1);
++}
++
++void ambarella_ir_get_panasonic_info(struct ambarella_ir_frame_info *pframe_info)
++{
++	pframe_info->frame_head_size 	= 2;
++	pframe_info->frame_data_size 	= 96;
++	pframe_info->frame_end_size	= 1;
++	pframe_info->frame_repeat_head_size	= 0;
++}
++
+diff --git a/drivers/input/misc/ambarella_ir_philips.c b/drivers/input/misc/ambarella_ir_philips.c
+new file mode 100644
+index 00000000..7d8ccbc9
+--- /dev/null
++++ b/drivers/input/misc/ambarella_ir_philips.c
+@@ -0,0 +1,238 @@
++/*
++ * drivers/input/misc/ambarella_ir_philips.c
++ *
++ * History:
++ *      2007/03/28 - [Dragon Chiang] created file
++ *	2009/03/10 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++
++/**
++ * Shift-Coded Signals (RC-5)vary the order of pulse space to code the
++ * information. In this case if the space width is short (approximately 550us)
++ * and the pulse width is long (approximately 1100us) the signal corresponds to
++ * a logical one or a high. If the space is long and the pulse is short the
++ * signal corresponds to a logical zero or a low.
++ *
++ *           |     |     |
++ *        +--|  +--|--+  |  +---
++ *        |  |  |  |  |  |  |
++ *     ---+  |--+  |  +--|--+
++ *        1  |  1  |  0  |  1
++ */
++
++/* Philips (RC-5) */
++#define PHILIPS_DEFAULT_FREQUENCY	36000	/* 36KHz */
++#define PHILIPS_DEFAULT_SMALLER_TIME	1728	/* T, 1728 microseconds. */
++
++/**       |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
++ *     ---+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +---
++ *        | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
++ *        | +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
++ *        |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
++ *        |  AGC  |TOG|<     address     >|<       command       >|
++ *
++ *                 |        |
++ */
++#define PHILIPS_LEADER_UPBOUND		0xffff	/* default don't care */
++#define PHILIPS_LEADER_LOWBOUND		30
++
++#define PHILIPS_SHC_SIG_CYC_UPBOUND	14	/* default 10~ 12 */
++#define PHILIPS_SHC_SIG_CYC_LOWBOUND	8
++
++#define PHILIPS_SHC_DOB_CYC_UPBOUND	25	/* default 12~ 23 */
++#define PHILIPS_SHC_DOB_CYC_LOWBOUND	20
++
++static int ambarella_ir_philips_shift_leader_code(struct ambarella_ir_info *pinfo)
++{
++/**       |                 |                 |
++ *     ---|--------+        +--------+        |
++ *        |        |        |        |        |
++ *        |        +--------+        +--------|---
++ *        |                 |                 |
++ *        |                AGC                |
++ *
++ *      Leader     | Leader | Leader |
++ */
++	u16 val_1, val_0 = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++#if 0
++	if ((val_0 <= PHILIPS_LEADER_UPBOUND) &&
++	    (val_0 > PHILIPS_LEADER_LOWBOUND)) {
++#else
++	if (val_0 > PHILIPS_LEADER_LOWBOUND) {
++#endif
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val_0 = ambarella_ir_read_data(pinfo, 0);
++		val_1 = ambarella_ir_read_data(pinfo, 1);
++	} else if ((pinfo->ir_pread + 2) == MAX_IR_BUFFER) {
++		val_0 = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++		val_1 = ambarella_ir_read_data(pinfo, 0);
++	} else {
++		val_0 = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++		val_1 = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 2);
++	}
++
++	if ((val_0 < PHILIPS_SHC_SIG_CYC_UPBOUND)  &&
++	    (val_0 > PHILIPS_SHC_SIG_CYC_LOWBOUND) &&
++	    (val_1 < PHILIPS_SHC_SIG_CYC_UPBOUND)  &&
++	    (val_1 > PHILIPS_SHC_SIG_CYC_LOWBOUND))
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_philips_find_head(struct ambarella_ir_info *pinfo)
++{
++	int i, val = 0;
++
++	i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
++
++	while(i--) {
++		if(ambarella_ir_philips_shift_leader_code(pinfo)) {
++			dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
++			val = 1;
++			break;
++		} else {
++			dev_dbg(&pinfo->input->dev, "didn't  find leader code, i [%d]\n", i);
++			ambarella_ir_move_read_ptr(pinfo, 1);
++		}
++	}
++
++	return val ;
++}
++
++static int ambarella_ir_philips_shift_invert_code(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < PHILIPS_SHC_DOB_CYC_UPBOUND) &&
++	    (val > PHILIPS_SHC_DOB_CYC_LOWBOUND))
++		return 1;
++	else
++		return 0;
++}
++
++static int ambarella_ir_philips_shift_repeat_code(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < PHILIPS_SHC_SIG_CYC_UPBOUND) &&
++	    (val > PHILIPS_SHC_SIG_CYC_LOWBOUND)) {
++		ambarella_ir_inc_read_ptr(pinfo);
++
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++		if ((val < PHILIPS_SHC_SIG_CYC_UPBOUND) &&
++		    (val > PHILIPS_SHC_SIG_CYC_LOWBOUND))
++			return 1;
++		else
++			return 0;
++	} else
++		return 0;
++}
++
++static int ambarella_ir_philips_shift_decode(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	int i, val = 0;
++	u8 addr = 0, data = 0;
++
++	ambarella_ir_move_read_ptr(pinfo, 3);
++
++	/* Get toggle code and Initialize start value */
++	if (ambarella_ir_philips_shift_invert_code(pinfo))
++		val = 1;
++	else if (ambarella_ir_philips_shift_repeat_code(pinfo))
++		val = 0;
++	else {
++		dev_dbg(&pinfo->input->dev, "Err->toggle code doesn't match");
++		return (-1);
++	}
++
++	dev_dbg(&pinfo->input->dev, "toggle code:%d", val);
++
++	/* address */
++	for (i = 0; i < 5; i++) {
++		if (ambarella_ir_philips_shift_invert_code(pinfo)) {
++			val = 1 - val;
++		} else if (ambarella_ir_philips_shift_repeat_code(pinfo)) {
++		}else {
++			dev_dbg(&pinfo->input->dev, "Err->addr code(%d) doesn't match", i);
++			return (-1);
++		}
++		addr = (addr << 1) | val;
++		ambarella_ir_inc_read_ptr(pinfo);
++	}
++
++	/* data */
++	for (i = 0; i < 6; i++) {
++		if (ambarella_ir_philips_shift_invert_code(pinfo)) {
++			val = 1 - val;
++		} else if (ambarella_ir_philips_shift_repeat_code(pinfo)) {
++		}else {
++			dev_dbg(&pinfo->input->dev, "Err->data code(%d) doesn't match", i);
++			return (-1);
++		}
++		data = (data << 1) | val;
++		ambarella_ir_inc_read_ptr(pinfo);
++	}
++
++	*uid = (addr << 16) | data;
++
++	return 0;
++}
++
++int ambarella_ir_philips_parse(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	int				rval;
++	int				cur_ptr = pinfo->ir_pread;
++
++	if (ambarella_ir_philips_find_head(pinfo)
++		&& ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
++		+ pinfo->frame_info.frame_head_size) {
++
++		dev_dbg(&pinfo->input->dev, "go to decode statge\n");
++		ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
++		rval = ambarella_ir_philips_shift_decode(pinfo, uid);
++	} else {
++		return -1;
++	}
++
++	if (rval >= 0) {
++		dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
++		return 0;
++	}
++
++	return (-1);
++}
++
++void ambarella_ir_get_philips_info(struct ambarella_ir_frame_info *pframe_info)
++{
++	pframe_info->frame_head_size 	= 6;
++	pframe_info->frame_data_size 	= 22;
++	pframe_info->frame_end_size	= 1;
++	pframe_info->frame_repeat_head_size	= 0;
++}
++
+diff --git a/drivers/input/misc/ambarella_ir_sony.c b/drivers/input/misc/ambarella_ir_sony.c
+new file mode 100644
+index 00000000..d7b68c48
+--- /dev/null
++++ b/drivers/input/misc/ambarella_ir_sony.c
+@@ -0,0 +1,256 @@
++/*
++ * drivers/input/misc/ambarella_ir_sony.c
++ *
++ * History:
++ *      2007/03/28 - [Dragon Chiang] created file
++ *	2009/03/10 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++
++/**
++ * Space-Coded Signals (REC-80) vary the length of the spaces between pulses
++ * to code the information. In this case if the space width is short
++ * (approximately 550us) it corresponds to a logical zero or a low. If the
++ * space width is long (approximately 1650us) it corresponds to a logical one
++ * or a high.
++ *
++ *      ---+  +--+  +--+    +--+    +---
++ *         |  |  |  |  |    |  |    |
++ *         +--+  +--+  +----+  +----+
++ *          0     0      1       1
++ */
++
++/* Sony 12-bit, 15-bit and 20-bit versions of the protocol exist (12-bit processed here) */
++#define SONY_DEFAULT_FREQUENCY		36000	/* 36KHz */
++#define SONY_DEFAULT_SMALLER_TIME	600	/* T, 600 microseconds. */
++
++/** bit 0 [1200us]
++ *      ---+    +----+
++ *         |    |    |
++ *         +----+    +---
++ *           -T   +T
++ */
++
++/** bit 1 [1800us]
++ *      ---+    +--------+
++ *         |    |        |
++ *         +----+        +---
++ *           -T    +2T
++ */
++
++/** start [1800us]
++ *         +------------------------------+
++ *         |                              |
++ *   ------+                              +-----------
++ *                   -3T(1800us)
++ */
++
++/**
++ * If you hold the remote button pressed, the whole transmited frame
++ * repeats every 25ms.
++ */
++
++#define SONY_LEADER_LOW_UPBOUND		33	/* default 1800us */
++#define SONY_LEADER_LOW_LOWBOUND	28
++
++#define SONY_DATA_LOW_UPBOUND		9	/* default 560us  */
++#define SONY_DATA_LOW_LOWBOUND		4
++#define SONY_DATA_0_HIGH_UPBOUND	9	/* default 560us  */
++#define SONY_DATA_0_HIGH_LOWBOUND	4
++#define SONY_DATA_1_HIGH_UPBOUND	18	/* default 1680us */
++#define SONY_DATA_1_HIGH_LOWBOUND	12
++
++/**
++ * Check the waveform data is leader code or not.
++ */
++static int ambarella_ir_sony_space_leader_code(struct ambarella_ir_info *pinfo)
++{
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < SONY_LEADER_LOW_UPBOUND) &&
++	    (val > SONY_LEADER_LOW_LOWBOUND) )
++		return 1;	/* leader code */
++	else
++		return 0;
++}
++
++static int ambarella_ir_sony_find_head(struct ambarella_ir_info *pinfo)
++{
++	int i, val = 0;
++
++	i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
++
++	while(i--) {
++		if(ambarella_ir_sony_space_leader_code(pinfo)) {
++			dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
++			val = 1;
++			break;
++		} else {
++			dev_dbg(&pinfo->input->dev, "didn't  find leader code, i [%d]\n", i);
++			ambarella_ir_move_read_ptr(pinfo, 1);
++		}
++	}
++
++	return val ;
++}
++
++/**
++ * Check the waveform data is 0 bit or not.
++ */
++static int ambarella_ir_sony_space_code_0(struct ambarella_ir_info *pinfo)
++{
++	/* 500us of Silence + 700us of IR for bits ZERO, */
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < SONY_DATA_LOW_UPBOUND) &&
++	    (val > SONY_DATA_LOW_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++		if ((val < SONY_DATA_0_HIGH_UPBOUND) &&
++		    (val > SONY_DATA_0_HIGH_LOWBOUND) )
++			return 1;	/* code 0 */
++		else
++			return 0;
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++		if ((val < SONY_DATA_0_HIGH_UPBOUND) &&
++		    (val > SONY_DATA_0_HIGH_LOWBOUND) )
++			return 1;	/* code 0 */
++		else
++			return 0;
++	}
++}
++
++/**
++ * Check the waveform data is 1 bit or not.
++ */
++static int ambarella_ir_sony_space_code_1(struct ambarella_ir_info *pinfo)
++{
++	/* 500us of Silence + 1300us of IR for bits ONE. */
++	u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
++
++	if ((val < SONY_DATA_LOW_UPBOUND) &&
++	    (val > SONY_DATA_LOW_LOWBOUND)) {
++	} else {
++		return 0;
++	}
++
++	if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
++		val = ambarella_ir_read_data(pinfo, 0);
++		if ((val < SONY_DATA_1_HIGH_UPBOUND) &&
++		    (val > SONY_DATA_1_HIGH_LOWBOUND) )
++			return 1;	/* code 1 */
++		else
++			return 0;
++	} else {
++		val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
++		if ((val < SONY_DATA_1_HIGH_UPBOUND) &&
++		    (val > SONY_DATA_1_HIGH_LOWBOUND) )
++			return 1;	/* code 1 */
++		else
++			return 0;
++	}
++}
++
++/**
++ * Translate waveform data to useful message.
++ */
++static int ambarella_ir_sony_space_decode(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	/* Following the header you will find straight 12 bits.
++	   The first immediate bit after the START is the LSB of the 12 bits.
++	   Lets name this first bit as B0, the Last will be B12.
++	   B0 to B6 form the 7 bits for the Command Code.
++	   B8 to B11 form the 5 bits for the Device Address.
++	*/
++
++	int i;
++
++	u8 addr = 0, data = 0;
++
++	/* command - 7 bits*/
++	for (i = 0; i < 7; i++) {
++		if (ambarella_ir_sony_space_code_0(pinfo)) {
++		}
++		else if (ambarella_ir_sony_space_code_1(pinfo)) {
++			data |= 1 << i;
++		}
++		else {
++			dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match", i);
++		}
++		ambarella_ir_move_read_ptr(pinfo, 2);
++	}
++
++	/* device address - 5 bits */
++	for (i = 0; i < 5; i++) {
++		if (ambarella_ir_sony_space_code_0(pinfo)) {
++		}
++		else if (ambarella_ir_sony_space_code_1(pinfo)) {
++			addr |= 1 << i;
++		}
++		else {
++			dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match", i);
++		}
++		ambarella_ir_move_read_ptr(pinfo, 2);
++	}
++
++	*uid = (addr << 16) | data;
++
++	return 0;
++}
++
++int ambarella_ir_sony_parse(struct ambarella_ir_info *pinfo, u32 *uid)
++{
++	int				rval;
++	int				cur_ptr = pinfo->ir_pread;
++
++	if (ambarella_ir_sony_find_head(pinfo)
++		&& ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
++		+ pinfo->frame_info.frame_head_size) {
++
++		dev_dbg(&pinfo->input->dev, "go to decode statge\n");
++		ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
++		rval = ambarella_ir_sony_space_decode(pinfo, uid);
++	} else {
++		return -1;
++	}
++
++	if (rval >= 0) {
++		dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
++		return 0;
++	}
++
++	return (-1);
++}
++
++void ambarella_ir_get_sony_info(struct ambarella_ir_frame_info *pframe_info)
++{
++	pframe_info->frame_head_size 	= 1;
++	pframe_info->frame_data_size 	= 24;
++	pframe_info->frame_end_size	= 1;
++	pframe_info->frame_repeat_head_size	= 0;
++}
++
+diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c
+index caa2c406..702c88d6 100644
+--- a/drivers/input/misc/wm831x-on.c
++++ b/drivers/input/misc/wm831x-on.c
+@@ -40,16 +40,19 @@ struct wm831x_on {
+  */
+ static void wm831x_poll_on(struct work_struct *work)
+ {
+-	struct wm831x_on *wm831x_on = container_of(work, struct wm831x_on,
+-						   work.work);
+-	struct wm831x *wm831x = wm831x_on->wm831x;
+-	int poll, ret;
++	int					ret;
++	struct wm831x_on			*wm831x_on;
++	struct wm831x				*wm831x;
++	int					key;
++	int					poll = 0;
++
++	wm831x_on = container_of(work, struct wm831x_on, work.work);
++	wm831x = wm831x_on->wm831x;
+ 
+ 	ret = wm831x_reg_read(wm831x, WM831X_ON_PIN_CONTROL);
+ 	if (ret >= 0) {
+-		poll = !(ret & WM831X_ON_PIN_STS);
+-
+-		input_report_key(wm831x_on->dev, KEY_POWER, poll);
++		key = !(ret & WM831X_ON_PIN_STS);
++		input_report_key(wm831x_on->dev, KEY_POWER, key);
+ 		input_sync(wm831x_on->dev);
+ 	} else {
+ 		dev_err(wm831x->dev, "Failed to read ON status: %d\n", ret);
+@@ -57,7 +60,7 @@ static void wm831x_poll_on(struct work_struct *work)
+ 	}
+ 
+ 	if (poll)
+-		schedule_delayed_work(&wm831x_on->work, 100);
++		schedule_delayed_work(&wm831x_on->work, HZ / 10);
+ }
+ 
+ static irqreturn_t wm831x_on_irq(int irq, void *data)
+@@ -100,8 +103,8 @@ static int wm831x_on_probe(struct platform_device *pdev)
+ 	wm831x_on->dev->dev.parent = &pdev->dev;
+ 
+ 	ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
+-				   IRQF_TRIGGER_RISING, "wm831x_on",
+-				   wm831x_on);
++		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++		"wm831x_on", wm831x_on);
+ 	if (ret < 0) {
+ 		dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
+ 		goto err_input_dev;
+@@ -125,8 +128,11 @@ err:
+ 
+ static int wm831x_on_remove(struct platform_device *pdev)
+ {
+-	struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
+-	int irq = platform_get_irq(pdev, 0);
++	struct wm831x_on			*wm831x_on;
++	int					irq;
++
++	wm831x_on = platform_get_drvdata(pdev);
++	irq = platform_get_irq(pdev, 0);
+ 
+ 	free_irq(irq, wm831x_on);
+ 	cancel_delayed_work_sync(&wm831x_on->work);
+@@ -134,9 +140,53 @@ static int wm831x_on_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm831x_on_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct wm831x_on			*wm831x_on;
++	int					irq;
++
++	wm831x_on = platform_get_drvdata(pdev);
++	irq = platform_get_irq(pdev, 0);
++
++	disable_irq(irq);
++	cancel_delayed_work_sync(&wm831x_on->work);
++
++	return 0;
++}
++
++static int wm831x_on_resume(struct platform_device *pdev)
++{
++	struct wm831x_on			*wm831x_on;
++	struct wm831x				*wm831x;
++	int					irq;
++	int					ret;
++
++	wm831x_on = platform_get_drvdata(pdev);
++	irq = platform_get_irq(pdev, 0);
++
++	wm831x = wm831x_on->wm831x;
++
++	//TBD: Check resumed form self-referesh.
++	ret = wm831x_reg_read(wm831x, WM831X_ON_SOURCE);
++	if (ret & WM831X_ON_SOURCE_ON_PIN) {
++		input_report_key(wm831x_on->dev, KEY_POWER, 1);
++		input_report_key(wm831x_on->dev, KEY_POWER, 0);
++		input_sync(wm831x_on->dev);
++	}
++	enable_irq(irq);
++
++	return 0;
++}
++#endif /* CONFIG_PM */
++
+ static struct platform_driver wm831x_on_driver = {
+ 	.probe		= wm831x_on_probe,
+ 	.remove		= wm831x_on_remove,
++#ifdef CONFIG_PM
++	.suspend	= wm831x_on_suspend,
++	.resume		= wm831x_on_resume,
++#endif
+ 	.driver		= {
+ 		.name	= "wm831x-on",
+ 		.owner	= THIS_MODULE,
+diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
+index 4a33351c..0e148121 100644
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -25,6 +25,12 @@ config ARM_VIC_NR
+ 	  The maximum number of VICs available in the system, for
+ 	  power management.
+ 
++config AMBARELLA_VIC
++	bool
++	depends on PLAT_AMBARELLA
++	select IRQ_DOMAIN
++	select MULTI_IRQ_HANDLER
++
+ config RENESAS_INTC_IRQPIN
+ 	bool
+ 	select IRQ_DOMAIN
+diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
+index cda4cb5f..c3018a92 100644
+--- a/drivers/irqchip/Makefile
++++ b/drivers/irqchip/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
+ obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
+ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o
+ obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
++obj-$(CONFIG_AMBARELLA_VIC)		+= irq-ambarella.o
+ obj-$(CONFIG_SIRF_IRQ)			+= irq-sirfsoc.o
+ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
+ obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
+diff --git a/drivers/irqchip/irq-ambarella.c b/drivers/irqchip/irq-ambarella.c
+new file mode 100644
+index 00000000..b2bbec0d
+--- /dev/null
++++ b/drivers/irqchip/irq-ambarella.c
+@@ -0,0 +1,657 @@
++/*
++ * drivers/irqchip/irq-ambarella.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2013, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/irqdomain.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/of_address.h>
++#include <linux/interrupt.h>
++#include <linux/syscore_ops.h>
++#include <asm/exception.h>
++#include "irqchip.h"
++
++#include <plat/rct.h>
++
++#define HWIRQ_TO_BANK(hwirq)	((hwirq) >> 5)
++#define HWIRQ_TO_OFFSET(hwirq)	((hwirq) & 0x1f)
++
++struct ambvic_chip_data {
++	void __iomem *reg_base[VIC_INSTANCES];
++	void __iomem *ipi_reg_base;
++	struct irq_domain *domain;
++};
++
++#ifdef CONFIG_SMP
++
++static DEFINE_RAW_SPINLOCK(irq_controller_lock);
++
++#define IPI0_IRQ_MASK		((1 << (IPI01_IRQ % 32)) | \
++				 (1 << (IPI02_IRQ % 32)) | \
++				 (1 << (IPI03_IRQ % 32)) | \
++				 (1 << (IPI04_IRQ % 32)) | \
++				 (1 << (IPI05_IRQ % 32)) | \
++				 (1 << (IPI06_IRQ % 32)))
++#define IPI1_IRQ_MASK		((1 << (IPI11_IRQ % 32)) | \
++				 (1 << (IPI12_IRQ % 32)) | \
++				 (1 << (IPI13_IRQ % 32)) | \
++				 (1 << (IPI14_IRQ % 32)) | \
++				 (1 << (IPI15_IRQ % 32)) | \
++				 (1 << (IPI16_IRQ % 32)))
++#define IPI_IRQ_MASK		(IPI0_IRQ_MASK | IPI1_IRQ_MASK)
++
++#define AMBVIC_IRQ_IS_IPI0(irq)	(((irq) >= IPI01_IRQ && (irq) <= IPI06_IRQ))
++#define AMBVIC_IRQ_IS_IPI1(irq)	(((irq) >= IPI11_IRQ && (irq) <= IPI16_IRQ))
++#define AMBVIC_IRQ_IS_IPI(irq)	(AMBVIC_IRQ_IS_IPI0(irq) || AMBVIC_IRQ_IS_IPI1(irq))
++
++#endif
++
++static struct ambvic_chip_data ambvic_data __read_mostly;
++
++/* ==========================================================================*/
++#if (VIC_SUPPORT_CPU_OFFLOAD >= 1)
++
++static void ambvic_ack_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
++	amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
++#else
++	amba_writel(reg_base + VIC_INT_EDGE_CLR_OFFSET, offset);
++#endif
++}
++
++static void ambvic_mask_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_INT_EN_CLR_INT_OFFSET, offset);
++}
++
++static void ambvic_unmask_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_INT_EN_INT_OFFSET, offset);
++}
++
++static void ambvic_mask_ack_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_INT_EN_CLR_INT_OFFSET, offset);
++#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
++	amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
++#else
++	amba_writel(reg_base + VIC_INT_EDGE_CLR_OFFSET, offset);
++#endif
++}
++
++static int ambvic_set_type_irq(struct irq_data *data, unsigned int type)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	struct irq_desc *desc = irq_to_desc(data->irq);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	switch (type) {
++	case IRQ_TYPE_EDGE_RISING:
++		amba_writel(reg_base + VIC_INT_SENSE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_EVT_INT_OFFSET, offset);
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_EDGE_FALLING:
++		amba_writel(reg_base + VIC_INT_SENSE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_EVT_CLR_INT_OFFSET, offset);
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_EDGE_BOTH:
++		amba_writel(reg_base + VIC_INT_SENSE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_BOTHEDGE_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_EVT_CLR_INT_OFFSET, offset);
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_LEVEL_HIGH:
++		amba_writel(reg_base + VIC_INT_SENSE_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_EVT_INT_OFFSET, offset);
++		desc->handle_irq = handle_level_irq;
++		break;
++	case IRQ_TYPE_LEVEL_LOW:
++		amba_writel(reg_base + VIC_INT_SENSE_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
++		amba_writel(reg_base + VIC_INT_EVT_CLR_INT_OFFSET, offset);
++		desc->handle_irq = handle_level_irq;
++		break;
++	default:
++		pr_err("%s: irq[%d] type[%d] fail!\n",
++			__func__, data->irq, type);
++		return -EINVAL;
++	}
++
++	/* clear obsolete irq */
++#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
++	amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
++#else
++	amba_writel(reg_base + VIC_INT_EDGE_CLR_OFFSET, offset);
++#endif
++
++	return 0;
++}
++
++#else
++static void ambvic_ack_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
++}
++
++static void ambvic_mask_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0x1 << offset);
++}
++
++static void ambvic_unmask_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_INTEN_OFFSET, 0x1 << offset);
++}
++
++static void ambvic_mask_ack_irq(struct irq_data *data)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++
++	amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0x1 << offset);
++	amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
++}
++
++static int ambvic_set_type_irq(struct irq_data *data, unsigned int type)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	struct irq_desc *desc = irq_to_desc(data->irq);
++	u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
++	u32 mask, bit, sense, bothedges, event;
++
++	mask = ~(0x1 << offset);
++	bit = (0x1 << offset);
++	sense = amba_readl(reg_base + VIC_SENSE_OFFSET);
++	bothedges = amba_readl(reg_base + VIC_BOTHEDGE_OFFSET);
++	event = amba_readl(reg_base + VIC_EVENT_OFFSET);
++	switch (type) {
++	case IRQ_TYPE_EDGE_RISING:
++		sense &= mask;
++		bothedges &= mask;
++		event |= bit;
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_EDGE_FALLING:
++		sense &= mask;
++		bothedges &= mask;
++		event &= mask;
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_EDGE_BOTH:
++		sense &= mask;
++		bothedges |= bit;
++		event &= mask;
++		desc->handle_irq = handle_edge_irq;
++		break;
++	case IRQ_TYPE_LEVEL_HIGH:
++		sense |= bit;
++		bothedges &= mask;
++		event |= bit;
++		desc->handle_irq = handle_level_irq;
++		break;
++	case IRQ_TYPE_LEVEL_LOW:
++		sense |= bit;
++		bothedges &= mask;
++		event &= mask;
++		desc->handle_irq = handle_level_irq;
++		break;
++	default:
++		pr_err("%s: irq[%d] type[%d] fail!\n",
++			__func__, data->irq, type);
++		return -EINVAL;
++	}
++
++	amba_writel(reg_base + VIC_SENSE_OFFSET, sense);
++	amba_writel(reg_base + VIC_BOTHEDGE_OFFSET, bothedges);
++	amba_writel(reg_base + VIC_EVENT_OFFSET, event);
++	/* clear obsolete irq */
++	amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
++
++	return 0;
++}
++
++#endif
++
++#ifdef CONFIG_SMP
++static int ambvic_set_affinity(struct irq_data *data,
++		const struct cpumask *mask_val, bool force)
++{
++	void __iomem *reg_base = irq_data_get_irq_chip_data(data);
++	u32 cpu = cpumask_any_and(mask_val, cpu_online_mask);
++	u32 mask = 1 << HWIRQ_TO_OFFSET(data->hwirq);
++	u32 val0, val1;
++
++	if (cpu >= nr_cpu_ids)
++		return -EINVAL;
++
++	raw_spin_lock(&irq_controller_lock);
++
++	val0 = amba_readl(reg_base + VIC_INT_PTR0_OFFSET);
++	val1 = amba_readl(reg_base + VIC_INT_PTR1_OFFSET);
++
++	if (cpu == 0) {
++		val0 |= mask;
++		val1 &= ~mask;
++	} else {
++		val0 &= ~mask;
++		val1 |= mask;
++	}
++
++	amba_writel(reg_base + VIC_INT_PTR0_OFFSET, val0);
++	amba_writel(reg_base + VIC_INT_PTR1_OFFSET, val1);
++
++	raw_spin_unlock(&irq_controller_lock);
++
++	return 0;
++}
++#endif
++
++static struct irq_chip ambvic_chip = {
++	.name		= "VIC",
++	.irq_ack	= ambvic_ack_irq,
++	.irq_mask	= ambvic_mask_irq,
++	.irq_mask_ack	= ambvic_mask_ack_irq,
++	.irq_unmask	= ambvic_unmask_irq,
++	.irq_set_type	= ambvic_set_type_irq,
++#ifdef CONFIG_SMP
++	.irq_set_affinity = ambvic_set_affinity,
++#endif
++	.flags		= (IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND |
++			IRQCHIP_SKIP_SET_WAKE),
++};
++
++/* ==========================================================================*/
++#ifdef CONFIG_SMP
++static void ambvic_raise_softirq(const struct cpumask *mask, unsigned int irq)
++{
++	int cpu, softirq;
++
++	/* currently we only support dual cores, so we just pick the
++	 * first cpu we find in 'mask'.. */
++	cpu = cpumask_any(mask);
++
++	/*
++	 * Ensure that stores to Normal memory are visible to the
++	 * other CPUs before issuing the IPI.
++	 */
++	dsb();
++
++	/* submit softirq */
++	softirq = irq + ((cpu == 0) ? (IPI01_IRQ % 32) : (IPI11_IRQ % 32));
++	ambvic_sw_set(ambvic_data.ipi_reg_base, softirq);
++}
++
++void ambvic_smp_softirq_init(void)
++{
++	void __iomem *reg_base = ambvic_data.ipi_reg_base;
++	u32 val;
++
++	raw_spin_lock(&irq_controller_lock);
++
++	/* Clear pending IPIs */
++	amba_writel(reg_base + VIC_SOFTEN_CLR_OFFSET, IPI_IRQ_MASK);
++
++	/* Enable all of IPIs */
++	val = amba_readl(reg_base + VIC_INT_PTR0_OFFSET);
++	val |= IPI0_IRQ_MASK;
++	val &= ~IPI1_IRQ_MASK;
++	amba_writel(reg_base + VIC_INT_PTR0_OFFSET, val);
++
++	val = amba_readl(reg_base + VIC_INT_PTR1_OFFSET);
++	val |= IPI1_IRQ_MASK;
++	val &= ~IPI0_IRQ_MASK;
++	amba_writel(reg_base + VIC_INT_PTR1_OFFSET, val);
++
++	amba_writel(reg_base + VIC_SENSE_OFFSET, IPI_IRQ_MASK);
++	amba_writel(reg_base + VIC_EVENT_OFFSET, IPI_IRQ_MASK);
++	amba_writel(reg_base + VIC_INTEN_OFFSET, IPI_IRQ_MASK);
++
++	raw_spin_unlock(&irq_controller_lock);
++}
++#endif
++
++static inline int ambvic_handle_ipi(struct pt_regs *regs,
++		struct irq_domain *domain, u32 hwirq)
++{
++#ifdef CONFIG_SMP
++	/* IPI Handling */
++	if (AMBVIC_IRQ_IS_IPI(hwirq)) {
++		//printk("***********  hwirq = %d\n", hwirq);
++		ambvic_sw_clr(ambvic_data.ipi_reg_base, hwirq % 32);
++		if (AMBVIC_IRQ_IS_IPI0(hwirq))
++			handle_IPI(hwirq - IPI01_IRQ, regs);
++		else
++			handle_IPI(hwirq - IPI11_IRQ, regs);
++
++		return 1;
++	}
++#endif
++	return 0;
++}
++
++#if (VIC_SUPPORT_CPU_OFFLOAD >= 2)
++static int ambvic_handle_scratchpad_vic(struct pt_regs *regs,
++	struct irq_domain *domain)
++{
++	u32 scratchpad, irq_sta, irq, hwirq;
++	int handled = 0;
++
++	if (smp_processor_id())
++		scratchpad = AHBSP_PRI_IRQ_C1_REG;
++	else
++		scratchpad = AHBSP_PRI_IRQ_C0_REG;
++
++	do {
++		hwirq = amba_readl(scratchpad);
++		if (hwirq == VIC_NULL_PRI_IRQ_VAL) {
++#if (VIC_NULL_PRI_IRQ_FIX == 1)
++			irq_sta = amba_readl(ambvic_data.reg_base[2] + VIC_IRQ_STA_OFFSET);
++			if ((irq_sta & 0x1) == 0)
++				break;
++#else
++			break;
++#endif
++		} else if (hwirq == 0) {
++			irq_sta = amba_readl(ambvic_data.reg_base[0] + VIC_IRQ_STA_OFFSET);
++			if ((irq_sta & 0x1) == 0)
++				break;
++		}
++
++#if 0
++		printk("CPU%d_%s: %d_%d\n",
++			smp_processor_id(), __func__,
++			(hwirq >> 5) & 0x3, hwirq & 0x1F);
++#endif
++		if (ambvic_handle_ipi(regs, domain, hwirq)) {
++			handled = 1;
++			continue;
++		}
++
++		irq = irq_find_mapping(domain, hwirq);
++		handle_IRQ(irq, regs);
++		handled = 1;
++	} while (1);
++
++	return handled;
++}
++#else
++static int ambvic_handle_one(struct pt_regs *regs,
++	struct irq_domain *domain, u32 bank)
++{
++	void __iomem *reg_base = ambvic_data.reg_base[bank];
++	u32 hwirq, irq, irq_sta;
++	int handled = 0;
++
++	do {
++#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
++		hwirq = amba_readl(reg_base + VIC_INT_PENDING_OFFSET);
++		if (hwirq == 0) {
++			irq_sta = amba_readl(reg_base + VIC_IRQ_STA_OFFSET);
++			if ((irq_sta & 0x1) == 0) {
++				break;
++			}
++		}
++#else
++		irq_sta = amba_readl(reg_base + VIC_IRQ_STA_OFFSET);
++		if (irq_sta == 0) {
++			break;
++		}
++		hwirq = ffs(irq_sta) - 1;
++#endif
++		hwirq += bank * NR_VIC_IRQ_SIZE;
++
++		if (ambvic_handle_ipi(regs, domain, hwirq)) {
++			handled = 1;
++			continue;
++		}
++
++		irq = irq_find_mapping(domain, hwirq);
++		handle_IRQ(irq, regs);
++		handled = 1;
++	} while (1);
++
++	return handled;
++}
++#endif
++
++static asmlinkage void __exception_irq_entry ambvic_handle_irq(struct pt_regs *regs)
++{
++	int handled;
++
++	do {
++		handled = 0;
++#if (VIC_SUPPORT_CPU_OFFLOAD >= 2)
++		handled = ambvic_handle_scratchpad_vic(regs, ambvic_data.domain);
++#else
++{
++		int i;
++
++		for (i = 0; i < VIC_INSTANCES; i++) {
++			handled |= ambvic_handle_one(regs, ambvic_data.domain, i);
++		}
++}
++#endif
++	} while (handled);
++}
++
++static int ambvic_irq_domain_map(struct irq_domain *d,
++		unsigned int irq, irq_hw_number_t hwirq)
++{
++	if (hwirq > NR_VIC_IRQS)
++		return -EPERM;
++
++	irq_set_chip_and_handler(irq, &ambvic_chip, handle_level_irq);
++	irq_set_chip_data(irq, ambvic_data.reg_base[HWIRQ_TO_BANK(hwirq)]);
++	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++
++	return 0;
++}
++
++static struct irq_domain_ops amb_irq_domain_ops = {
++	.map = ambvic_irq_domain_map,
++	.xlate = irq_domain_xlate_twocell,
++};
++
++
++#if defined(CONFIG_PM)
++
++struct ambvic_pm_reg {
++	u32 int_sel_reg;
++	u32 inten_reg;
++	u32 soften_reg;
++	u32 proten_reg;
++	u32 sense_reg;
++	u32 bothedge_reg;
++	u32 event_reg;
++	u32 int_ptr0_reg;
++	u32 int_ptr1_reg;
++};
++
++static struct ambvic_pm_reg ambvic_pm[VIC_INSTANCES];
++
++static int ambvic_suspend(void)
++{
++	struct ambvic_pm_reg *pm_val;
++	void __iomem *reg_base;
++	int i;
++
++	for (i = 0; i < VIC_INSTANCES; i++) {
++		reg_base = ambvic_data.reg_base[i];
++		pm_val = &ambvic_pm[i];
++
++		pm_val->int_sel_reg = amba_readl(reg_base + VIC_INT_SEL_OFFSET);
++		pm_val->inten_reg = amba_readl(reg_base + VIC_INTEN_OFFSET);
++		pm_val->soften_reg = amba_readl(reg_base + VIC_SOFTEN_OFFSET);
++		pm_val->proten_reg = amba_readl(reg_base + VIC_PROTEN_OFFSET);
++		pm_val->sense_reg = amba_readl(reg_base + VIC_SENSE_OFFSET);
++		pm_val->bothedge_reg = amba_readl(reg_base + VIC_BOTHEDGE_OFFSET);
++		pm_val->event_reg = amba_readl(reg_base + VIC_EVENT_OFFSET);
++		pm_val->int_ptr0_reg = amba_readl(reg_base + VIC_INT_PTR0_OFFSET);
++		pm_val->int_ptr1_reg = amba_readl(reg_base + VIC_INT_PTR1_OFFSET);
++	}
++
++	return 0;
++}
++
++static void ambvic_resume(void)
++{
++	struct ambvic_pm_reg *pm_val;
++	void __iomem *reg_base;
++	int i;
++
++	for (i = VIC_INSTANCES - 1; i >= 0; i--) {
++		reg_base = ambvic_data.reg_base[i];
++		pm_val = &ambvic_pm[i];
++
++		amba_writel(reg_base + VIC_INT_SEL_OFFSET, pm_val->int_sel_reg);
++		amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0xffffffff);
++		amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0xffffffff);
++		amba_writel(reg_base + VIC_INTEN_OFFSET, pm_val->inten_reg);
++		amba_writel(reg_base + VIC_SOFTEN_CLR_OFFSET, 0xffffffff);
++		amba_writel(reg_base + VIC_SOFTEN_OFFSET, pm_val->soften_reg);
++		amba_writel(reg_base + VIC_PROTEN_OFFSET, pm_val->proten_reg);
++		amba_writel(reg_base + VIC_SENSE_OFFSET, pm_val->sense_reg);
++		amba_writel(reg_base + VIC_BOTHEDGE_OFFSET, pm_val->bothedge_reg);
++		amba_writel(reg_base + VIC_EVENT_OFFSET, pm_val->event_reg);
++		amba_writel(reg_base + VIC_INT_PTR0_OFFSET, pm_val->int_ptr0_reg);
++		amba_writel(reg_base + VIC_INT_PTR1_OFFSET, pm_val->int_ptr1_reg);
++	}
++}
++
++struct syscore_ops ambvic_syscore_ops = {
++	.suspend	= ambvic_suspend,
++	.resume		= ambvic_resume,
++};
++
++#endif
++
++int __init ambvic_of_init(struct device_node *np, struct device_node *parent)
++{
++	void __iomem *reg_base;
++	int i, irq;
++
++	memset(&ambvic_data, 0, sizeof(struct ambvic_chip_data));
++
++	for (i = 0; i < VIC_INSTANCES; i++) {
++		reg_base = of_iomap(np, i);
++		BUG_ON(!reg_base);
++
++		amba_writel(reg_base + VIC_INT_SEL_OFFSET, 0x00000000);
++		amba_writel(reg_base + VIC_INTEN_OFFSET, 0x00000000);
++		amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0xffffffff);
++		amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0xffffffff);
++		amba_writel(reg_base + VIC_INT_PTR0_OFFSET, 0xffffffff);
++		amba_writel(reg_base + VIC_INT_PTR1_OFFSET, 0x00000000);
++
++		ambvic_data.reg_base[i] = reg_base;
++	}
++
++	set_handle_irq(ambvic_handle_irq);
++
++	ambvic_data.domain = irq_domain_add_linear(np,
++			NR_VIC_IRQS, &amb_irq_domain_ops, NULL);
++	BUG_ON(!ambvic_data.domain);
++
++	/* create mapping to make hwirq == irq to make life easier */
++	for (i = NR_VIC_IRQS - 1; i >= 0; i--) {
++		irq = irq_create_mapping(ambvic_data.domain, i);
++		irq_set_chip_and_handler(irq, &ambvic_chip, handle_level_irq);
++		irq_set_chip_data(irq, ambvic_data.reg_base[HWIRQ_TO_BANK(i)]);
++		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++	}
++
++#ifdef CONFIG_SMP
++	ambvic_data.ipi_reg_base = ambvic_data.reg_base[IPI01_IRQ / 32];
++	ambvic_smp_softirq_init();
++	set_smp_cross_call(ambvic_raise_softirq);
++#if 0
++	/*
++	 * Set the default affinity from all CPUs to the boot cpu.
++	 * This is required since the MPIC doesn't limit several CPUs
++	 * from acknowledging the same interrupt.
++	 */
++	cpumask_clear(irq_default_affinity);
++	cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
++#endif
++#endif
++
++#if defined(CONFIG_PM)
++	register_syscore_ops(&ambvic_syscore_ops);
++#endif
++	return 0;
++}
++
++IRQCHIP_DECLARE(ambvic, "ambarella,vic", ambvic_of_init);
++
++/* ==========================================================================*/
++#if (VIC_SUPPORT_CPU_OFFLOAD >= 1)
++void ambvic_sw_set(void __iomem *reg_base, u32 offset)
++{
++	amba_writel(reg_base + VIC_SOFT_INT_INT_OFFSET, offset);
++}
++
++void ambvic_sw_clr(void __iomem *reg_base, u32 offset)
++{
++	amba_writel(reg_base + VIC_SOFT_INT_CLR_INT_OFFSET, offset);
++}
++#else
++void ambvic_sw_set(void __iomem *reg_base, u32 offset)
++{
++	amba_writel(reg_base + VIC_SOFTEN_OFFSET, 0x1 << offset);
++}
++
++void ambvic_sw_clr(void __iomem *reg_base, u32 offset)
++{
++	amba_writel(reg_base + VIC_SOFTEN_CLR_OFFSET, 0x1 << offset);
++}
++#endif
++
++
+diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
+index 521340a7..9ab36620 100644
+--- a/drivers/mfd/wm831x-core.c
++++ b/drivers/mfd/wm831x-core.c
+@@ -1667,7 +1667,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
+ 	switch (ret) {
+ 	case WM8310:
+ 		parent = WM8310;
+-		wm831x->num_gpio = 16;
++		wm831x->num_gpio = 12;
+ 		wm831x->charger_irq_wake = 1;
+ 		if (rev > 0) {
+ 			wm831x->has_gpio_ena = 1;
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 3ae6f132..a3fb62ed 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -2277,6 +2277,7 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
+ 		return 0;
+ 
+ 	mmc_power_off(host);
++	host->ocr = 0;
+ 	return -EIO;
+ }
+ 
+@@ -2748,6 +2749,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
+ 		if (!host->bus_ops || host->bus_ops->suspend)
+ 			break;
+ 
++		mmc_bus_get(host);
+ 		/* Calling bus_ops->remove() with a claimed host can deadlock */
+ 		if (host->bus_ops->remove)
+ 			host->bus_ops->remove(host);
+@@ -2757,6 +2759,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
+ 		mmc_power_off(host);
+ 		mmc_release_host(host);
+ 		host->pm_flags = 0;
++		mmc_bus_put(host);
+ 		break;
+ 
+ 	case PM_POST_SUSPEND:
+diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
+index 35c2f85b..759c0dd7 100644
+--- a/drivers/mmc/core/debugfs.c
++++ b/drivers/mmc/core/debugfs.c
+@@ -126,6 +126,12 @@ static int mmc_ios_show(struct seq_file *s, void *data)
+ 	case MMC_TIMING_SD_HS:
+ 		str = "sd high-speed";
+ 		break;
++	case MMC_TIMING_UHS_SDR12:
++		str = "sd uhs SDR12";
++		break;
++	case MMC_TIMING_UHS_SDR25:
++		str = "sd uhs SDR25";
++		break;
+ 	case MMC_TIMING_UHS_SDR50:
+ 		str = "sd uhs SDR50";
+ 		break;
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index dda1a42a..97e2e287 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -295,13 +295,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
+ 		}
+ 	}
+ 
++	/*
++	 * The EXT_CSD format is meant to be forward compatible. As long
++	 * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
++	 * are authorized, see JEDEC JESD84-B50 section B.8.
++	 */
+ 	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
+-	if (card->ext_csd.rev > 6) {
+-		pr_err("%s: unrecognised EXT_CSD revision %d\n",
+-			mmc_hostname(card->host), card->ext_csd.rev);
+-		err = -EINVAL;
+-		goto out;
+-	}
+ 
+ 	card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
+ 	card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
+diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
+index 6889a821..eab38e78 100644
+--- a/drivers/mmc/core/sdio.c
++++ b/drivers/mmc/core/sdio.c
+@@ -1202,3 +1202,40 @@ err:
+ 	return err;
+ }
+ 
++int sdio_reset_comm(struct mmc_card *card)
++{
++	struct mmc_host *host = card->host;
++	u32 ocr;
++	int err;
++
++	//printk("%s():\n", __func__);
++	mmc_claim_host(host);
++
++	mmc_go_idle(host);
++
++	mmc_set_clock(host, host->f_min);
++
++	err = mmc_send_io_op_cond(host, 0, &ocr);
++	if (err)
++		goto err;
++
++	host->ocr = mmc_select_voltage(host, ocr);
++	if (!host->ocr) {
++		err = -EINVAL;
++		goto err;
++	}
++
++	err = mmc_sdio_init_card(host, host->ocr, card, 0);
++	if (err)
++		goto err;
++
++	mmc_release_host(host);
++	return 0;
++	err:
++		//printk("%s: Error resetting SDIO communications (%d)\n",
++		//       mmc_hostname(host), err);
++		mmc_release_host(host);
++	return err;
++}
++EXPORT_SYMBOL(sdio_reset_comm);
++
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 9ab8f8de..2e2dcbd8 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -4,6 +4,21 @@
+ 
+ comment "MMC/SD/SDIO Host Controller Drivers"
+ 
++config MMC_AMBARELLA
++	tristate "Ambarella Media Processor SD/MMC Host Controller driver"
++	depends on PLAT_AMBARELLA
++	help
++	  This selects the Ambarella Media Processor Multimedia Card
++	  Interface support. If you have an Ambarella Media Processor
++	  platform with a Multimedia Card slot, say Y here.
++
++config AMBARELLA_EMMC_BOOT
++        bool "EMMC Boot for Ambarella Platform"
++        default n
++        help
++          If you want to use ambarella platform to boot from emmc, you must
++          select this item, so it can help emmc reboot.
++
+ config MMC_ARMMMCI
+ 	tristate "ARM AMBA Multimedia Card Interface support"
+ 	depends on ARM_AMBA
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index cd322807..a489d093 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -2,6 +2,7 @@
+ # Makefile for MMC/SD host controller drivers
+ #
+ 
++obj-$(CONFIG_MMC_AMBARELLA)	+= ambarella_sd.o
+ obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
+ obj-$(CONFIG_MMC_PXA)		+= pxamci.o
+ obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
+diff --git a/drivers/mmc/host/ambarella_sd.c b/drivers/mmc/host/ambarella_sd.c
+new file mode 100644
+index 00000000..dbaba4f3
+--- /dev/null
++++ b/drivers/mmc/host/ambarella_sd.c
+@@ -0,0 +1,2826 @@
++/*
++ * drivers/mmc/host/ambarella_sd.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/clk.h>
++#include <linux/of_gpio.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/mmc/slot-gpio.h>
++#include <linux/dma-mapping.h>
++#include <linux/slab.h>
++#include <linux/blkdev.h>
++#include <linux/scatterlist.h>
++#include <linux/mmc/host.h>
++#include <linux/mmc/card.h>
++#include <linux/mmc/mmc.h>
++#include <linux/mmc/sd.h>
++#include <linux/debugfs.h>
++#include <asm/dma.h>
++#include <mach/hardware.h>
++#include <plat/fio.h>
++#include <plat/sd.h>
++#include <plat/event.h>
++#include <plat/rct.h>
++
++static struct mmc_host *G_mmc[SD_INSTANCES * AMBA_SD_MAX_SLOT_NUM];
++
++/* ==========================================================================*/
++#define CONFIG_SD_AMBARELLA_TIMEOUT_VAL		(0xe)
++#define CONFIG_SD_AMBARELLA_WAIT_TIMEOUT	(HZ / 100)
++#define CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT	(100000)
++#define CONFIG_SD_AMBARELLA_MAX_TIMEOUT		(10 * HZ)
++#define CONFIG_SD_AMBARELLA_VSW_PRE_SPEC	(5)
++#define CONFIG_SD_AMBARELLA_VSW_WAIT_LIMIT	(1000)
++
++#undef CONFIG_SD_AMBARELLA_DEBUG
++#undef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
++#undef CONFIG_SD_AMBARELLA_TUNING_DEBUG
++
++#define ambsd_printk(level, phcinfo, format, arg...)	\
++	printk(level "%s.%u: " format, dev_name(phcinfo->pinfo->dev), \
++	phcinfo->slot_id, ## arg)
++
++#define ambsd_err(phcinfo, format, arg...)		\
++	ambsd_printk(KERN_ERR, phcinfo, format, ## arg)
++#define ambsd_warn(phcinfo, format, arg...)		\
++	ambsd_printk(KERN_WARNING, phcinfo, format, ## arg)
++#define ambsd_info(phcinfo, format, arg...)		\
++	ambsd_printk(KERN_INFO, phcinfo, format, ## arg)
++#define ambsd_rtdbg(phcinfo, format, arg...)		\
++	ambsd_printk(KERN_DEBUG, phcinfo, format, ## arg)
++
++#ifdef CONFIG_SD_AMBARELLA_DEBUG
++#define ambsd_dbg(phcinfo, format, arg...)		\
++	ambsd_printk(KERN_DEBUG, phcinfo, format, ## arg)
++#else
++#define ambsd_dbg(phcinfo, format, arg...)		\
++	({ if (0) ambsd_printk(KERN_DEBUG, phcinfo, format, ##arg); 0; })
++#endif
++
++#ifdef CONFIG_SD_AMBARELLA_TUNING_DEBUG
++#define ambsd_tuning_dbg(phcinfo, format, arg...)		\
++	ambsd_printk(KERN_DEBUG, phcinfo, format, ## arg)
++#else
++#define ambsd_tuning_dbg(phcinfo, format, arg...)		\
++	({ if (0) ambsd_printk(KERN_DEBUG, phcinfo, format, ##arg); 0; })
++#endif
++
++
++/* ==========================================================================*/
++enum ambarella_sd_state {
++	AMBA_SD_STATE_IDLE,
++	AMBA_SD_STATE_CMD,
++	AMBA_SD_STATE_DATA,
++	AMBA_SD_STATE_RESET,
++	AMBA_SD_STATE_ERR
++};
++
++struct ambarella_sd_phy_timing {
++	u32				mode;
++	u32				val0;
++	u32				val1;
++};
++
++struct ambarella_sd_mmc_info {
++	struct mmc_host			*mmc;
++	struct mmc_request		*mrq;
++
++	wait_queue_head_t		wait;
++
++	enum ambarella_sd_state		state;
++
++	struct scatterlist		*sg;
++	u32				sg_len;
++	u32				wait_tmo;
++	u16				blk_sz;
++	u16				blk_cnt;
++	u32				arg_reg;
++	u16				xfr_reg;
++	u16				cmd_reg;
++	u16				sta_reg;
++	u8				tmo;
++	u8				use_adma;
++	u32				sta_counter;
++
++	char				*buf_vaddress;
++	dma_addr_t			buf_paddress;
++	u32				dma_address;
++	u32				dma_size;
++
++	void				(*pre_dma)(void *data);
++	void				(*post_dma)(void *data);
++
++	u32				slot_id;
++	struct ambarella_sd_controller_info *pinfo;
++	u32				valid;
++	int				fixed_cd;
++	int				fixed_wp;
++
++	int				pwr_gpio;
++	u8				pwr_gpio_active;
++	int				v18_gpio;
++	u8				v18_gpio_active;
++	u32				no_1_8_v : 1,
++					caps_ddr : 1,
++					caps_adma : 1,
++					force_gpio : 1;
++
++	struct pinctrl			*pinctrl;
++	struct pinctrl_state		*state_work;
++	struct pinctrl_state		*state_idle;
++
++	struct notifier_block		system_event;
++	struct semaphore		system_event_sem;
++
++	struct dentry			*debugfs;
++
++#ifdef CONFIG_PM
++	u32				sd_nisen;
++	u32				sd_eisen;
++	u32				sd_nixen;
++	u32				sd_eixen;
++#endif
++};
++
++struct ambarella_sd_controller_info {
++	unsigned char __iomem 		*regbase;
++	unsigned char __iomem 		*fio_reg;
++	unsigned char __iomem 		*timing_reg;
++	unsigned char __iomem		*sbc_reg;
++	struct device			*dev;
++	unsigned int			irq;
++	u32				dma_fix;
++	u32				reset_error;
++
++	u32				max_blk_sz;
++	struct kmem_cache		*buf_cache;
++
++	struct clk			*clk;
++	u32				default_wait_tmo;
++	u32				switch_voltage_tmo;
++	u8				slot_num;
++	u32				phy_type;
++	struct ambarella_sd_phy_timing	*phy_timing;
++	u32				phy_timing_num;
++
++	struct ambarella_sd_mmc_info	*pslotinfo[AMBA_SD_MAX_SLOT_NUM];
++	struct mmc_ios			controller_ios;
++	bool	auto_tuning;
++};
++
++static const u8 tuning_blk_pattern_4bit[] = {
++        0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
++        0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
++        0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
++        0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
++        0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
++        0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
++        0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
++        0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
++};
++
++static const u8 tuning_blk_pattern_8bit[] = {
++        0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
++        0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
++        0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
++        0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
++        0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
++        0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
++        0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
++        0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
++        0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
++        0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
++        0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
++        0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
++        0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
++        0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
++        0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
++        0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
++};
++
++/* ==========================================================================*/
++#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
++static void ambarella_sd_show_info(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	ambsd_dbg(pslotinfo, "Enter %s\n", __func__);
++	ambsd_dbg(pslotinfo, "sg = 0x%x.\n", (u32)pslotinfo->sg);
++	ambsd_dbg(pslotinfo, "sg_len = 0x%x.\n", pslotinfo->sg_len);
++	ambsd_dbg(pslotinfo, "tmo = 0x%x.\n", pslotinfo->tmo);
++	ambsd_dbg(pslotinfo, "blk_sz = 0x%x.\n", pslotinfo->blk_sz);
++	ambsd_dbg(pslotinfo, "blk_cnt = 0x%x.\n", pslotinfo->blk_cnt);
++	ambsd_dbg(pslotinfo, "arg_reg = 0x%x.\n", pslotinfo->arg_reg);
++	ambsd_dbg(pslotinfo, "xfr_reg = 0x%x.\n", pslotinfo->xfr_reg);
++	ambsd_dbg(pslotinfo, "cmd_reg = 0x%x.\n", pslotinfo->cmd_reg);
++	ambsd_dbg(pslotinfo, "buf_vaddress = 0x%x.\n",
++		(u32)pslotinfo->buf_vaddress);
++	ambsd_dbg(pslotinfo, "buf_paddress = 0x%x.\n", pslotinfo->buf_paddress);
++	ambsd_dbg(pslotinfo, "dma_address = 0x%x.\n", pslotinfo->dma_address);
++	ambsd_dbg(pslotinfo, "dma_size = 0x%x.\n", pslotinfo->dma_size);
++	ambsd_dbg(pslotinfo, "pre_dma = 0x%x.\n", (u32)pslotinfo->pre_dma);
++	ambsd_dbg(pslotinfo, "post_dma = 0x%x.\n", (u32)pslotinfo->post_dma);
++	ambsd_dbg(pslotinfo, "SD: state = 0x%x.\n", pslotinfo->state);
++	ambsd_dbg(pslotinfo, "Exit %s\n", __func__);
++}
++#endif
++
++void ambarella_detect_sd_slot(int slotid, int fixed_cd)
++{
++	struct mmc_host *mmc;
++	struct ambarella_sd_mmc_info *pslotinfo;
++
++	if (slotid >= SD_INSTANCES * AMBA_SD_MAX_SLOT_NUM) {
++		pr_err("%s: Invalid slotid: %d\n", __func__, slotid);
++		return;
++	}
++
++	mmc = G_mmc[slotid];
++	pslotinfo = mmc_priv(mmc);
++	pslotinfo->fixed_cd = fixed_cd;
++
++	mmc_detect_change(mmc, 0);
++}
++EXPORT_SYMBOL(ambarella_detect_sd_slot);
++
++static ssize_t fixed_cd_get(struct file *file, char __user *buf,
++		size_t count, loff_t *ppos)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = file->private_data;
++	char tmp[4];
++
++	snprintf(tmp, sizeof(tmp), "%d\n", pslotinfo->fixed_cd);
++	tmp[3] = '\n';
++
++	return simple_read_from_buffer(buf, count, ppos, tmp, sizeof(tmp));
++}
++
++static ssize_t fixed_cd_set(struct file *file, const char __user *buf,
++		size_t size, loff_t *ppos)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = file->private_data;
++	char tmp[20];
++	ssize_t len;
++
++	len = simple_write_to_buffer(tmp, sizeof(tmp) - 1, ppos, buf, size);
++	if (len >= 0) {
++		tmp[len] = '\0';
++		pslotinfo->fixed_cd = !!simple_strtoul(tmp, NULL, 0);
++	}
++
++	mmc_detect_change(pslotinfo->mmc, 0);
++
++	return len;
++}
++
++static const struct file_operations fixed_cd_fops = {
++	.read	= fixed_cd_get,
++	.write	= fixed_cd_set,
++	.open	= simple_open,
++	.llseek	= default_llseek,
++};
++
++static void ambarella_sd_add_debugfs(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	struct mmc_host *mmc = pslotinfo->mmc;
++	struct dentry *root, *fixed_cd;
++
++	if (!mmc->debugfs_root)
++		return;
++
++	root = debugfs_create_dir("ambhost", mmc->debugfs_root);
++	if (IS_ERR_OR_NULL(root))
++		goto err;
++
++	pslotinfo->debugfs = root;
++
++	fixed_cd = debugfs_create_file("fixed_cd", S_IWUSR | S_IRUGO,
++			pslotinfo->debugfs, pslotinfo, &fixed_cd_fops);
++	if (IS_ERR_OR_NULL(fixed_cd))
++		goto err;
++
++	return;
++
++err:
++	debugfs_remove_recursive(root);
++	pslotinfo->debugfs = NULL;
++	dev_err(pslotinfo->pinfo->dev, "failed to add debugfs\n");
++}
++
++static void ambarella_sd_remove_debugfs(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	debugfs_remove_recursive(pslotinfo->debugfs);
++}
++
++static void ambarella_sd_check_dma_boundary(u32 address, u32 size, u32 max_size)
++{
++	u32 start_512kb, end_512kb;
++
++	start_512kb = (address) & (~(max_size - 1));
++	end_512kb = (address + size - 1) & (~(max_size - 1));
++	BUG_ON(start_512kb != end_512kb);
++}
++
++static void ambarella_sd_pre_sg_to_dma(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++	u32 i, offset;
++
++	for (i = 0, offset = 0; i < pslotinfo->sg_len; i++) {
++		memcpy(pslotinfo->buf_vaddress + offset,
++			sg_virt(&pslotinfo->sg[i]),
++			pslotinfo->sg[i].length);
++		offset += pslotinfo->sg[i].length;
++	}
++	BUG_ON(offset != pslotinfo->dma_size);
++	dma_sync_single_for_device(pslotinfo->pinfo->dev, pslotinfo->buf_paddress,
++		pslotinfo->dma_size, DMA_TO_DEVICE);
++	pslotinfo->dma_address = pslotinfo->buf_paddress;
++	pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
++}
++
++static void ambarella_sd_pre_sg_to_adma(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++	int i;
++	u32 offset;
++	u32 dma_len;
++	u32 remain_size;
++	u32 current_addr;
++	u32 word_num, byte_num;
++
++	dma_len = dma_map_sg(pslotinfo->pinfo->dev, pslotinfo->sg,
++		pslotinfo->sg_len, DMA_TO_DEVICE);
++	for (i = 0, offset = 0; i < dma_len; i++) {
++		remain_size = sg_dma_len(&pslotinfo->sg[i]);
++		current_addr = sg_dma_address(&pslotinfo->sg[i]);
++		current_addr |= pslotinfo->pinfo->dma_fix;
++		if (sd_addr_is_unlign(current_addr)) {
++			ambsd_err(pslotinfo, "Please disable ADMA\n");
++			BUG();
++		}
++
++		while (unlikely(remain_size > SD_ADMA_TBL_LINE_MAX_LEN)) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) =
++				(SD_ADMA_TBL_ATTR_TRAN |
++				SD_ADMA_TBL_ATTR_WORD |
++				SD_ADMA_TBL_ATTR_VALID);
++			*(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
++				current_addr;
++			offset += SD_ADMA_TBL_LINE_SIZE;
++			current_addr += SD_ADMA_TBL_LINE_MAX_LEN;
++			remain_size -= SD_ADMA_TBL_LINE_MAX_LEN;
++		}
++		word_num = remain_size >> 2;
++		byte_num = remain_size - (word_num << 2);
++		if (word_num) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) =
++				(SD_ADMA_TBL_ATTR_TRAN |
++				SD_ADMA_TBL_ATTR_WORD |
++				SD_ADMA_TBL_ATTR_VALID);
++			*(u32 *)(pslotinfo->buf_vaddress + offset) |=
++				(word_num << 16);
++			*(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
++				current_addr;
++			current_addr += (word_num << 2);
++			if (byte_num) {
++				offset += SD_ADMA_TBL_LINE_SIZE;
++			}
++		}
++		if (byte_num) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) =
++				(SD_ADMA_TBL_ATTR_TRAN |
++				SD_ADMA_TBL_ATTR_VALID);
++			*(u32 *)(pslotinfo->buf_vaddress + offset) |=
++				byte_num << 16;
++			*(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
++				current_addr;
++		}
++		if (unlikely(i == dma_len - 1)) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) |=
++				SD_ADMA_TBL_ATTR_END;
++		}
++		offset += SD_ADMA_TBL_LINE_SIZE;
++	}
++	dma_sync_single_for_device(pslotinfo->pinfo->dev, pslotinfo->buf_paddress,
++		offset, DMA_TO_DEVICE);
++	pslotinfo->dma_address = pslotinfo->buf_paddress;
++	pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
++}
++
++static void ambarella_sd_post_sg_to_dma(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++
++	dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
++			pslotinfo->buf_paddress,
++			pslotinfo->dma_size,
++			DMA_TO_DEVICE);
++}
++
++static void ambarella_sd_post_sg_to_adma(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++
++	dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
++			pslotinfo->buf_paddress,
++			pslotinfo->dma_size,
++			DMA_FROM_DEVICE);
++
++	dma_unmap_sg(pslotinfo->pinfo->dev,
++			pslotinfo->sg,
++			pslotinfo->sg_len,
++			DMA_TO_DEVICE);
++}
++
++static void ambarella_sd_pre_dma_to_sg(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++
++	dma_sync_single_for_device(pslotinfo->pinfo->dev,
++			pslotinfo->buf_paddress,
++			pslotinfo->dma_size,
++			DMA_FROM_DEVICE);
++
++	pslotinfo->dma_address = pslotinfo->buf_paddress;
++	pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
++}
++
++static void ambarella_sd_pre_adma_to_sg(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++	int i;
++	u32 dma_len;
++	u32 offset;
++	u32 remain_size;
++	u32 current_addr;
++	u32 word_num, byte_num;
++
++	dma_len = dma_map_sg(pslotinfo->pinfo->dev, pslotinfo->sg,
++		pslotinfo->sg_len, DMA_FROM_DEVICE);
++	for (i = 0, offset = 0; i < dma_len; i++) {
++		remain_size = sg_dma_len(&pslotinfo->sg[i]);
++		current_addr = sg_dma_address(&pslotinfo->sg[i]);
++		current_addr |= pslotinfo->pinfo->dma_fix;
++		if (sd_addr_is_unlign(current_addr)) {
++			ambsd_err(pslotinfo, "Please disable ADMA\n");
++			BUG();
++		}
++
++		while (unlikely(remain_size > SD_ADMA_TBL_LINE_MAX_LEN)) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) =
++				(SD_ADMA_TBL_ATTR_TRAN |
++				SD_ADMA_TBL_ATTR_WORD |
++				SD_ADMA_TBL_ATTR_VALID);
++			*(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
++				current_addr;
++			offset += SD_ADMA_TBL_LINE_SIZE;
++			current_addr += SD_ADMA_TBL_LINE_MAX_LEN;
++			remain_size -= SD_ADMA_TBL_LINE_MAX_LEN;
++		}
++		word_num = remain_size >> 2;
++		byte_num = remain_size - (word_num << 2);
++		if (word_num) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) =
++				(SD_ADMA_TBL_ATTR_TRAN |
++				SD_ADMA_TBL_ATTR_WORD |
++				SD_ADMA_TBL_ATTR_VALID);
++			*(u32 *)(pslotinfo->buf_vaddress + offset) |=
++				(word_num << 16);
++			*(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
++				current_addr;
++			current_addr += (word_num << 2);
++			if (byte_num) {
++				offset += SD_ADMA_TBL_LINE_SIZE;
++			}
++		}
++		if (byte_num) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) =
++				(SD_ADMA_TBL_ATTR_TRAN |
++				SD_ADMA_TBL_ATTR_VALID);
++			*(u32 *)(pslotinfo->buf_vaddress + offset) |=
++				(byte_num << 16);
++			*(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
++				current_addr;
++		}
++		if (unlikely(i == dma_len - 1)) {
++			*(u32 *)(pslotinfo->buf_vaddress + offset) |=
++				SD_ADMA_TBL_ATTR_END;
++		}
++		offset += SD_ADMA_TBL_LINE_SIZE;
++	}
++	dma_sync_single_for_device(pslotinfo->pinfo->dev,
++			pslotinfo->buf_paddress, offset,
++			DMA_TO_DEVICE);
++	pslotinfo->dma_address = pslotinfo->buf_paddress;
++	pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
++}
++
++static void ambarella_sd_post_dma_to_sg(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++	u32 i, offset;
++
++	dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
++			pslotinfo->buf_paddress,
++			pslotinfo->dma_size,
++			DMA_FROM_DEVICE);
++
++	for (i = 0, offset = 0; i < pslotinfo->sg_len; i++) {
++		memcpy(sg_virt(&pslotinfo->sg[i]),
++			pslotinfo->buf_vaddress + offset,
++			pslotinfo->sg[i].length);
++		offset += pslotinfo->sg[i].length;
++	}
++	BUG_ON(offset != pslotinfo->dma_size);
++}
++
++static void ambarella_sd_post_adma_to_sg(void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = data;
++
++	dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
++			pslotinfo->buf_paddress,
++			pslotinfo->dma_size,
++			DMA_FROM_DEVICE);
++
++	dma_unmap_sg(pslotinfo->pinfo->dev,
++			pslotinfo->sg,
++			pslotinfo->sg_len,
++			DMA_FROM_DEVICE);
++}
++
++static void ambarella_sd_request_bus(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++
++	down(&pslotinfo->system_event_sem);
++
++	if (pslotinfo->slot_id == 0) {
++		fio_select_lock(SELECT_FIO_SD);
++	} else {
++		fio_select_lock(SELECT_FIO_SDIO);
++		if (pslotinfo->force_gpio)
++			pinctrl_select_state(pslotinfo->pinctrl, pslotinfo->state_work);
++	}
++
++}
++
++static void ambarella_sd_release_bus(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++
++	if (pslotinfo->slot_id == 0) {
++		fio_unlock(SELECT_FIO_SD);
++	} else {
++		if (pslotinfo->force_gpio)
++			pinctrl_select_state(pslotinfo->pinctrl, pslotinfo->state_idle);
++		fio_unlock(SELECT_FIO_SDIO);
++	}
++
++	up(&pslotinfo->system_event_sem);
++}
++
++static void ambarella_sd_enable_int(struct mmc_host *mmc, u32 mask)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	if (pinfo->slot_num > 1) {
++		if (pslotinfo->slot_id == 0)
++			fio_amb_sd0_set_int(mask, 1);
++		else
++			fio_amb_sdio0_set_int(mask, 1);
++	} else {
++		amba_setbitsl(pinfo->regbase + SD_NISEN_OFFSET, mask);
++		amba_setbitsl(pinfo->regbase + SD_NIXEN_OFFSET, mask);
++	}
++
++}
++
++static void ambarella_sd_disable_int(struct mmc_host *mmc, u32 mask)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	if (pinfo->slot_num > 1) {
++		if (pslotinfo->slot_id == 0)
++			fio_amb_sd0_set_int(mask, 0);
++		else
++			fio_amb_sdio0_set_int(mask, 0);
++	} else {
++		amba_clrbitsl(pinfo->regbase + SD_NISEN_OFFSET, mask);
++		amba_clrbitsl(pinfo->regbase + SD_NIXEN_OFFSET, mask);
++	}
++}
++
++static void ambarella_sd_set_iclk(struct mmc_host *mmc, u16 clk_div)
++{
++	u16 clkreg;
++	u32 counter = 0;
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	clk_div <<= 8;
++	clk_div |= SD_CLK_ICLK_EN;
++	amba_writew(pinfo->regbase + SD_CLK_OFFSET, clk_div);
++	while (1) {
++		clkreg = amba_readw(pinfo->regbase + SD_CLK_OFFSET);
++		if (clkreg & SD_CLK_ICLK_STABLE)
++			break;
++		if ((clkreg & ~SD_CLK_ICLK_STABLE) != clk_div) {
++			amba_writew(pinfo->regbase + SD_CLK_OFFSET, clk_div);
++			udelay(1);
++		}
++		counter++;
++		if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++			ambsd_warn(pslotinfo,
++				"Wait SD_CLK_ICLK_STABLE = %d @ 0x%x\n",
++				counter, clkreg);
++			break;
++		}
++	}
++}
++
++static void ambarella_sd_clear_clken(struct mmc_host *mmc)
++{
++	u16 clkreg;
++	u32 counter = 0;
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	while (1) {
++		clkreg = amba_readw(pinfo->regbase + SD_CLK_OFFSET);
++		if (clkreg & SD_CLK_EN) {
++			amba_writew(pinfo->regbase + SD_CLK_OFFSET,
++				(clkreg & ~SD_CLK_EN));
++			udelay(1);
++		} else {
++			break;
++		}
++		counter++;
++		if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++			ambsd_warn(pslotinfo, "%s(%d @ 0x%x)\n",
++				__func__, counter, clkreg);
++			break;
++		}
++	}
++}
++
++static void ambarella_sd_set_clken(struct mmc_host *mmc)
++{
++	u16 clkreg;
++	u32 counter = 0;
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	while (1) {
++		clkreg = amba_readw(pinfo->regbase + SD_CLK_OFFSET);
++		if (clkreg & SD_CLK_EN) {
++			break;
++		} else {
++			amba_writew(pinfo->regbase + SD_CLK_OFFSET,
++				(clkreg | SD_CLK_EN));
++			udelay(1);
++		}
++		counter++;
++		if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++			ambsd_warn(pslotinfo, "%s(%d @ 0x%x)\n",
++				__func__, counter, clkreg);
++			break;
++		}
++	}
++}
++
++static void ambarella_sd_reset_all(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 nis_flag = 0;
++	u32 eis_flag = 0;
++	u32 counter = 0;
++	u8 reset_reg;
++
++	ambsd_dbg(pslotinfo, "Enter %s with state %u\n",
++		__func__, pslotinfo->state);
++
++	ambarella_sd_disable_int(mmc, 0xFFFFFFFF);
++	amba_write2w(pinfo->regbase + SD_NIS_OFFSET, 0xFFFF, 0xFFFF);
++
++	/*reset sd timing register*/
++	if(pinfo->phy_type == 0 && pinfo->timing_reg) {
++		amba_writel(pinfo->sbc_reg, 0x0);
++		amba_writel(pinfo->timing_reg + 4, 0x0);
++		amba_writel(pinfo->timing_reg, 0x04070000);
++	} else if(pinfo->phy_type == 1) {
++		amba_writel(pinfo->regbase + SD_DELAY_SEL_L, 0x0);
++		amba_writel(pinfo->regbase + SD_DELAY_SEL_H, 0x0);
++	} else if(pinfo->phy_type == 2 && pinfo->timing_reg) {
++		amba_writel(pinfo->timing_reg, amba_rct_readl(pinfo->timing_reg)
++			& 0x1c1f1c1f);
++	}
++
++	amba_writeb(pinfo->regbase + SD_RESET_OFFSET, SD_RESET_ALL);
++	while (1) {
++		reset_reg = amba_readb(pinfo->regbase + SD_RESET_OFFSET);
++		if (!(reset_reg & SD_RESET_ALL))
++			break;
++		counter++;
++		if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++			ambsd_warn(pslotinfo, "Wait SD_RESET_ALL....\n");
++			break;
++		}
++	}
++
++	ambarella_sd_set_iclk(mmc, 0x0000);
++	amba_writeb(pinfo->regbase + SD_TMO_OFFSET,
++		CONFIG_SD_AMBARELLA_TIMEOUT_VAL);
++
++	nis_flag = SD_NISEN_REMOVAL	|
++		SD_NISEN_INSERT		|
++		SD_NISEN_DMA		|
++		SD_NISEN_BLOCK_GAP	|
++		SD_NISEN_XFR_DONE	|
++		SD_NISEN_CMD_DONE;
++	eis_flag = SD_EISEN_ACMD12_ERR	|
++		SD_EISEN_CURRENT_ERR	|
++		SD_EISEN_DATA_BIT_ERR	|
++		SD_EISEN_DATA_CRC_ERR	|
++		SD_EISEN_DATA_TMOUT_ERR	|
++		SD_EISEN_CMD_IDX_ERR	|
++		SD_EISEN_CMD_BIT_ERR	|
++		SD_EISEN_CMD_CRC_ERR	|
++		SD_EISEN_CMD_TMOUT_ERR;
++
++	if (pslotinfo->use_adma == 1)
++		eis_flag |= SD_EISEN_ADMA_ERR;
++	else
++		eis_flag &= ~SD_EISEN_ADMA_ERR;
++
++	ambarella_sd_enable_int(mmc, (eis_flag << 16) | nis_flag);
++
++	pslotinfo->state = AMBA_SD_STATE_RESET;
++	pinfo->reset_error = 0;
++
++	ambsd_dbg(pslotinfo, "Exit %s with counter %u\n", __func__, counter);
++}
++
++static void ambarella_sd_reset_cmd_line(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 counter = 0;
++	u8 reset_reg;
++
++	ambsd_dbg(pslotinfo, "Enter %s with state %u\n",
++		__func__, pslotinfo->state);
++
++	amba_writeb(pinfo->regbase + SD_RESET_OFFSET, SD_RESET_CMD);
++	while (1) {
++		reset_reg = amba_readb(pinfo->regbase + SD_RESET_OFFSET);
++		if (!(reset_reg & SD_RESET_CMD))
++			break;
++		counter++;
++		if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++			ambsd_warn(pslotinfo, "Wait SD_RESET_CMD...\n");
++			pinfo->reset_error = 1;
++			break;
++		}
++	}
++
++	ambsd_dbg(pslotinfo, "Exit %s with counter %u\n", __func__, counter);
++}
++
++static void ambarella_sd_reset_data_line(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 counter = 0;
++	u8 reset_reg;
++
++	ambsd_dbg(pslotinfo, "Enter %s with state %u\n",
++		__func__, pslotinfo->state);
++
++	amba_writeb(pinfo->regbase + SD_RESET_OFFSET, SD_RESET_DAT);
++	while (1) {
++		reset_reg = amba_readb(pinfo->regbase + SD_RESET_OFFSET);
++		if (!(reset_reg & SD_RESET_DAT))
++			break;
++		counter++;
++		if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++			ambsd_warn(pslotinfo, "Wait SD_RESET_DAT...\n");
++			pinfo->reset_error = 1;
++			break;
++		}
++	}
++
++	ambsd_dbg(pslotinfo, "Exit %s with counter %u\n", __func__, counter);
++}
++
++static inline void ambarella_sd_data_done(
++	struct ambarella_sd_mmc_info *pslotinfo, u16 nis, u16 eis)
++{
++	struct mmc_data *data;
++
++	if ((pslotinfo->state == AMBA_SD_STATE_CMD) &&
++		((pslotinfo->cmd_reg & 0x3) == SD_CMD_RSP_48BUSY)) {
++		if (eis) {
++			pslotinfo->state = AMBA_SD_STATE_ERR;
++		} else {
++			pslotinfo->state = AMBA_SD_STATE_IDLE;
++		}
++		wake_up(&pslotinfo->wait);
++		return;
++	}
++	if (pslotinfo->mrq == NULL) {
++		ambsd_dbg(pslotinfo, "%s: mrq is NULL, nis[0x%x] eis[0x%x]\n",
++			__func__, nis, eis);
++		return;
++	}
++	if (pslotinfo->mrq->data == NULL) {
++		ambsd_dbg(pslotinfo, "%s: data is NULL, nis[0x%x] eis[0x%x]\n",
++			__func__, nis, eis);
++		return;
++	}
++
++	data = pslotinfo->mrq->data;
++	if (eis) {
++		if (eis & SD_EIS_DATA_BIT_ERR) {
++			data->error = -EILSEQ;
++		} else if (eis & SD_EIS_DATA_CRC_ERR) {
++			data->error = -EILSEQ;
++		} else if (eis & SD_EIS_ADMA_ERR) {
++			data->error = -EILSEQ;
++		} else if (eis & SD_EIS_DATA_TMOUT_ERR) {
++			data->error = -ETIMEDOUT;
++		} else {
++			data->error = -EIO;
++		}
++#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
++		ambsd_err(pslotinfo, "%s: CMD[%u] get eis[0x%x]\n", __func__,
++			pslotinfo->mrq->cmd->opcode, eis);
++#endif
++		pslotinfo->state = AMBA_SD_STATE_ERR;
++		wake_up(&pslotinfo->wait);
++		return;
++	} else {
++		data->bytes_xfered = pslotinfo->dma_size;
++	}
++
++	pslotinfo->state = AMBA_SD_STATE_IDLE;
++	wake_up(&pslotinfo->wait);
++}
++
++static inline void ambarella_sd_cmd_done(
++	struct ambarella_sd_mmc_info *pslotinfo, u16 nis, u16 eis)
++{
++	struct mmc_command *cmd;
++	u32 rsp0, rsp1, rsp2, rsp3;
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u16 ac12es;
++
++	if (pslotinfo->mrq == NULL) {
++		ambsd_dbg(pslotinfo, "%s: mrq is NULL, nis[0x%x] eis[0x%x]\n",
++			__func__, nis, eis);
++		return;
++	}
++	if (pslotinfo->mrq->cmd == NULL) {
++		ambsd_dbg(pslotinfo, "%s: cmd is NULL, nis[0x%x] eis[0x%x]\n",
++			__func__, nis, eis);
++		return;
++	}
++
++	cmd = pslotinfo->mrq->cmd;
++	if (eis) {
++		if (eis & SD_EIS_CMD_BIT_ERR) {
++			cmd->error = -EILSEQ;
++		} else if (eis & SD_EIS_CMD_CRC_ERR) {
++			cmd->error = -EILSEQ;
++		} else if (eis & SD_EIS_CMD_TMOUT_ERR) {
++			cmd->error = -ETIMEDOUT;
++		} else if (eis & SD_EIS_ACMD12_ERR) {
++			ac12es = amba_readl(pinfo->regbase + SD_AC12ES_OFFSET);
++			if (ac12es & SD_AC12ES_TMOUT_ERROR) {
++				cmd->error = -ETIMEDOUT;
++			} else if (eis & SD_AC12ES_CRC_ERROR) {
++				cmd->error = -EILSEQ;
++			} else {
++				cmd->error = -EIO;
++			}
++
++			if (pslotinfo->mrq->stop) {
++				pslotinfo->mrq->stop->error = cmd->error;
++			} else {
++				ambsd_err(pslotinfo, "%s NULL stop 0x%x %u\n",
++					__func__, ac12es, cmd->error);
++			}
++		} else {
++			cmd->error = -EIO;
++		}
++#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
++		ambsd_err(pslotinfo, "%s: CMD[%u] get eis[0x%x]\n", __func__,
++			pslotinfo->mrq->cmd->opcode, eis);
++#endif
++		pslotinfo->state = AMBA_SD_STATE_ERR;
++		wake_up(&pslotinfo->wait);
++		return;
++	}
++
++	if (cmd->flags & MMC_RSP_136) {
++		rsp0 = amba_readl(pinfo->regbase + SD_RSP0_OFFSET);
++		rsp1 = amba_readl(pinfo->regbase + SD_RSP1_OFFSET);
++		rsp2 = amba_readl(pinfo->regbase + SD_RSP2_OFFSET);
++		rsp3 = amba_readl(pinfo->regbase + SD_RSP3_OFFSET);
++		cmd->resp[0] = ((rsp3 << 8) | (rsp2 >> 24));
++		cmd->resp[1] = ((rsp2 << 8) | (rsp1 >> 24));
++		cmd->resp[2] = ((rsp1 << 8) | (rsp0 >> 24));
++		cmd->resp[3] = (rsp0 << 8);
++	} else {
++		cmd->resp[0] = amba_readl(pinfo->regbase + SD_RSP0_OFFSET);
++	}
++
++	if ((pslotinfo->state == AMBA_SD_STATE_CMD) &&
++		((pslotinfo->cmd_reg & 0x3) != SD_CMD_RSP_48BUSY)) {
++		pslotinfo->state = AMBA_SD_STATE_IDLE;
++		wake_up(&pslotinfo->wait);
++	}
++}
++
++static void ambarella_sd_set_clk(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 sd_clk, desired_clk, actual_clk, bneed_div = 1;
++	u16 clk_div = 0x0000;
++
++	ambarella_sd_clear_clken(mmc);
++	if (ios->clock != 0) {
++		desired_clk = ios->clock;
++		if (desired_clk > mmc->f_max)
++			desired_clk = mmc->f_max;
++
++		if (desired_clk < 10000000) {
++			/* Below 10Mhz, divide by sd controller */
++			clk_set_rate(pinfo->clk, mmc->f_max);
++		} else {
++			clk_set_rate(pinfo->clk, desired_clk);
++			actual_clk = clk_get_rate(pinfo->clk);
++			bneed_div = 0;
++		}
++
++		if (bneed_div) {
++			sd_clk = clk_get_rate(pinfo->clk);
++			for (clk_div = 0x0; clk_div <= 0x80;) {
++				if (clk_div == 0)
++					actual_clk = sd_clk;
++				else
++					actual_clk = sd_clk / (clk_div << 1);
++
++				if (actual_clk <= desired_clk)
++					break;
++
++				if (clk_div >= 0x80)
++					break;
++
++				if (clk_div == 0x0)
++					clk_div = 0x1;
++				else
++					clk_div <<= 1;
++			}
++		}
++		ambsd_dbg(pslotinfo, "sd_pll = %lu.\n", clk_get_rate(pinfo->clk));
++		ambsd_dbg(pslotinfo, "desired_clk = %u.\n", desired_clk);
++		ambsd_dbg(pslotinfo, "actual_clk = %u.\n", actual_clk);
++		ambsd_dbg(pslotinfo, "clk_div = %u.\n", clk_div);
++		ambarella_sd_set_iclk(mmc, clk_div);
++		ambarella_sd_set_clken(mmc);
++	}
++}
++
++static void ambarella_sd_set_pwr(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	if (ios->power_mode == MMC_POWER_OFF) {
++		ambarella_sd_reset_all(pslotinfo->mmc);
++		amba_writeb(pinfo->regbase + SD_PWR_OFFSET, SD_PWR_OFF);
++
++		if (gpio_is_valid(pslotinfo->pwr_gpio)) {
++			gpio_set_value_cansleep(pslotinfo->pwr_gpio,
++						!pslotinfo->pwr_gpio_active);
++			msleep(300);
++		}
++
++		if (gpio_is_valid(pslotinfo->v18_gpio)) {
++			gpio_set_value_cansleep(pslotinfo->v18_gpio,
++						!pslotinfo->v18_gpio_active);
++			msleep(10);
++		}
++	} else if (ios->power_mode == MMC_POWER_UP) {
++		if (gpio_is_valid(pslotinfo->v18_gpio)) {
++			gpio_set_value_cansleep(pslotinfo->v18_gpio,
++						!pslotinfo->v18_gpio_active);
++			msleep(10);
++		}
++
++		if (gpio_is_valid(pslotinfo->pwr_gpio)) {
++			gpio_set_value_cansleep(pslotinfo->pwr_gpio,
++						pslotinfo->pwr_gpio_active);
++			msleep(300);
++		}
++
++		amba_writeb(pinfo->regbase + SD_PWR_OFFSET,
++			(SD_PWR_ON | SD_PWR_3_3V));
++	} else if (ios->power_mode == MMC_POWER_ON) {
++		switch (1 << ios->vdd) {
++		case MMC_VDD_165_195:
++		case MMC_VDD_32_33:
++		case MMC_VDD_33_34:
++			break;
++		default:
++			ambsd_err(pslotinfo, "%s Wrong voltage[%u]!\n",
++				__func__, ios->vdd);
++			break;
++		}
++	}
++	msleep(1);
++	ambsd_dbg(pslotinfo, "pwr = 0x%x.\n",
++		amba_readb(pinfo->regbase + SD_PWR_OFFSET));
++}
++
++static void ambarella_sd_set_phy_timing(
++		struct ambarella_sd_controller_info *pinfo, int mode)
++{
++	u32 i, val0, val1;
++
++	if (pinfo->phy_type < 0 || !pinfo->phy_timing || pinfo->phy_timing_num == 0)
++		return;
++
++	for (i = 0; i < pinfo->phy_timing_num; i++) {
++		if (pinfo->phy_timing[i].mode & (0x1 << mode))
++			break;
++	}
++
++	/* phy setting is not defined in DTS for this mode, so we use the
++	 * default phy setting defined for DS mode. */
++	if (i >= pinfo->phy_timing_num)
++		i = 0;
++
++	val0 = pinfo->phy_timing[i].val0;
++	val1 = pinfo->phy_timing[i].val1;
++
++	if (pinfo->phy_type == 0) {
++		/*using rct sd phy*/
++		amba_writel(pinfo->timing_reg, val0 | 0x02000000);
++		amba_writel(pinfo->timing_reg, val0);
++		amba_writel(pinfo->regbase + SD_LAT_CTRL_OFFSET, val1);
++	} else if(pinfo->phy_type == 1) {
++		/*using sd controller as sd phy*/
++		amba_writel(pinfo->regbase + SD_DELAY_SEL_L, val0);
++		amba_writel(pinfo->regbase + SD_DELAY_SEL_H, val1);
++	} else {
++		u32 ms_delay = amba_rct_readl(pinfo->timing_reg);
++		ms_delay &= val0;
++		ms_delay |= val1;
++		amba_rct_writel(pinfo->timing_reg, ms_delay);
++	}
++}
++
++static void ambarella_sd_set_bus(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u8 hostr = 0;
++
++	hostr = amba_readb(pinfo->regbase + SD_HOST_OFFSET);
++	if (ios->bus_width == MMC_BUS_WIDTH_8) {
++		hostr |= SD_HOST_8BIT;
++		hostr &= ~(SD_HOST_4BIT);
++	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
++		hostr &= ~(SD_HOST_8BIT);
++		hostr |= SD_HOST_4BIT;
++	} else if (ios->bus_width == MMC_BUS_WIDTH_1) {
++		hostr &= ~(SD_HOST_8BIT);
++		hostr &= ~(SD_HOST_4BIT);
++	} else {
++		ambsd_err(pslotinfo, "Unknown bus_width[%u], assume 1bit.\n",
++			ios->bus_width);
++		hostr &= ~(SD_HOST_8BIT);
++		hostr &= ~(SD_HOST_4BIT);
++	}
++
++	hostr &= ~SD_HOST_HIGH_SPEED;
++	switch (ios->timing) {
++	case MMC_TIMING_LEGACY:
++	case MMC_TIMING_MMC_HS:
++	case MMC_TIMING_MMC_HS200:
++	case MMC_TIMING_SD_HS:
++	case MMC_TIMING_UHS_SDR12:
++	case MMC_TIMING_UHS_SDR25:
++	case MMC_TIMING_UHS_SDR50:
++	case MMC_TIMING_UHS_SDR104:
++		amba_clrbitsl(pinfo->regbase + SD_XC_CTR_OFFSET,
++			SD_XC_CTR_DDR_EN);
++		amba_clrbitsw(pinfo->regbase + SD_HOST2_OFFSET, 0x0004);
++		break;
++	case MMC_TIMING_UHS_DDR50:
++		hostr |= SD_HOST_HIGH_SPEED;
++		amba_setbitsl(pinfo->regbase + SD_XC_CTR_OFFSET,
++			SD_XC_CTR_DDR_EN);
++		amba_setbitsw(pinfo->regbase + SD_HOST2_OFFSET, 0x0004);
++		break;
++	default:
++		amba_clrbitsl(pinfo->regbase + SD_XC_CTR_OFFSET,
++			SD_XC_CTR_DDR_EN);
++		amba_clrbitsw(pinfo->regbase + SD_HOST2_OFFSET, 0x0004);
++		ambsd_err(pslotinfo, "Unknown timing[%d], assume legacy.\n",
++			ios->timing);
++		break;
++	}
++
++	amba_writeb(pinfo->regbase + SD_HOST_OFFSET, hostr);
++	ambsd_dbg(pslotinfo, "hostr = 0x%x.\n", hostr);
++
++	if(!pinfo->auto_tuning || ios->timing == MMC_TIMING_LEGACY
++		|| ios->timing == MMC_TIMING_MMC_HS || ios->timing == MMC_TIMING_SD_HS)
++		ambarella_sd_set_phy_timing(pinfo, ios->timing);
++
++}
++
++static void ambarella_sd_check_ios(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	if ((pinfo->controller_ios.power_mode != ios->power_mode) ||
++		(pinfo->controller_ios.vdd != ios->vdd) ||
++		(pslotinfo->state == AMBA_SD_STATE_RESET)) {
++		ambarella_sd_set_pwr(mmc, ios);
++		pinfo->controller_ios.power_mode = ios->power_mode;
++		pinfo->controller_ios.vdd = ios->vdd;
++	}
++
++	if ((pinfo->controller_ios.clock != ios->clock) ||
++		(pslotinfo->state == AMBA_SD_STATE_RESET)) {
++		ambarella_sd_set_clk(mmc, ios);
++		pinfo->controller_ios.clock = ios->clock;
++	}
++
++	if ((pinfo->controller_ios.bus_width != ios->bus_width) ||
++		(pinfo->controller_ios.timing != ios->timing) ||
++		(pslotinfo->state == AMBA_SD_STATE_RESET)) {
++		ambarella_sd_set_bus(mmc, ios);
++		pinfo->controller_ios.bus_width = ios->bus_width;
++		pinfo->controller_ios.timing = ios->timing;
++	}
++
++	if (pslotinfo->state == AMBA_SD_STATE_RESET) {
++		pslotinfo->state = AMBA_SD_STATE_IDLE;
++	}
++}
++
++static void ambarella_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++	ambarella_sd_request_bus(mmc);
++	ambarella_sd_check_ios(mmc, ios);
++	ambarella_sd_release_bus(mmc);
++}
++
++static void ambarella_sd_recovery(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 latency = 0, sbc_reg = 0, timing_reg0 = 0, timing_reg1 = 0;
++	u32 sd_delay_sel0 = 0, sd_delay_sel1 = 0, divisor = 0;
++
++	/*save the sd timing register*/
++	if(pinfo->phy_type == 0 && pinfo->timing_reg) {
++		latency = amba_readl(pinfo->regbase + SD_LAT_CTRL_OFFSET);
++		timing_reg0 = amba_readl(pinfo->timing_reg);
++		timing_reg1 = amba_readl(pinfo->timing_reg + 4);
++		sbc_reg = amba_readl(pinfo->sbc_reg);
++	} else if(pinfo->phy_type == 1) {
++		sd_delay_sel0 = amba_readl(pinfo->regbase + SD_DELAY_SEL_L);
++		sd_delay_sel1 = amba_readl(pinfo->regbase + SD_DELAY_SEL_H);
++	} else if(pinfo->phy_type == 2 && pinfo->timing_reg) {
++		timing_reg0 = amba_readl(pinfo->timing_reg);
++	}
++
++	divisor = (amba_readw(pinfo->regbase + SD_CLK_OFFSET) & 0xff00) >> 8;
++
++	ambarella_sd_reset_all(mmc);
++
++	/*restore clk*/
++	ambarella_sd_clear_clken(mmc);
++	ambarella_sd_set_iclk(mmc, divisor);
++	ambarella_sd_set_clken(mmc);
++	ambarella_sd_set_bus(mmc, &pinfo->controller_ios);
++
++	/*restore the sd timing register*/
++	if(pinfo->phy_type == 0 && pinfo->timing_reg) {
++		amba_writel(pinfo->regbase + SD_LAT_CTRL_OFFSET, latency);
++		amba_writel(pinfo->timing_reg, timing_reg0);
++		amba_writel(pinfo->timing_reg + 4, timing_reg1);
++		amba_writel(pinfo->sbc_reg, sbc_reg);
++	} else if(pinfo->phy_type == 1) {
++		amba_writel(pinfo->regbase + SD_DELAY_SEL_L, sd_delay_sel0);
++		amba_writel(pinfo->regbase + SD_DELAY_SEL_H, sd_delay_sel1);
++	} else if(pinfo->phy_type == 2 && pinfo->timing_reg) {
++		amba_writel(pinfo->timing_reg, timing_reg0);
++	}
++
++}
++
++static u32 ambarella_sd_check_cd(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	int cdpin;
++
++	if (pslotinfo->fixed_cd != -1) {
++		cdpin = !!pslotinfo->fixed_cd;
++	} else {
++		cdpin = mmc_gpio_get_cd(mmc);
++		if (cdpin < 0) {
++			cdpin = amba_readl(pinfo->regbase + SD_STA_OFFSET);
++			cdpin &= SD_STA_CARD_INSERTED;
++		}
++	}
++
++	return !!cdpin;
++}
++
++static inline void ambarella_sd_prepare_tmo(
++	struct ambarella_sd_mmc_info *pslotinfo,
++	struct mmc_data *pmmcdata)
++{
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	pslotinfo->tmo = CONFIG_SD_AMBARELLA_TIMEOUT_VAL;
++	pslotinfo->wait_tmo = min_t(u32, pinfo->default_wait_tmo, CONFIG_SD_AMBARELLA_MAX_TIMEOUT);
++	pslotinfo->sta_counter = pinfo->default_wait_tmo / CONFIG_SD_AMBARELLA_MAX_TIMEOUT + 1;
++
++	ambsd_dbg(pslotinfo, "timeout_ns = %u, timeout_clks = %u, "
++		"wait_tmo = %u, tmo = %u, sta_counter = %u.\n",
++		pmmcdata->timeout_ns, pmmcdata->timeout_clks,
++		pslotinfo->wait_tmo, pslotinfo->tmo, pslotinfo->sta_counter);
++}
++
++static inline void ambarella_sd_pre_cmd(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	pslotinfo->state = AMBA_SD_STATE_CMD;
++	pslotinfo->sg_len = 0;
++	pslotinfo->sg = NULL;
++	pslotinfo->blk_sz = 0;
++	pslotinfo->blk_cnt = 0;
++	pslotinfo->arg_reg = 0;
++	pslotinfo->cmd_reg = 0;
++	pslotinfo->sta_reg = 0;
++	pslotinfo->tmo = CONFIG_SD_AMBARELLA_TIMEOUT_VAL;
++	pslotinfo->wait_tmo = (1 * HZ);
++	pslotinfo->xfr_reg = 0;
++	pslotinfo->dma_address = 0;
++	pslotinfo->dma_size = 0;
++
++	if (pslotinfo->mrq->stop) {
++		if (likely(pslotinfo->mrq->stop->opcode ==
++			MMC_STOP_TRANSMISSION)) {
++			pslotinfo->xfr_reg = SD_XFR_AC12_EN;
++		} else {
++			ambsd_err(pslotinfo, "%s strange stop cmd%u\n",
++				__func__, pslotinfo->mrq->stop->opcode);
++		}
++	}
++
++	if (!(pslotinfo->mrq->cmd->flags & MMC_RSP_PRESENT))
++		pslotinfo->cmd_reg = SD_CMD_RSP_NONE;
++	else if (pslotinfo->mrq->cmd->flags & MMC_RSP_136)
++		pslotinfo->cmd_reg = SD_CMD_RSP_136;
++	else if (pslotinfo->mrq->cmd->flags & MMC_RSP_BUSY)
++		pslotinfo->cmd_reg = SD_CMD_RSP_48BUSY;
++	else
++		pslotinfo->cmd_reg = SD_CMD_RSP_48;
++	if (pslotinfo->mrq->cmd->flags & MMC_RSP_CRC)
++		pslotinfo->cmd_reg |= SD_CMD_CHKCRC;
++	if (pslotinfo->mrq->cmd->flags & MMC_RSP_OPCODE)
++		pslotinfo->cmd_reg |= SD_CMD_CHKIDX;
++	pslotinfo->cmd_reg |= SD_CMD_IDX(pslotinfo->mrq->cmd->opcode);
++	pslotinfo->arg_reg = pslotinfo->mrq->cmd->arg;
++
++	if (pslotinfo->mrq->data) {
++		pslotinfo->state = AMBA_SD_STATE_DATA;
++		ambarella_sd_prepare_tmo(pslotinfo, pslotinfo->mrq->data);
++		pslotinfo->blk_sz = (pslotinfo->mrq->data->blksz & 0xFFF);
++		pslotinfo->dma_size = pslotinfo->mrq->data->blksz *
++			pslotinfo->mrq->data->blocks;
++		pslotinfo->sg_len = pslotinfo->mrq->data->sg_len;
++		pslotinfo->sg = pslotinfo->mrq->data->sg;
++		pslotinfo->xfr_reg |= SD_XFR_DMA_EN;
++		pslotinfo->cmd_reg |= SD_CMD_DATA;
++		pslotinfo->blk_cnt = pslotinfo->mrq->data->blocks;
++		if (pslotinfo->blk_cnt > 1) {
++			pslotinfo->xfr_reg |= SD_XFR_MUL_SEL;
++			pslotinfo->xfr_reg |= SD_XFR_BLKCNT_EN;
++		}
++		if (pslotinfo->mrq->data->flags & MMC_DATA_STREAM) {
++			pslotinfo->xfr_reg |= SD_XFR_MUL_SEL;
++			pslotinfo->xfr_reg &= ~SD_XFR_BLKCNT_EN;
++		}
++		if (pslotinfo->mrq->data->flags & MMC_DATA_WRITE) {
++			pslotinfo->xfr_reg &= ~SD_XFR_CTH_SEL;
++			pslotinfo->sta_reg = (SD_STA_WRITE_XFR_ACTIVE |
++				SD_STA_DAT_ACTIVE);
++			if (pslotinfo->use_adma == 1) {
++				pslotinfo->pre_dma = &ambarella_sd_pre_sg_to_adma;
++				pslotinfo->post_dma = &ambarella_sd_post_sg_to_adma;
++			} else {
++				pslotinfo->pre_dma = &ambarella_sd_pre_sg_to_dma;
++				pslotinfo->post_dma = &ambarella_sd_post_sg_to_dma;
++			}
++		} else {
++			pslotinfo->xfr_reg |= SD_XFR_CTH_SEL;
++			pslotinfo->sta_reg = (SD_STA_READ_XFR_ACTIVE |
++				SD_STA_DAT_ACTIVE);
++			if (pslotinfo->use_adma == 1) {
++				pslotinfo->pre_dma = &ambarella_sd_pre_adma_to_sg;
++				pslotinfo->post_dma = &ambarella_sd_post_adma_to_sg;
++			} else {
++				pslotinfo->pre_dma = &ambarella_sd_pre_dma_to_sg;
++				pslotinfo->post_dma = &ambarella_sd_post_dma_to_sg;
++			}
++		}
++		pslotinfo->pre_dma(pslotinfo);
++		if (pinfo->dma_fix) {
++			pslotinfo->dma_address |= pinfo->dma_fix;
++		}
++	}
++}
++
++static inline void ambarella_sd_send_cmd(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 valid_request, sta_reg, tmpreg, counter = 0;
++	long timeout;
++
++	ambarella_sd_request_bus(pslotinfo->mmc);
++
++	valid_request = ambarella_sd_check_cd(pslotinfo->mmc);
++	ambsd_dbg(pslotinfo, "cmd = %u valid_request = %u.\n",
++		pslotinfo->mrq->cmd->opcode, valid_request);
++	if (!valid_request) {
++		pslotinfo->mrq->cmd->error = -ENOMEDIUM;
++		pslotinfo->state = AMBA_SD_STATE_ERR;
++		goto ambarella_sd_send_cmd_exit;
++	}
++
++	ambarella_sd_check_ios(pslotinfo->mmc, &pslotinfo->mmc->ios);
++	if (pslotinfo->mrq->data) {
++		while (1) {
++			sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
++			if ((sta_reg & SD_STA_CMD_INHIBIT_DAT) == 0) {
++				break;
++			}
++			counter++;
++			if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++				if(pslotinfo->mrq->cmd->opcode != MMC_SEND_TUNING_BLOCK)
++					ambsd_warn(pslotinfo,
++						"Wait SD_STA_CMD_INHIBIT_DAT...\n");
++				pslotinfo->state = AMBA_SD_STATE_ERR;
++				pslotinfo->mrq->data->error = -EILSEQ;
++				pinfo->reset_error = 1;
++				goto ambarella_sd_send_cmd_exit;
++			}
++		}
++
++		amba_writeb(pinfo->regbase + SD_TMO_OFFSET, pslotinfo->tmo);
++		if (pslotinfo->use_adma == 1) {
++			amba_setbitsb(pinfo->regbase + SD_HOST_OFFSET,
++				SD_HOST_ADMA);
++			amba_writel(pinfo->regbase + SD_ADMA_ADDR_OFFSET,
++				pslotinfo->dma_address);
++		} else {
++			amba_clrbitsb(pinfo->regbase + SD_HOST_OFFSET,
++				SD_HOST_ADMA);
++			amba_writel(pinfo->regbase + SD_DMA_ADDR_OFFSET,
++				pslotinfo->dma_address);
++		}
++		amba_write2w(pinfo->regbase + SD_BLK_SZ_OFFSET,
++			pslotinfo->blk_sz, pslotinfo->blk_cnt);
++		amba_writel(pinfo->regbase + SD_ARG_OFFSET, pslotinfo->arg_reg);
++		amba_write2w(pinfo->regbase + SD_XFR_OFFSET,
++			pslotinfo->xfr_reg, pslotinfo->cmd_reg);
++	} else {
++		while (1) {
++			sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
++			if ((sta_reg & SD_STA_CMD_INHIBIT_CMD) == 0) {
++				break;
++			}
++			counter++;
++			if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
++				ambsd_warn(pslotinfo,
++					"Wait SD_STA_CMD_INHIBIT_CMD...\n");
++				pslotinfo->state = AMBA_SD_STATE_ERR;
++				pslotinfo->mrq->cmd->error = -EILSEQ;
++				pinfo->reset_error = 1;
++				goto ambarella_sd_send_cmd_exit;
++			}
++		}
++
++		amba_writel(pinfo->regbase + SD_ARG_OFFSET, pslotinfo->arg_reg);
++		amba_write2w(pinfo->regbase + SD_XFR_OFFSET,
++			0x00, pslotinfo->cmd_reg);
++	}
++
++ambarella_sd_send_cmd_exit:
++	if (pslotinfo->state == AMBA_SD_STATE_CMD) {
++		timeout = wait_event_timeout(pslotinfo->wait,
++			(pslotinfo->state != AMBA_SD_STATE_CMD),
++			pslotinfo->wait_tmo);
++		if (pslotinfo->state == AMBA_SD_STATE_CMD) {
++			ambsd_err(pslotinfo,
++				"cmd%u %u@[%ld:%u], sta=0x%04x\n",
++				pslotinfo->mrq->cmd->opcode,
++				pslotinfo->state, timeout, pslotinfo->wait_tmo,
++				amba_readl(pinfo->regbase + SD_STA_OFFSET));
++			pslotinfo->mrq->cmd->error = -ETIMEDOUT;
++		}
++	} else if (pslotinfo->state == AMBA_SD_STATE_DATA) {
++		do {
++			timeout = wait_event_timeout(pslotinfo->wait,
++				(pslotinfo->state != AMBA_SD_STATE_DATA),
++				pslotinfo->wait_tmo);
++			sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
++			if ((pslotinfo->state == AMBA_SD_STATE_DATA) &&
++				(sta_reg & pslotinfo->sta_reg)) {
++				ambsd_rtdbg(pslotinfo, "data%u %u@"
++					"[%ld:%u:%u:%u], sta=0x%04x:0x%04x\n",
++					pslotinfo->mrq->cmd->opcode,
++					pslotinfo->state, timeout,
++					pslotinfo->wait_tmo,
++					pslotinfo->mrq->data->timeout_ns,
++					pslotinfo->mrq->data->timeout_clks,
++					sta_reg, pslotinfo->sta_reg);
++				ambsd_rtdbg(pslotinfo,
++					"DMA %u in %u sg [0x%08x:0x%08x]\n",
++					pslotinfo->dma_size,
++					pslotinfo->sg_len,
++					pslotinfo->dma_address,
++					pslotinfo->dma_size);
++				tmpreg = amba_readw(pinfo->regbase +
++					SD_BLK_CNT_OFFSET);
++				if (tmpreg) {
++					ambsd_rtdbg(pslotinfo,
++						"SD_DMA_ADDR_OFFSET[0x%08X]\n",
++						amba_readl(pinfo->regbase +
++						SD_DMA_ADDR_OFFSET));
++					amba_writel((pinfo->regbase +
++						SD_DMA_ADDR_OFFSET),
++						amba_readl(pinfo->regbase +
++						SD_DMA_ADDR_OFFSET));
++				} else {
++					ambsd_rtdbg(pslotinfo,
++						"SD_DATA_OFFSET[0x%08X]\n",
++						amba_readl(pinfo->regbase +
++						SD_DATA_OFFSET));
++					ambsd_rtdbg(pslotinfo,
++						"SD_STA_OFFSET[0x%08X]\n",
++						amba_readl(pinfo->regbase +
++						SD_STA_OFFSET));
++				}
++			} else {
++				break;
++			}
++		} while (pslotinfo->sta_counter--);
++		if (pslotinfo->state == AMBA_SD_STATE_DATA) {
++			ambsd_err(pslotinfo,
++				"data%u %u@%u, sta=0x%04x:0x%04x\n",
++				pslotinfo->mrq->cmd->opcode,
++				pslotinfo->state,
++				pslotinfo->wait_tmo,
++				sta_reg, pslotinfo->sta_reg);
++			pslotinfo->mrq->data->error = -ETIMEDOUT;
++		}
++	}
++}
++
++static inline void ambarella_sd_post_cmd(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	if (pslotinfo->state == AMBA_SD_STATE_IDLE) {
++		ambarella_sd_release_bus(pslotinfo->mmc);
++		if (pslotinfo->mrq->data) {
++			pslotinfo->post_dma(pslotinfo);
++		}
++	} else {
++#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
++		u32 counter = 0;
++
++		ambsd_err(pslotinfo, "CMD%u retries[%u] state[%u].\n",
++			pslotinfo->mrq->cmd->opcode,
++			pslotinfo->mrq->cmd->retries,
++			pslotinfo->state);
++		for (counter = 0; counter < 0x100; counter += 4) {
++			ambsd_err(pslotinfo, "0x%04x: 0x%08x\n",
++			counter, amba_readl(pinfo->regbase + counter));
++		}
++		ambarella_sd_show_info(pslotinfo);
++#endif
++		if (pinfo->reset_error) {
++			ambarella_sd_recovery(pslotinfo->mmc);
++			//ambarella_sd_reset_all(pslotinfo->mmc);
++		}
++		ambarella_sd_release_bus(pslotinfo->mmc);
++	}
++}
++
++static void ambarella_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++
++	pslotinfo->mrq = mrq;
++	ambarella_sd_pre_cmd(pslotinfo);
++	ambarella_sd_send_cmd(pslotinfo);
++	ambarella_sd_post_cmd(pslotinfo);
++	pslotinfo->mrq = NULL;
++	mmc_request_done(mmc, mrq);
++}
++
++static int ambarella_sd_get_ro(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	int wpspl;
++
++	ambarella_sd_request_bus(mmc);
++
++	if (pslotinfo->fixed_wp != -1) {
++		wpspl = !!pslotinfo->fixed_wp;
++	} else {
++		wpspl = mmc_gpio_get_ro(mmc);
++		if (wpspl < 0) {
++			wpspl = amba_readl(pinfo->regbase + SD_STA_OFFSET);
++			wpspl &= SD_STA_WPS_PL;
++		}
++	}
++
++	ambarella_sd_release_bus(mmc);
++
++	ambsd_dbg(pslotinfo, "RO[%u].\n", wpspl);
++	return !!wpspl;
++}
++
++static int ambarella_sd_get_cd(struct mmc_host *mmc)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	u32 cdpin;
++
++	ambarella_sd_request_bus(mmc);
++	cdpin = ambarella_sd_check_cd(mmc);
++	ambarella_sd_release_bus(mmc);
++
++	ambsd_dbg(pslotinfo, "CD[%u].\n", cdpin);
++	return cdpin ? 1 : 0;
++}
++
++static void ambarella_sd_enable_sdio_irq(struct mmc_host *mmc, int enable)
++{
++	if (enable)
++		ambarella_sd_enable_int(mmc, SD_NISEN_CARD);
++	else
++		ambarella_sd_disable_int(mmc, SD_NISEN_CARD);
++}
++
++static int ambarella_sd_ssvs(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++	int retval = 0;
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++
++	ambarella_sd_request_bus(mmc);
++	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
++		amba_writeb(pinfo->regbase + SD_PWR_OFFSET,
++			(SD_PWR_ON | SD_PWR_3_3V));
++
++		if (gpio_is_valid(pslotinfo->v18_gpio)) {
++			gpio_set_value_cansleep(pslotinfo->v18_gpio,
++						!pslotinfo->v18_gpio_active);
++			msleep(10);
++		}
++	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
++		ambarella_sd_clear_clken(mmc);
++		msleep(CONFIG_SD_AMBARELLA_VSW_PRE_SPEC);
++		amba_writeb(pinfo->regbase + SD_PWR_OFFSET,
++			(SD_PWR_ON | SD_PWR_1_8V));
++
++		if (gpio_is_valid(pslotinfo->v18_gpio)) {
++			gpio_set_value_cansleep(pslotinfo->v18_gpio,
++						pslotinfo->v18_gpio_active);
++			msleep(pinfo->switch_voltage_tmo);
++		}
++		ambarella_sd_set_clken(mmc);
++	}
++	ambarella_sd_release_bus(mmc);
++
++	return retval;
++}
++
++static int ambarella_sd_card_busy(struct mmc_host *mmc)
++{
++	int retval = 0;
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 sta_reg;
++
++	ambarella_sd_request_bus(mmc);
++	sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
++	ambsd_dbg(pslotinfo, "SD_STA_OFFSET = 0x%08X.\n", sta_reg);
++	retval = !(sta_reg & 0x1F00000);
++	ambarella_sd_release_bus(mmc);
++
++	return retval;
++}
++
++static int ambarella_send_tuning_cmd(struct mmc_host *host, u32 opcode, int *cmd_error)
++{
++	struct mmc_request mrq = {NULL};
++	struct mmc_command cmd = {0};
++	struct mmc_data data = {0};
++	struct scatterlist sg;
++	struct mmc_ios *ios = &host->ios;
++	const u8 *tuning_block_pattern;
++	int size, err = 0;
++	u8 *data_buf;
++
++	if (ios->bus_width == MMC_BUS_WIDTH_8) {
++			tuning_block_pattern = tuning_blk_pattern_8bit;
++			size = sizeof(tuning_blk_pattern_8bit);
++	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
++			tuning_block_pattern = tuning_blk_pattern_4bit;
++			size = sizeof(tuning_blk_pattern_4bit);
++	} else
++			return -EINVAL;
++
++	data_buf = kzalloc(size, GFP_KERNEL);
++	if (!data_buf)
++			return -ENOMEM;
++
++	mrq.cmd = &cmd;
++	mrq.data = &data;
++
++	cmd.opcode = opcode;
++	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
++
++	data.blksz = size;
++	data.blocks = 1;
++	data.flags = MMC_DATA_READ;
++
++	/*
++	 * According to the tuning specs, Tuning process
++	 * is normally shorter 40 executions of CMD19,
++	 * and timeout value should be shorter than 150 ms
++	 */
++	data.timeout_ns = 150 * NSEC_PER_MSEC;
++
++	data.sg = &sg;
++	data.sg_len = 1;
++	sg_init_one(&sg, data_buf, size);
++
++	mmc_wait_for_req(host, &mrq);
++
++	if (cmd_error)
++		*cmd_error = cmd.error;
++
++	if (cmd.error) {
++		err = cmd.error;
++		goto out;
++	}
++
++	if (data.error) {
++		err = data.error;
++		goto out;
++	}
++
++	if (memcmp(data_buf, tuning_block_pattern, size))
++		err = -EIO;
++
++out:
++	kfree(data_buf);
++	return err;
++
++}
++
++static int ambarella_sd_execute_tuning(struct mmc_host *mmc, u32 opcode)
++{
++	struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	u32 tmp, misc, lat, s = -1, e = 0, middle;
++	u32 best_misc = 0, best_s = -1, best_e = 0, doing_retune = 0;
++	int dly, longest_range = 0, range = 0;
++	u32 clock = pinfo->controller_ios.clock;
++
++	if(!pinfo->auto_tuning || !pinfo->timing_reg)
++		return 0;
++
++retry:
++	if (doing_retune) {
++		clock -= 10000000;
++		if (clock <= 50000000) {
++			ambsd_tuning_dbg(pslotinfo,
++				"tuning: can't find any valid timing\n");
++			return -ECANCELED;
++		}
++
++		pinfo->controller_ios.clock = clock;
++		ambarella_sd_set_clk(mmc, &pinfo->controller_ios);
++	}
++
++	if(pinfo->phy_type == 0)
++		goto phy_type_0;
++	else if (pinfo->phy_type == 1)
++		goto phy_type_1;
++	else if (pinfo->phy_type == 2)
++		goto phy_type_2;
++
++phy_type_0:
++	for (misc = 0; misc < 4; misc++) {
++		writel_relaxed(0x8001, pinfo->sbc_reg);
++
++		tmp = readl_relaxed(pinfo->timing_reg);
++		tmp &= 0x0000ffff;
++		tmp |= ((misc >> 1) & 0x1) << 19;
++		writel_relaxed(tmp | (1 << 25), pinfo->timing_reg);
++		usleep_range(5, 10);
++		writel_relaxed(tmp, pinfo->timing_reg);
++		usleep_range(5, 10);
++		lat = ((misc >> 0) & 0x1) + 1;
++		tmp = (lat << 12) | (lat << 8) | (lat << 4) | (lat << 0);
++		writel_relaxed(tmp, pinfo->regbase + SD_LAT_CTRL_OFFSET);
++
++		for (dly = 0; dly < 4; dly++) {
++			tmp = readl_relaxed(pinfo->sbc_reg);
++			tmp &= 0xfffffff9;
++//			tmp |= (((dly >> 6) & 0x3) << 1);
++			tmp |= dly;
++			writel_relaxed(tmp, pinfo->sbc_reg);
++/*
++			sel = dly % 64;
++			if (sel < 0x20)
++				sel = 63 - sel;
++			else
++				sel = sel - 32;
++
++			tmp = (sel << 16) | (sel << 8) | (sel << 0);
++			writel_relaxed(tmp, pinfo->timing_reg + 4);
++*/
++			if (ambarella_send_tuning_cmd(mmc, opcode, NULL) == 0) {
++				/* Tuning is successful at this tuning point */
++				if (s == -1)
++					s = dly;
++				e = dly;
++				range++;
++			} else {
++				if (range > 0) {
++					ambsd_tuning_dbg(pslotinfo,
++						"tuning: misc[0x%x], count[%d](%d - %d)\n",
++						misc, e - s + 1, s, e);
++				}
++
++				if (range > longest_range) {
++					best_misc = misc;
++					best_s = s;
++					best_e = e;
++					longest_range = range;
++				}
++				s = -1;
++				e = range = 0;
++			}
++		}
++
++		/* in case the last timings are all working */
++		if (range > longest_range) {
++			if (range > 0) {
++				ambsd_tuning_dbg(pslotinfo,
++					"tuning last: misc[0x%x], count[%d](%d - %d)\n",
++					misc, e - s + 1, s, e);
++			}
++			best_misc = misc;
++			best_s = s;
++			best_e = e;
++			longest_range = range;
++		}
++		s = -1;
++		e = range = 0;
++	}
++
++	if (longest_range == 0) {
++		if (clock > 50000000) {
++			doing_retune = 1;
++			goto retry;
++		}
++
++		return -EIO;
++	}
++
++	middle = (best_s + best_e) / 2;
++
++//	tmp = (((middle >> 6) & 0x3) << 1) | 0x8001;
++	tmp = (middle << 1) | 0x8001;
++	writel_relaxed(tmp, pinfo->sbc_reg);
++/*
++	sel = middle % 64;
++	if (sel < 0x20)
++			sel = 63 - sel;
++	else
++			sel = sel - 32;
++
++	tmp = (sel << 16) | (sel << 8) | (sel << 0);
++	writel_relaxed(tmp, pinfo->timing_reg + 4);
++*/
++	tmp = readl_relaxed(pinfo->timing_reg);
++	tmp &= 0x0000ffff;
++	tmp |= ((best_misc >> 1) & 0x1) << 19;
++	writel_relaxed(tmp | (1 << 25), pinfo->timing_reg);
++	usleep_range(5, 10);
++	writel_relaxed(tmp, pinfo->timing_reg);
++	usleep_range(5, 10);
++
++	lat = ((best_misc >> 0) & 0x1) + 1;
++	tmp = (lat << 12) | (lat << 8) | (lat << 4) | (lat << 0);
++	writel_relaxed(tmp, pinfo->regbase + SD_LAT_CTRL_OFFSET);
++
++	ambarella_sd_recovery(mmc);
++
++	return 0;
++
++phy_type_1:
++
++	/* misc: 3 bits data out delay
++	 * dly: 2 bits clk mode and 3 bits clk out delay, total 5 bits;
++	 */
++
++	for(misc = 0; misc < 8; misc++) {
++		for(dly = 0; dly < 32; dly++) {
++			tmp = (misc << 9) | (misc << 15) | (misc << 21) | (misc << 27);
++			amba_writel(pinfo->regbase + SD_DELAY_SEL_L, tmp);
++			tmp = ((dly >> 3) << 25) | ((dly & 0x07) << 22) | (misc << 1)
++				| (misc << 7) | (misc << 13) | (misc << 19);
++			amba_writel(pinfo->regbase + SD_DELAY_SEL_H, tmp);
++
++			if (ambarella_send_tuning_cmd(mmc, opcode, NULL) == 0) {
++				/* Tuning is successful at this tuning point */
++				if (s == -1)
++					s = dly;
++				e = dly;
++				range++;
++			} else {
++				if (range > 0) {
++					ambsd_tuning_dbg(pslotinfo,
++						"tuning last: misc[0x%x], count[%d](%d - %d)\n",
++						misc, e - s + 1, s, e);
++				}
++
++				if (range > longest_range) {
++					best_misc = misc;
++					best_s = s;
++					best_e = e;
++					longest_range = range;
++				}
++				s = -1;
++				e = range = 0;
++			}
++		}
++
++		/* in case the last timings are all working */
++		if (range > longest_range) {
++			if (range > 0) {
++				ambsd_tuning_dbg(pslotinfo,
++					"tuning last: misc[0x%x], count[%d](%d - %d)\n",
++					misc, e - s + 1, s, e);
++			}
++			best_misc = misc;
++			best_s = s;
++			best_e = e;
++			longest_range = range;
++		}
++		s = -1;
++		e = range = 0;
++	}
++
++	if (longest_range == 0) {
++		if (clock > 50000000) {
++			doing_retune = 1;
++			goto retry;
++		}
++
++		return -EIO;
++	}
++
++	middle = (best_s + best_e) / 2;
++
++	tmp = (best_misc << 9) | (best_misc << 15) | (best_misc << 21) | (best_misc << 27);
++	amba_writel(pinfo->regbase + SD_DELAY_SEL_L, tmp);
++	tmp = ((middle >> 3) << 25) | ((middle & 0x07) << 22) | (best_misc << 1)
++		| (best_misc << 7) | (best_misc << 13) | (best_misc << 19);
++	amba_writel(pinfo->regbase + SD_DELAY_SEL_H, tmp);
++
++	ambarella_sd_recovery(mmc);
++
++	return 0;
++
++phy_type_2:
++
++	/* misc: 5 bits out clock delay
++	 * dly: 2 bits out data delay and 3 bits input data delay, total 5 bits;
++	 */
++
++	/*This is only used for s2e sdio slot*/
++	lat = amba_readl(pinfo->timing_reg);
++	lat &= ~0xC3E0E000;
++
++	for(misc = 0; misc < 32; misc++) {
++		for(dly = 0; dly < 32; dly++) {
++			tmp = lat | ((dly >> 3) << 30) | ((dly & 0x07) << 13) | (misc << 21);
++			amba_writel(pinfo->timing_reg, tmp);
++			if (ambarella_send_tuning_cmd(mmc, opcode, NULL) == 0) {
++				/* Tuning is successful at this tuning point */
++				if (s == -1)
++					s = dly;
++				e = dly;
++				range++;
++			} else {
++				if (range > 0) {
++					ambsd_tuning_dbg(pslotinfo,
++						"tuning last: misc[0x%x], count[%d](%d - %d)\n",
++						misc, e - s + 1, s, e);
++				}
++
++				if (range > longest_range) {
++					best_misc = misc;
++					best_s = s;
++					best_e = e;
++					longest_range = range;
++				}
++				s = -1;
++				e = range = 0;
++			}
++		}
++
++		/* in case the last timings are all working */
++		if (range > longest_range) {
++			if (range > 0) {
++				ambsd_tuning_dbg(pslotinfo,
++					"tuning last: misc[0x%x], count[%d](%d - %d)\n",
++					misc, e - s + 1, s, e);
++			}
++			best_misc = misc;
++			best_s = s;
++			best_e = e;
++			longest_range = range;
++		}
++		s = -1;
++		e = range = 0;
++	}
++
++	if (longest_range == 0) {
++		if (clock > 50000000) {
++			doing_retune = 1;
++			goto retry;
++		}
++
++		return -EIO;
++	}
++
++	middle = (best_s + best_e) / 2;
++	tmp = lat | ((middle >> 3) << 30) | ((middle & 0x07) << 13) | (best_misc << 21);
++	amba_writel(pinfo->timing_reg, tmp);
++
++	ambarella_sd_recovery(mmc);
++
++	return 0;
++}
++
++static const struct mmc_host_ops ambarella_sd_host_ops = {
++	.request = ambarella_sd_request,
++	.set_ios = ambarella_sd_ios,
++	.get_ro = ambarella_sd_get_ro,
++	.get_cd = ambarella_sd_get_cd,
++	.enable_sdio_irq = ambarella_sd_enable_sdio_irq,
++	.start_signal_voltage_switch = ambarella_sd_ssvs,
++	.card_busy = ambarella_sd_card_busy,
++	.execute_tuning =  ambarella_sd_execute_tuning,
++};
++
++static int ambarella_sd_system_event(struct notifier_block *nb,
++	unsigned long val, void *data)
++{
++	struct ambarella_sd_mmc_info *pslotinfo;
++	struct ambarella_sd_controller_info *pinfo;
++
++	pslotinfo = container_of(nb, struct ambarella_sd_mmc_info, system_event);
++	pinfo = (struct ambarella_sd_controller_info *)pslotinfo->pinfo;
++
++	switch (val) {
++	case AMBA_EVENT_PRE_CPUFREQ:
++		pr_debug("%s[%u]: Pre Change\n", __func__, pslotinfo->slot_id);
++		down(&pslotinfo->system_event_sem);
++		break;
++
++	case AMBA_EVENT_POST_CPUFREQ:
++		pr_debug("%s[%u]: Post Change\n", __func__, pslotinfo->slot_id);
++		ambarella_sd_set_clk(pslotinfo->mmc, &pinfo->controller_ios);
++		up(&pslotinfo->system_event_sem);
++		break;
++
++	default:
++		break;
++	}
++
++	return NOTIFY_OK;
++}
++
++static irqreturn_t ambarella_sd_irq(int irq, void *devid)
++{
++	struct ambarella_sd_controller_info *pinfo = devid;
++	struct ambarella_sd_mmc_info *pslotinfo = NULL;
++	u16 nis, eis, slot_id;
++
++	/* Read and clear the interrupt registers */
++	amba_read2w(pinfo->regbase + SD_NIS_OFFSET, &nis, &eis);
++	amba_write2w(pinfo->regbase + SD_NIS_OFFSET, nis, eis);
++
++	if (pinfo->slot_num > 1) {
++		u32 fio_ctrl = amba_readl(pinfo->fio_reg + FIO_CTR_OFFSET);
++		slot_id = (fio_ctrl & FIO_CTR_XD) ? 1 : 0;
++	} else
++		slot_id = 0;
++
++	pslotinfo = pinfo->pslotinfo[slot_id];
++
++	ambsd_dbg(pslotinfo, "%s nis = 0x%x, eis = 0x%x & %u\n",
++				__func__, nis, eis, pslotinfo->state);
++
++	if (nis & SD_NIS_CARD) {
++		ambsd_dbg(pslotinfo, "SD_NIS_CARD\n");
++		mmc_signal_sdio_irq(pslotinfo->mmc);
++	}
++
++	if(pslotinfo->fixed_cd == -1) {
++		if (nis & SD_NIS_REMOVAL) {
++			ambsd_dbg(pslotinfo, "SD_NIS_REMOVAL\n");
++			mmc_detect_change(pslotinfo->mmc, msecs_to_jiffies(1000));
++		} else if (nis & SD_NIS_INSERT) {
++			ambsd_dbg(pslotinfo, "SD_NIS_INSERT\n");
++			mmc_detect_change(pslotinfo->mmc, msecs_to_jiffies(1000));
++		}
++	}
++
++	if (eis) {
++		if (eis & (SD_EIS_CMD_TMOUT_ERR | SD_EIS_CMD_CRC_ERR |
++			SD_EIS_CMD_BIT_ERR | SD_EIS_CMD_IDX_ERR |
++			SD_EIS_ACMD12_ERR)) {
++			ambarella_sd_reset_cmd_line(pslotinfo->mmc);
++		}
++		if (eis & (SD_EIS_DATA_TMOUT_ERR | SD_EIS_DATA_CRC_ERR)) {
++			ambarella_sd_reset_data_line(pslotinfo->mmc);
++		}
++		if (eis & (SD_EIS_DATA_BIT_ERR | SD_EIS_CURRENT_ERR)) {
++			//ambarella_sd_reset_all(pslotinfo->mmc);
++			ambarella_sd_recovery(pslotinfo->mmc);
++		}
++		if (pslotinfo->state == AMBA_SD_STATE_CMD) {
++			ambarella_sd_cmd_done(pslotinfo, nis, eis);
++		} else if (pslotinfo->state == AMBA_SD_STATE_DATA) {
++			ambarella_sd_data_done(pslotinfo, nis, eis);
++		}
++	} else {
++		if (nis & SD_NIS_CMD_DONE) {
++			ambarella_sd_cmd_done(pslotinfo, nis, eis);
++		}
++		if (nis & SD_NIS_XFR_DONE) {
++			ambarella_sd_data_done(pslotinfo, nis, eis);
++		}
++#if 0
++		if (nis & SD_NIS_DMA) {
++			amba_writel(pinfo->regbase + SD_DMA_ADDR_OFFSET,
++			amba_readl(pinfo->regbase + SD_DMA_ADDR_OFFSET));
++		}
++#endif
++	}
++
++	return IRQ_HANDLED;
++}
++
++
++/* ==========================================================================*/
++
++static int ambarella_sd_init_slot(struct device_node *np, int id,
++			struct ambarella_sd_controller_info *pinfo)
++{
++	struct device_node *save_np;
++	struct ambarella_sd_mmc_info *pslotinfo = NULL;
++	struct mmc_host *mmc;
++	enum of_gpio_flags flags;
++	u32 gpio_init_flag, hc_cap, hc_timeout_clk;
++	int global_id, retval = 0;
++
++	mmc = mmc_alloc_host(sizeof(*pslotinfo), pinfo->dev);
++	if (!mmc) {
++		dev_err(pinfo->dev, "Failed to alloc mmc host %u!\n", id);
++		return -ENOMEM;
++	}
++	pslotinfo = mmc_priv(mmc);
++	pslotinfo->mmc = mmc;
++
++	/* in order to use mmc_of_parse(), we reassign the parent
++	 * of_node, this should be a workaroud. */
++	save_np = mmc->parent->of_node;
++	mmc->parent->of_node = np;
++	mmc_of_parse(mmc);
++	mmc->parent->of_node = save_np;
++
++	/* our own extra property */
++	if (of_property_read_u32(np, "amb,fixed-wp", &pslotinfo->fixed_wp) < 0)
++		pslotinfo->fixed_wp = -1;
++	if (of_property_read_u32(np, "amb,fixed-cd", &pslotinfo->fixed_cd) < 0)
++		pslotinfo->fixed_cd = -1;
++	pslotinfo->no_1_8_v = !!of_find_property(np, "no-1-8-v", NULL);
++	pslotinfo->caps_ddr = !!of_find_property(np, "amb,caps-ddr", NULL);
++	pslotinfo->caps_adma = !!of_find_property(np, "amb,caps-adma", NULL);
++	pslotinfo->force_gpio = !!of_find_property(np, "amb,force-gpio", NULL);
++	if (pslotinfo->force_gpio) {
++		pslotinfo->pinctrl = devm_pinctrl_get(pinfo->dev);
++		if (IS_ERR(pslotinfo->pinctrl)) {
++			retval = PTR_ERR(pslotinfo->pinctrl);
++			dev_err(pinfo->dev, "Can't get pinctrl: %d\n", retval);
++			goto init_slot_err1;
++		}
++
++		pslotinfo->state_work =
++			pinctrl_lookup_state(pslotinfo->pinctrl, "work");
++		if (IS_ERR(pslotinfo->state_work)) {
++			retval = PTR_ERR(pslotinfo->state_work);
++			dev_err(pinfo->dev, "Can't get pinctrl state: work\n");
++			goto init_slot_err1;
++		}
++
++		pslotinfo->state_idle =
++			pinctrl_lookup_state(pslotinfo->pinctrl, "idle");
++		if (IS_ERR(pslotinfo->state_idle)) {
++			retval = PTR_ERR(pslotinfo->state_idle);
++			dev_err(pinfo->dev, "Can't get pinctrl state: idle\n");
++			goto init_slot_err1;
++		}
++	}
++
++	/* request gpio for external power control */
++	pslotinfo->pwr_gpio = of_get_named_gpio_flags(np, "pwr-gpios", 0, &flags);
++	pslotinfo->pwr_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	if (gpio_is_valid(pslotinfo->pwr_gpio)) {
++		if (pslotinfo->pwr_gpio_active)
++			gpio_init_flag = GPIOF_OUT_INIT_LOW;
++		else
++			gpio_init_flag = GPIOF_OUT_INIT_HIGH;
++
++		retval = devm_gpio_request_one(pinfo->dev, pslotinfo->pwr_gpio,
++					gpio_init_flag, "sd ext power");
++		if (retval < 0) {
++			dev_err(pinfo->dev, "Failed to request pwr-gpios!\n");
++			goto init_slot_err1;
++		}
++	}
++
++	/* request gpio for 3.3v/1.8v switch */
++	pslotinfo->v18_gpio = of_get_named_gpio_flags(np, "v18-gpios", 0, &flags);
++	pslotinfo->v18_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	if (gpio_is_valid(pslotinfo->v18_gpio)) {
++		if (pslotinfo->v18_gpio_active)
++			gpio_init_flag = GPIOF_OUT_INIT_LOW;
++		else
++			gpio_init_flag = GPIOF_OUT_INIT_HIGH;
++
++		retval = devm_gpio_request_one(pinfo->dev, pslotinfo->v18_gpio,
++				gpio_init_flag, "sd ext power");
++		if (retval < 0) {
++			dev_err(pinfo->dev, "Failed to request v18-gpios!\n");
++			goto init_slot_err1;
++		}
++	}
++
++	mmc->f_min = mmc->f_max >> 8;
++	mmc->ops = &ambarella_sd_host_ops;
++
++	init_waitqueue_head(&pslotinfo->wait);
++	pslotinfo->state = AMBA_SD_STATE_ERR;
++	pslotinfo->slot_id = id;
++	pslotinfo->pinfo = pinfo;
++	pinfo->pslotinfo[id] = pslotinfo;
++	sema_init(&pslotinfo->system_event_sem, 1);
++
++	ambarella_sd_request_bus(mmc);
++
++	ambarella_sd_reset_all(mmc);
++
++	hc_cap = amba_readl(pinfo->regbase + SD_CAP_OFFSET);
++
++	dev_dbg(pinfo->dev,
++		"SD Clock: base[%uMHz], min[%uHz], max[%uHz].\n",
++		SD_CAP_BASE_FREQ(hc_cap), mmc->f_min, mmc->f_max);
++
++	hc_timeout_clk = mmc->f_max / 1000;
++	if (hc_timeout_clk == 0)
++		hc_timeout_clk = 24000;
++
++	mmc->max_discard_to = (1 << 27) / hc_timeout_clk;
++
++	if (hc_cap & SD_CAP_MAX_2KB_BLK)
++		mmc->max_blk_size = 2048;
++	else if (hc_cap & SD_CAP_MAX_1KB_BLK)
++		mmc->max_blk_size = 1024;
++	else if (hc_cap & SD_CAP_MAX_512B_BLK)
++		mmc->max_blk_size = 512;
++
++	dev_dbg(pinfo->dev, "SD max_blk_size: %u.\n", mmc->max_blk_size);
++
++	mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
++			MMC_CAP_ERASE | MMC_CAP_BUS_WIDTH_TEST;
++
++	mmc->caps2 |= MMC_CAP2_HS200 | MMC_CAP2_HS200_1_8V_SDR;
++
++	if (mmc->f_max > 25000000) {
++		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
++		mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
++	}
++
++	if (!(hc_cap & SD_CAP_DMA)) {
++		ambsd_err(pslotinfo, "HW do not support DMA!\n");
++		retval = -ENODEV;
++		goto init_slot_err1;
++	}
++
++	if (hc_cap & SD_CAP_ADMA_SUPPORT) {
++		dev_dbg(pinfo->dev, "HW support ADMA!\n");
++		pslotinfo->use_adma = pslotinfo->caps_adma ? 1 : 0;
++	}
++
++	dev_dbg(pinfo->dev, "HW%s support Suspend/Resume!\n",
++			(hc_cap & SD_CAP_SUS_RES) ? "" : " do not");
++
++	mmc->ocr_avail = 0;
++	if (hc_cap & SD_CAP_VOL_3_3V)
++		mmc->ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
++
++	if ((hc_cap & SD_CAP_VOL_1_8V) && !pslotinfo->no_1_8_v) {
++		mmc->ocr_avail |= MMC_VDD_165_195;
++		if (hc_cap & SD_CAP_HIGH_SPEED)
++			mmc->caps |= MMC_CAP_1_8V_DDR;
++
++		mmc->caps |= MMC_CAP_UHS_SDR12;
++		if (mmc->f_max > 25000000) {
++			mmc->caps |= MMC_CAP_UHS_SDR25;
++			if (pslotinfo->caps_ddr)
++				mmc->caps |= MMC_CAP_UHS_DDR50;
++		}
++
++		if (mmc->f_max > 50000000)
++			mmc->caps |= MMC_CAP_UHS_SDR50;
++
++		if (mmc->f_max > 100000000)
++			mmc->caps |= MMC_CAP_UHS_SDR104;
++	}
++
++	if (mmc->ocr_avail == 0) {
++		ambsd_err(pslotinfo, "HW report wrong voltages[0x%x]!\n", hc_cap);
++		retval = -ENODEV;
++		goto init_slot_err1;
++	}
++
++	if (!(hc_cap & SD_CAP_INTMODE)) {
++		ambsd_err(pslotinfo, "HW do not support Interrupt mode!\n");
++		retval = -ENODEV;
++		goto init_slot_err1;
++	}
++
++	dev_dbg(pinfo->dev, "SD caps: 0x%x.\n", mmc->caps);
++	dev_dbg(pinfo->dev, "SD ocr: 0x%x.\n", mmc->ocr_avail);
++
++	mmc->max_blk_count = 0xFFFF;
++	mmc->max_seg_size = pinfo->max_blk_sz;
++	mmc->max_segs = mmc->max_seg_size / PAGE_SIZE;
++	mmc->max_req_size =
++		min(mmc->max_seg_size, mmc->max_blk_size * mmc->max_blk_count);
++
++	pslotinfo->buf_vaddress = kmem_cache_alloc(pinfo->buf_cache, GFP_KERNEL);
++	if (!pslotinfo->buf_vaddress) {
++		ambsd_err(pslotinfo, "Can't alloc DMA memory");
++		retval = -ENOMEM;
++		goto init_slot_err1;
++	}
++	pslotinfo->buf_paddress = dma_map_single(pinfo->dev,
++					pslotinfo->buf_vaddress,
++					mmc->max_req_size,
++					DMA_BIDIRECTIONAL);
++	ambarella_sd_check_dma_boundary(pslotinfo->buf_paddress,
++				mmc->max_req_size, pinfo->max_blk_sz);
++
++	dev_notice(pinfo->dev, "Slot%u use bounce buffer[0x%p<->0x%08x]\n",
++		pslotinfo->slot_id, pslotinfo->buf_vaddress,
++		pslotinfo->buf_paddress);
++
++	dev_notice(pinfo->dev, "Slot%u req_size=0x%08X, "
++		"segs=%u, seg_size=0x%08X\n",
++		pslotinfo->slot_id, mmc->max_req_size,
++		mmc->max_segs, mmc->max_seg_size);
++
++	dev_notice(pinfo->dev, "Slot%u use %sDMA\n", pslotinfo->slot_id,
++		pslotinfo->use_adma ? "A" :"");
++
++	ambarella_sd_release_bus(mmc);
++
++	retval = mmc_add_host(pslotinfo->mmc);
++	if (retval < 0) {
++		ambsd_err(pslotinfo, "Can't add mmc host!\n");
++		goto init_slot_err2;
++	}
++
++	ambarella_sd_add_debugfs(pslotinfo);
++
++	pslotinfo->system_event.notifier_call = ambarella_sd_system_event;
++	ambarella_register_event_notifier(&pslotinfo->system_event);
++
++	retval = of_property_read_u32(np, "global-id", &global_id);
++	if (retval < 0 || global_id >= SD_INSTANCES * AMBA_SD_MAX_SLOT_NUM)
++		global_id = 0;
++	G_mmc[global_id] = mmc;
++
++	return 0;
++
++init_slot_err2:
++	dma_unmap_single(pinfo->dev, pslotinfo->buf_paddress,
++			pslotinfo->mmc->max_req_size, DMA_BIDIRECTIONAL);
++	kmem_cache_free(pinfo->buf_cache, pslotinfo->buf_vaddress);
++
++init_slot_err1:
++	mmc_free_host(mmc);
++	return retval;
++}
++
++static int ambarella_sd_free_slot(struct ambarella_sd_mmc_info *pslotinfo)
++{
++	struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
++	int retval = 0;
++
++	ambarella_unregister_event_notifier(&pslotinfo->system_event);
++
++	ambarella_sd_remove_debugfs(pslotinfo);
++
++	mmc_remove_host(pslotinfo->mmc);
++
++	if (pslotinfo->buf_paddress) {
++		dma_unmap_single(pinfo->dev, pslotinfo->buf_paddress,
++			pslotinfo->mmc->max_req_size, DMA_BIDIRECTIONAL);
++		pslotinfo->buf_paddress = (dma_addr_t)NULL;
++	}
++
++	if (pslotinfo->buf_vaddress) {
++		kmem_cache_free(pinfo->buf_cache, pslotinfo->buf_vaddress);
++		pslotinfo->buf_vaddress = NULL;
++	}
++
++	mmc_free_host(pslotinfo->mmc);
++
++	return retval;
++}
++
++static int ambarella_sd_of_parse(struct ambarella_sd_controller_info *pinfo)
++{
++	struct device_node *np = pinfo->dev->of_node;
++	const __be32 *prop;
++	const char *clk_name;
++	int psize, tmo, switch_vol_tmo, retval = 0;
++
++	retval = of_property_read_string(np, "amb,clk-name", &clk_name);
++	if (retval < 0) {
++		dev_err(pinfo->dev, "Get pll-name failed! %d\n", retval);
++		goto pasre_err;
++	}
++
++	pinfo->clk = clk_get(NULL, clk_name);
++	if (IS_ERR(pinfo->clk)) {
++		dev_err(pinfo->dev, "Get PLL failed!\n");
++		retval = PTR_ERR(pinfo->clk);
++		goto pasre_err;
++	}
++
++	if (of_find_property(np, "amb,dma-addr-fix", NULL))
++		pinfo->dma_fix = 0xc0000000;
++
++	retval = of_property_read_u32(np, "amb,wait-tmo", &tmo);
++	if (retval < 0)
++		tmo = 0x10000;
++
++	pinfo->default_wait_tmo = msecs_to_jiffies(tmo);
++
++	if (pinfo->default_wait_tmo < CONFIG_SD_AMBARELLA_WAIT_TIMEOUT)
++		pinfo->default_wait_tmo = CONFIG_SD_AMBARELLA_WAIT_TIMEOUT;
++
++	retval = of_property_read_u32(np, "amb,switch-vol-tmo", &switch_vol_tmo);
++	if (retval < 0)
++		switch_vol_tmo = 100;
++
++	pinfo->switch_voltage_tmo = switch_vol_tmo;
++
++	retval = of_property_read_u32(np, "amb,max-blk-size", &pinfo->max_blk_sz);
++	if (retval < 0)
++		pinfo->max_blk_sz = 0x20000;
++
++	pinfo->auto_tuning = !!of_find_property(np, "amb,auto-tuning", NULL);
++	retval = of_property_read_u32(np, "amb,phy-type", &pinfo->phy_type);
++	if(retval) {
++		/*this controller don't support sd phy*/
++		pinfo->phy_type = -1;
++		retval = 0;
++	} else {
++		/* amb,phy-timing must be provided when timing_reg is given */
++		prop = of_get_property(np, "amb,phy-timing", &psize);
++		if (!prop) {
++			retval = -EINVAL;
++			goto pasre_err;
++		}
++
++		psize /= sizeof(u32);
++		BUG_ON(psize % 3);
++		pinfo->phy_timing_num = psize / 3;
++		pinfo->phy_timing = devm_kzalloc(pinfo->dev, psize, GFP_KERNEL);
++		if (pinfo->phy_timing == NULL) {
++			retval = -ENOMEM;
++			goto pasre_err;
++		}
++
++		retval = of_property_read_u32_array(np, "amb,phy-timing",
++				(u32 *)pinfo->phy_timing, psize);
++
++		/* bit0 of mode must be set, and the phy setting in first row with
++		 * bit0 set is the default one. */
++		BUG_ON(!(pinfo->phy_timing[0].mode & 0x1));
++	}
++
++pasre_err:
++	return retval;
++}
++
++static int ambarella_sd_get_resource(struct platform_device *pdev,
++			struct ambarella_sd_controller_info *pinfo)
++{
++	struct resource *mem;
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get SD/MMC mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	pinfo->regbase = devm_ioremap(&pdev->dev,
++					mem->start, resource_size(mem));
++	if (pinfo->regbase == NULL) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get FIO mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	pinfo->fio_reg = devm_ioremap(&pdev->dev,
++					mem->start, resource_size(mem));
++	if (pinfo->fio_reg == NULL) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 2);
++	if (mem == NULL) {
++		pinfo->timing_reg = NULL;
++		pinfo->auto_tuning = false;
++	} else {
++		pinfo->timing_reg = devm_ioremap(&pdev->dev,
++					mem->start, resource_size(mem));
++		if (pinfo->timing_reg == NULL) {
++			dev_err(&pdev->dev, "devm_ioremap() failed\n");
++			return -ENOMEM;
++		}
++	}
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 3);
++	if (mem == NULL) {
++			pinfo->sbc_reg = pinfo->timing_reg;
++	} else {
++			pinfo->sbc_reg = devm_ioremap(&pdev->dev,
++									mem->start, resource_size(mem));
++			if (pinfo->sbc_reg == NULL) {
++					dev_err(&pdev->dev, "devm_ioremap() failed for sbc_reg\n");
++					return -ENOMEM;
++			}
++	}
++
++	pinfo->irq = platform_get_irq(pdev, 0);
++	if (pinfo->irq < 0) {
++		dev_err(&pdev->dev, "Get SD/MMC irq resource failed!\n");
++		return -ENXIO;
++	}
++
++	return 0;
++}
++
++static int ambarella_sd_probe(struct platform_device *pdev)
++{
++	struct ambarella_sd_controller_info *pinfo;
++	struct device_node *slot_np;
++	int retval, i, slot_id = -1;
++
++	pinfo = devm_kzalloc(&pdev->dev, sizeof(*pinfo), GFP_KERNEL);
++	if (pinfo == NULL) {
++		dev_err(&pdev->dev, "Out of memory!\n");
++		return -ENOMEM;
++	}
++	pinfo->dev = &pdev->dev;
++
++	retval = ambarella_sd_get_resource(pdev, pinfo);
++	if (retval < 0)
++		return retval;
++
++	retval = ambarella_sd_of_parse(pinfo);
++	if (retval < 0)
++		return retval;
++
++	pinfo->buf_cache = kmem_cache_create(dev_name(&pdev->dev),
++				pinfo->max_blk_sz, pinfo->max_blk_sz, 0, NULL);
++	if (!pinfo->buf_cache) {
++		dev_err(&pdev->dev, "Can't alloc DMA Cache");
++		return -ENOMEM;
++	}
++
++	pinfo->slot_num = 0;
++	for_each_child_of_node(pdev->dev.of_node, slot_np) {
++		if (!slot_np->name || of_node_cmp(slot_np->name, "slot"))
++			continue;
++
++		retval = of_property_read_u32(slot_np, "reg", &slot_id);
++		if (retval < 0 || slot_id >= AMBA_SD_MAX_SLOT_NUM)
++			goto ambarella_sd_probe_free_host;
++
++		retval = ambarella_sd_init_slot(slot_np, slot_id, pinfo);
++		if (retval < 0)
++			goto ambarella_sd_probe_free_host;
++
++		pinfo->slot_num++;
++	}
++
++	platform_set_drvdata(pdev, pinfo);
++
++	retval = devm_request_irq(&pdev->dev, pinfo->irq, ambarella_sd_irq,
++				IRQF_SHARED | IRQF_TRIGGER_HIGH,
++				dev_name(&pdev->dev), pinfo);
++	if (retval < 0) {
++		dev_err(&pdev->dev, "Can't Request IRQ%u!\n", pinfo->irq);
++		goto ambarella_sd_probe_free_host;
++	}
++
++	dev_info(&pdev->dev, "%u slots @ %luHz\n",
++			pinfo->slot_num, clk_get_rate(pinfo->clk));
++
++	return 0;
++
++ambarella_sd_probe_free_host:
++	for (i = pinfo->slot_num - 1; i >= 0; i--)
++		ambarella_sd_free_slot(pinfo->pslotinfo[i]);
++
++	if (pinfo->buf_cache) {
++		kmem_cache_destroy(pinfo->buf_cache);
++		pinfo->buf_cache = NULL;
++	}
++
++	return retval;
++}
++
++static int ambarella_sd_remove(struct platform_device *pdev)
++{
++	struct ambarella_sd_controller_info *pinfo;
++	int retval = 0, i;
++
++	pinfo = platform_get_drvdata(pdev);
++
++	for (i = 0; i < pinfo->slot_num; i++)
++		ambarella_sd_free_slot(pinfo->pslotinfo[i]);
++
++	if (pinfo->buf_cache)
++		kmem_cache_destroy(pinfo->buf_cache);
++
++	dev_notice(&pdev->dev,
++		"Remove Ambarella Media Processor SD/MMC Host Controller.\n");
++
++	return retval;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_sd_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	struct ambarella_sd_controller_info *pinfo;
++	struct ambarella_sd_mmc_info *pslotinfo;
++
++	int retval = 0, i;
++
++	pinfo = platform_get_drvdata(pdev);
++
++	for (i = 0; i < pinfo->slot_num; i++) {
++		pslotinfo = pinfo->pslotinfo[i];
++
++		if (pslotinfo->mmc) {
++			if (pslotinfo->mmc->pm_caps & MMC_PM_KEEP_POWER) {
++				pslotinfo->mmc->pm_flags = MMC_PM_KEEP_POWER;
++			}
++			retval = mmc_suspend_host(pslotinfo->mmc);
++			if (retval) {
++				ambsd_err(pslotinfo,
++					"mmc_suspend_host[%d] failed[%d]!\n", i, retval);
++				return retval;
++			}
++		}
++		if (pslotinfo->mmc->pm_caps & MMC_PM_KEEP_POWER) {
++			ambarella_sd_disable_int(pslotinfo->mmc, SD_NISEN_CARD);
++			pslotinfo->sd_nisen = amba_readw(pinfo->regbase + SD_NISEN_OFFSET);
++			pslotinfo->sd_eisen = amba_readw(pinfo->regbase + SD_EISEN_OFFSET);
++			pslotinfo->sd_nixen = amba_readw(pinfo->regbase + SD_NIXEN_OFFSET);
++			pslotinfo->sd_eixen = amba_readw(pinfo->regbase + SD_EIXEN_OFFSET);
++		}
++	}
++
++	disable_irq(pinfo->irq);
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n", __func__,
++				retval, state.event);
++
++	return retval;
++
++}
++
++static int ambarella_sd_resume(struct platform_device *pdev)
++{
++	struct ambarella_sd_controller_info *pinfo;
++	struct ambarella_sd_mmc_info *pslotinfo;
++	int retval = 0, i;
++
++	pinfo = platform_get_drvdata(pdev);
++
++	enable_irq(pinfo->irq);
++
++	for (i = 0; i < pinfo->slot_num; i++) {
++		pslotinfo = pinfo->pslotinfo[i];
++		if (gpio_is_valid(pslotinfo->pwr_gpio)){
++			gpio_direction_output(pslotinfo->pwr_gpio, pslotinfo->pwr_gpio_active);
++		}
++		if (pslotinfo->mmc->pm_caps & MMC_PM_KEEP_POWER) {
++			amba_writew(pinfo->regbase + SD_NISEN_OFFSET, pslotinfo->sd_nisen);
++			amba_writew(pinfo->regbase + SD_EISEN_OFFSET, pslotinfo->sd_eisen);
++			amba_writew(pinfo->regbase + SD_NIXEN_OFFSET, pslotinfo->sd_nixen);
++			amba_writew(pinfo->regbase + SD_EIXEN_OFFSET, pslotinfo->sd_eixen);
++			pslotinfo->mmc->caps |= MMC_CAP_NONREMOVABLE;
++			mdelay(10);
++			ambarella_sd_set_clk(pslotinfo->mmc, &pinfo->controller_ios);
++			ambarella_sd_set_bus(pslotinfo->mmc, &pinfo->controller_ios);
++			mdelay(10);
++			ambarella_sd_enable_int(pslotinfo->mmc, SD_NISEN_CARD);
++		} else {
++			clk_set_rate(pinfo->clk, pslotinfo->mmc->f_max);
++			ambarella_sd_reset_all(pslotinfo->mmc);
++		}
++	}
++
++	for (i = 0; i < pinfo->slot_num; i++) {
++		pslotinfo = pinfo->pslotinfo[i];
++		if (pslotinfo->mmc) {
++			retval = mmc_resume_host(pslotinfo->mmc);
++			if (retval) {
++				ambsd_err(pslotinfo,
++				"mmc_resume_host[%d] failed[%d]!\n", i, retval);
++			}
++		}
++	}
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, retval);
++
++	return retval;
++}
++#endif
++
++#ifdef CONFIG_AMBARELLA_EMMC_BOOT
++void ambarella_sd_shutdown (struct platform_device *pdev)
++{
++	struct ambarella_sd_controller_info *pinfo;
++	struct ambarella_sd_mmc_info *pslotinfo;
++	struct mmc_host *host;
++	struct mmc_command cmd = {0};
++	int i;
++
++	pinfo = platform_get_drvdata(pdev);
++
++	for (i = 0; i < pinfo->slot_num; i++) {
++		pslotinfo = pinfo->pslotinfo[i];
++		host = pslotinfo->mmc;
++		if((host == G_mmc[0]) && ((system_state == SYSTEM_RESTART) ||
++			(system_state == SYSTEM_HALT))) {
++			if (mmc_try_claim_host(pslotinfo->mmc)) {
++				cmd.opcode = 0;
++				cmd.arg = 0xf0f0f0f0;
++				cmd.flags = MMC_RSP_NONE;
++
++				mmc_wait_for_cmd(pslotinfo->mmc, &cmd, 0);
++			} else {
++				dev_err(&pdev->dev, "Unable to claim host!\n");
++			}
++		}
++	}
++
++}
++#endif
++
++static const struct of_device_id ambarella_mmc_dt_ids[] = {
++	{ .compatible = "ambarella,sdmmc", },
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ambarella_mmc_dt_ids);
++
++static struct platform_driver ambarella_sd_driver = {
++	.probe		= ambarella_sd_probe,
++	.remove		= ambarella_sd_remove,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_sd_suspend,
++	.resume		= ambarella_sd_resume,
++#endif
++
++#ifdef CONFIG_AMBARELLA_EMMC_BOOT
++	.shutdown	= ambarella_sd_shutdown,
++#endif
++	.driver		= {
++		.name	= "ambarella-sd",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_mmc_dt_ids,
++	},
++};
++
++static int __init ambarella_sd_init(void)
++{
++	int retval = 0;
++
++	retval = platform_driver_register(&ambarella_sd_driver);
++	if (retval) {
++		printk(KERN_ERR "%s: Register failed %d!\n",
++			__func__, retval);
++	}
++
++	return retval;
++}
++
++static void __exit ambarella_sd_exit(void)
++{
++	platform_driver_unregister(&ambarella_sd_driver);
++}
++
++fs_initcall(ambarella_sd_init);
++module_exit(ambarella_sd_exit);
++
++MODULE_DESCRIPTION("Ambarella Media Processor SD/MMC Host Controller");
++MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
+index 5fab4e6e..14cb18d4 100644
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -197,6 +197,17 @@ config MTD_BLOCK_RO
+ 	  You do not need this option for use with the DiskOnChip devices. For
+ 	  those, enable NFTL support (CONFIG_NFTL) instead.
+ 
++config MTD_BLOCK_AMBRO
++	tristate "Ambarella Readonly block device access to MTD devices"
++	depends on MTD_BLOCK!=y && MTD_BLOCK_RO!=y && MTD_UBI_GLUEBI!=y && BLOCK
++	select MTD_BLKDEVS
++	help
++	  This allows you to mount read-only file systems (such as cramfs/squashfs)
++	  from an MTD device, without the overhead (and danger) of the caching
++	  driver, but with the bad block skipped.
++
++	  Note: This is mutually exclusive with UBI gluebi.
++
+ config FTL
+ 	tristate "FTL (Flash Translation Layer) support"
+ 	depends on BLOCK
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index 4cfb31e6..28471dc3 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
+ obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
+ obj-$(CONFIG_MTD_BLOCK)		+= mtdblock.o
+ obj-$(CONFIG_MTD_BLOCK_RO)	+= mtdblock_ro.o
++obj-$(CONFIG_MTD_BLOCK_AMBRO)	+= mtdblock_ambro.o
+ obj-$(CONFIG_FTL)		+= ftl.o
+ obj-$(CONFIG_NFTL)		+= nftl.o
+ obj-$(CONFIG_INFTL)		+= inftl.o
+diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
+index 2a4d55e4..53ee819e 100644
+--- a/drivers/mtd/devices/Kconfig
++++ b/drivers/mtd/devices/Kconfig
+@@ -2,6 +2,11 @@ menu "Self-contained MTD device drivers"
+ 	depends on MTD!=n
+ 	depends on HAS_IOMEM
+ 
++config MTD_AMBARELLA_SPI_NOR
++	tristate "Ambarella Support SPI Nor Flash chips"
++	help
++	  Support Ambarella SPI NOR controler
++
+ config MTD_PMC551
+ 	tristate "Ramix PMC551 PCI Mezzanine RAM card support"
+ 	depends on PCI
+diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
+index d83bd730..e8f64af0 100644
+--- a/drivers/mtd/devices/Makefile
++++ b/drivers/mtd/devices/Makefile
+@@ -16,6 +16,6 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH)	+= elm.o
+ obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
+ obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
+ obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
+-
++obj-$(CONFIG_MTD_AMBARELLA_SPI_NOR)	+= ambarella_spinor.o spinor.o
+ 
+ CFLAGS_docg3.o			+= -I$(src)
+diff --git a/drivers/mtd/devices/ambarella_spinor.c b/drivers/mtd/devices/ambarella_spinor.c
+new file mode 100644
+index 00000000..81b056a0
+--- /dev/null
++++ b/drivers/mtd/devices/ambarella_spinor.c
+@@ -0,0 +1,786 @@
++/*
++ * drivers/mtd/ambarella_spinor.c
++ *
++ * History:
++ *    2014/03/10 - [cddiao] created file
++ *
++ * Copyright (C) 2014-2019, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include "spinor.h"
++
++/* Flash opcodes. */
++#define    OPCODE_WREN        0x06    /* Write enable */
++#define    OPCODE_RDSR        0x05    /* Read status register */
++#define    OPCODE_WRSR        0x01    /* Write status register 1 byte */
++#define    OPCODE_NORM_READ   0x03    /* Read data bytes (low frequency) */
++#define    OPCODE_FAST_READ   0x0b    /* Read data bytes (high frequency) */
++#define    OPCODE_PP          0x02    /* Page program (up to 256 bytes) */
++#define    OPCODE_BE_4K       0x20    /* Erase 4KiB block */
++#define    OPCODE_BE_32K      0x52    /* Erase 32KiB block */
++#define    OPCODE_CHIP_ERASE  0xc7    /* Erase whole flash chip */
++#define    OPCODE_SE          0xd8    /* Sector erase (usually 64KiB) */
++#define    OPCODE_RDID        0x9f    /* Read JEDEC ID */
++
++/* Used for SST flashes only. */
++#define    OPCODE_BP          0x02    /* Byte program */
++#define    OPCODE_WRDI        0x04    /* Write disable */
++#define    OPCODE_AAI_WP      0xad    /* Auto address increment word program */
++
++/* Used for Macronix flashes only. */
++#define    OPCODE_EN4B        0xb7    /* Enter 4-byte mode */
++#define    OPCODE_EX4B        0xe9    /* Exit 4-byte mode */
++
++/* Used for Spansion flashes only. */
++#define    OPCODE_BRWR        0x17    /* Bank register write */
++
++/* Status Register bits. */
++#define    SR_WIP            1    /* Write in progress */
++#define    SR_WEL            2    /* Write enable latch */
++/* meaning of other SR_* bits may differ between vendors */
++#define    SR_BP0            4    /* Block protect 0 */
++#define    SR_BP1            8    /* Block protect 1 */
++#define    SR_BP2            0x10    /* Block protect 2 */
++#define    SR_SRWD           0x80    /* SR write protect */
++
++/* Define max times to check status register before we give up. */
++#define    MAX_READY_WAIT_JIFFIES    (400 * HZ)    /* 40s max chip erase */
++#define    MAX_CMD_SIZE        5
++
++#define JEDEC_MFR(_jedec_id)    ((_jedec_id) >> 16)
++
++#define PART_DEV_SPINOR		(0x08)
++static u16 spi_addr_mode = 3;
++
++/****************************************************************************/
++
++static inline struct amb_norflash *mtd_to_amb(struct mtd_info *mtd)
++{
++    return container_of(mtd, struct amb_norflash, mtd);
++}
++
++/****************************************************************************/
++
++static int read_sr(struct amb_norflash *flash)
++{
++    ssize_t retval = 0;
++    u8 code = OPCODE_RDSR;
++    u8 val;
++    retval = ambspi_read_reg(flash, 1, code, &val);
++
++    if (retval < 0) {
++        dev_err((const struct device *)&flash->dev, "error %d reading SR\n",
++                (int) retval);
++        return retval;
++    }
++
++    return val;
++}
++
++/*
++ * Set write enable latch with Write Enable command.
++ * Returns negative if error occurred.
++ */
++int write_enable(struct amb_norflash *flash)
++{
++    u8 code = OPCODE_WREN;
++    return ambspi_send_cmd(flash, code, 0, 0, 0);
++}
++
++/*
++ * Send write disble instruction to the chip.
++ */
++static inline int write_disable(struct amb_norflash *flash)
++{
++    u8 code = OPCODE_WRDI;
++    return ambspi_send_cmd(flash, code, 0, 0, 0);
++}
++
++/*
++ * Enable/disable 4-byte addressing mode.
++ */
++static inline int set_4byte(struct amb_norflash *flash, u32 jedec_id, int enable)
++{
++	int ret = 0;
++
++	switch (JEDEC_MFR(jedec_id)) {
++		case CFI_MFR_MACRONIX:
++		case 0xEF: /* winbond */
++		case 0xC8: /* GD */
++			flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
++			return ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
++		case CFI_MFR_ST: /*Micron*/
++			write_enable(flash);
++			flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
++			ret = ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
++			write_disable(flash);
++			return ret;
++		default:
++			/* Spansion style */
++			flash->command[0] = OPCODE_BRWR;
++			flash->command[1] = enable << 7;
++			return ambspi_send_cmd(flash, flash->command[0], 0, flash->command[1], 1);
++	}
++}
++/*
++mode 1 - enter 4 byte spi addr mode
++	 0 - exit  4 byte spi addr mode
++*/
++static void check_set_spinor_addr_mode(struct amb_norflash *flash, int mode)
++{
++	if (flash->addr_width == 4) {
++		if (spi_addr_mode == 3 && mode){
++			set_4byte(flash, flash->jedec_id, 1);
++			spi_addr_mode = 4;
++		} else if (spi_addr_mode == 4 && mode == 0){
++			set_4byte(flash, flash->jedec_id, 0);
++			spi_addr_mode = 3;
++		}
++	}
++}
++/*
++ * Service routine to read status register until ready, or timeout occurs.
++ * Returns non-zero if error.
++ */
++int wait_till_ready(struct amb_norflash *flash)
++{
++    unsigned long deadline;
++    int sr;
++
++    deadline = jiffies + MAX_READY_WAIT_JIFFIES;
++
++    do {
++        if ((sr = read_sr(flash)) < 0)
++            break;
++        else if (!(sr & SR_WIP))
++            return 0;
++
++        cond_resched();
++
++    } while (!time_after_eq(jiffies, deadline));
++
++    return 1;
++}
++
++/*
++ * Erase the whole flash memory
++ *
++ * Returns 0 if successful, non-zero otherwise.
++ */
++static int erase_chip(struct amb_norflash *flash)
++{
++    /* Wait until finished previous write command. */
++    if (wait_till_ready(flash))
++        return 1;
++
++    /* Send write enable, then erase commands. */
++    write_enable(flash);
++
++    /* Set up command buffer. */
++    flash->command[0] = OPCODE_CHIP_ERASE;
++    ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
++
++    return 0;
++}
++
++
++/*
++ * Erase one sector of flash memory at offset ``offset'' which is any
++ * address within the sector which should be erased.
++ *
++ * Returns 0 if successful, non-zero otherwise.
++ */
++static int erase_sector(struct amb_norflash *flash, u32 offset)
++{
++
++    /* Wait until finished previous write command. */
++    if (wait_till_ready(flash))
++        return 1;
++
++    /* Send write enable, then erase commands. */
++    write_enable(flash);
++
++    /* Set up command buffer. */
++    flash->command[0] = flash->erase_opcode;
++    ambspi_send_cmd(flash, flash->command[0], 0, offset, flash->addr_width);
++
++    return 0;
++}
++
++/****************************************************************************/
++
++/*
++ * MTD implementation
++ */
++
++/*
++ * Erase an address range on the flash chip.  The address range may extend
++ * one or more erase sectors.  Return an error is there is a problem erasing.
++ */
++static int amba_erase(struct mtd_info *mtd, struct erase_info *instr)
++{
++    struct amb_norflash *flash = mtd_to_amb(mtd);
++    u32 addr, len;
++    uint32_t rem;
++
++    div_u64_rem(instr->len, mtd->erasesize, &rem);
++    if (rem)
++        return -EINVAL;
++
++    addr = instr->addr;
++    len = instr->len;
++
++    mutex_lock(&flash->lock);
++	check_set_spinor_addr_mode(flash, 1);
++    /* whole-chip erase? */
++    if (len == flash->mtd.size) {
++        if (erase_chip(flash)) {
++            instr->state = MTD_ERASE_FAILED;
++			check_set_spinor_addr_mode(flash, 0);
++            mutex_unlock(&flash->lock);
++            return -EIO;
++        }
++
++    /* REVISIT in some cases we could speed up erasing large regions
++     * by using OPCODE_SE instead of OPCODE_BE_4K.  We may have set up
++     * to use "small sector erase", but that's not always optimal.
++     */
++
++    /* "sector"-at-a-time erase */
++    } else {
++        while (len) {
++            if (erase_sector(flash, addr)) {
++                instr->state = MTD_ERASE_FAILED;
++				check_set_spinor_addr_mode(flash, 0);
++                mutex_unlock(&flash->lock);
++				return -EIO;
++            }
++
++            addr += mtd->erasesize;
++            len -= mtd->erasesize;
++        }
++    }
++	check_set_spinor_addr_mode(flash, 0);
++    mutex_unlock(&flash->lock);
++
++    instr->state = MTD_ERASE_DONE;
++    mtd_erase_callback(instr);
++
++    return 0;
++}
++
++/*
++ * Read an address range from the flash chip.  The address range
++ * may be any size provided it is within the physical boundaries.
++ */
++ static int amba_read(struct mtd_info *mtd, loff_t from, size_t len,
++    size_t *retlen, u_char *buf)
++{
++    struct amb_norflash *flash = mtd_to_amb(mtd);
++    uint8_t opcode;
++    int offset;
++    int needread = 0;
++    int ret=0;
++
++    mutex_lock(&flash->lock);
++
++    /* Wait till previous write/erase is done. */
++    if (wait_till_ready(flash)) {
++        /* REVISIT status return?? */
++        mutex_unlock(&flash->lock);
++        return 1;
++    }
++	check_set_spinor_addr_mode(flash, 1);
++    /* Set up the write data buffer. */
++    opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
++    flash->command[0] = opcode;
++    flash->dummy = 0;
++
++    for (offset = 0; offset < len; ) {
++        needread = len - offset;
++        if (needread >= AMBA_SPINOR_DMA_BUFF_SIZE) {
++            ret = ambspi_read_data(flash, from+offset, AMBA_SPINOR_DMA_BUFF_SIZE);
++            if(ret) {
++				dev_err((const struct device *)&flash->dev,
++						"SPI NOR read error from=%x len=%d\r\n", (u32)(from+offset), AMBA_SPINOR_DMA_BUFF_SIZE);
++				check_set_spinor_addr_mode(flash, 0);
++				mutex_unlock(&flash->lock);
++				return -1;
++            }
++			memcpy(buf+offset, flash->dmabuf, AMBA_SPINOR_DMA_BUFF_SIZE);
++			offset += AMBA_SPINOR_DMA_BUFF_SIZE;
++        }else{
++			ret = ambspi_read_data(flash, from+offset, needread);
++			if(ret) {
++				dev_err((const struct device *)&flash->dev,
++						"SPI NOR read error from=%x len=%d\r\n", (u32)(from+offset), needread);
++				check_set_spinor_addr_mode(flash, 0);
++				mutex_unlock(&flash->lock);
++				return -1;
++            }
++            memcpy(buf+offset, flash->dmabuf, needread);
++            offset += needread;
++        }
++    }
++    *retlen = offset;
++	check_set_spinor_addr_mode(flash, 0);
++    mutex_unlock(&flash->lock);
++    return 0;
++}
++
++/*
++ * Write an address range to the flash chip.  Data must be written in
++ * FLASH_PAGESIZE chunks.  The address range may be any size provided
++ * it is within the physical boundaries.
++ */
++static int amba_write(struct mtd_info *mtd, loff_t to, size_t len,
++    size_t *retlen, const u_char *buf)
++{
++    struct amb_norflash *flash = mtd_to_amb(mtd);
++    u32 page_offset, needwrite, needcopy, page_write;
++    mutex_lock(&flash->lock);
++
++    /* Wait until finished previous write command. */
++    if (wait_till_ready(flash)) {
++        mutex_unlock(&flash->lock);
++        return 1;
++    }
++	check_set_spinor_addr_mode(flash, 1);
++    write_enable(flash);
++
++    /* Set up the opcode in the write buffer. */
++    flash->command[0] = OPCODE_PP;
++    flash->dummy = 0;
++    page_offset = to & (flash->page_size - 1);
++    /* do all the bytes fit onto one page? */
++    if (page_offset + len <= flash->page_size) {
++        memcpy(flash->dmabuf, buf, len);
++        ambspi_prog_data(flash, 0, to, len);
++        *retlen = len;
++    } else {
++        u32 i;
++        u32 j;
++
++        /* the size of data remaining on the first page */
++        needwrite = flash->page_size - page_offset;
++        memcpy(flash->dmabuf, buf, needwrite);
++        ambspi_prog_data(flash, 0, to, needwrite);
++        *retlen = needwrite;
++        for (j=needwrite; j < len; j += needcopy) {
++            if (len-j < AMBA_SPINOR_DMA_BUFF_SIZE) {
++                needcopy = len-j;
++            }else{
++                needcopy = AMBA_SPINOR_DMA_BUFF_SIZE;
++            }
++            memcpy(flash->dmabuf, buf+j, needcopy);
++
++            for (i = 0; i < needcopy; i += page_write) {
++                page_write = needcopy - i;
++                if (page_write > flash->page_size) {
++                    page_write = flash->page_size;
++                }
++                /* write the next page to flash */
++                if (wait_till_ready(flash)) {
++					check_set_spinor_addr_mode(flash, 0);
++                    mutex_unlock(&flash->lock);
++                    return 1;
++                }
++                write_enable(flash);
++                ambspi_prog_data(flash, i, to+i+j, page_write);
++                *retlen += page_write;
++            }
++        }
++    }
++	check_set_spinor_addr_mode(flash, 0);
++    mutex_unlock(&flash->lock);
++    return 0;
++}
++
++
++/****************************************************************************/
++struct flash_info {
++    /* JEDEC id zero means "no ID" (most older chips);otherwise it has
++     * a high byte of zero plus three data bytes: the manufacturer id,
++     * then a two byte device id.
++     */
++    u32        jedec_id;
++    u16        ext_id;
++
++    /* The size listed here is what works with OPCODE_SE, which isn't
++     * necessarily called a "sector" by the vendor.
++     */
++    unsigned    sector_size;
++    u16         n_sectors;
++
++    u16        page_size;
++    u16        addr_width;
++
++	u32			max_clk_hz;
++    u16        flags;
++#define    SECT_4K        0x01        /* OPCODE_BE_4K works uniformly */
++};
++
++
++#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _page_size, _max_clk_hz, _flags)    \
++    {                                                                 \
++        .jedec_id = (_jedec_id),                                      \
++        .ext_id = (_ext_id),                                          \
++        .sector_size = (_sector_size),                                \
++        .n_sectors = (_n_sectors),                                    \
++        .page_size = (_page_size),                                      \
++		.max_clk_hz = (_max_clk_hz),                                    \
++        .flags = (_flags), }
++
++
++struct ambid_t {
++    char name[32];
++    struct flash_info driver_data;
++};
++
++static const struct ambid_t amb_ids[] = {
++    { "s70fl01gs", INFO(0x010220, 0x4d00, 256 * 1024, 256, 512, 50000000, 0) },
++	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, 256, 50000000, 0) },
++	{ "mx25l25645g", INFO(0xc22019, 0, 64 * 1024, 512, 256, 50000000, 0) },
++	{ "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024, 256, 50000000, 0) },
++	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, 256, 50000000, 0) },
++	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, 256, 50000000, 0) },
++	{ "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, 256, 50000000, 0) },
++	{ "gd25q256c", INFO(0xc84019, 0, 64 * 1024, 512, 256, 50000000, 0) },
++	{ "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024, 256, 50000000, 0) },
++    { },
++};
++
++static const struct ambid_t *jedec_probe(struct amb_norflash *flash)
++{
++    int	retval;
++    u8	code = OPCODE_RDID;
++    u8	id[5];
++    u32	jedec;
++    u16	ext_jedec;
++    struct flash_info	*info;
++	int		tmp;
++
++    /* JEDEC also defines an optional "extended device information"
++     * string for after vendor-specific data, after the three bytes
++     * we use here.  Supporting some chips might require using it.
++     */
++    retval = ambspi_read_reg(flash, 5, code, id);
++	if (retval < 0) {
++        dev_err((const struct device *)&flash->dev, "error %d reading id\n",
++                (int) retval);
++        return ERR_PTR(retval);
++    }
++    jedec = id[0];
++    jedec = jedec << 8;
++    jedec |= id[1];
++    jedec = jedec << 8;
++    jedec |= id[2];
++
++    ext_jedec = id[3] << 8 | id[4];
++
++    for (tmp = 0; tmp < ARRAY_SIZE(amb_ids) - 1; tmp++) {
++        info = (void *)&amb_ids[tmp].driver_data;
++        if (info->jedec_id == jedec) {
++            if (info->ext_id != 0 && info->ext_id != ext_jedec)
++                continue;
++            return &amb_ids[tmp];
++        }
++    }
++    dev_err((const struct device *)&flash->dev, "unrecognized JEDEC id %06x\n", jedec);
++    return ERR_PTR(-ENODEV);
++}
++
++static int amb_get_resource(struct amb_norflash    *flash, struct platform_device *pdev)
++{
++    struct resource *res;
++    int errorCode = 0;
++
++    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++    if (!res) {
++        dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
++        errorCode = -ENXIO;
++        goto spinor_get_resource_err_exit;
++    }
++
++    flash->regbase =
++        devm_ioremap(&pdev->dev, res->start, resource_size(res));
++    if (!flash->regbase) {
++        dev_err(&pdev->dev, "devm_ioremap() failed\n");
++        errorCode = -ENOMEM;
++        goto spinor_get_resource_err_exit;
++    }
++
++    res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++    if (!res) {
++        dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
++        errorCode = -ENXIO;
++        goto spinor_get_resource_err_exit;
++    }
++
++    flash->dmaregbase =
++        devm_ioremap(&pdev->dev, res->start, resource_size(res));
++    if (!flash->dmaregbase) {
++        dev_err(&pdev->dev, "devm_ioremap() failed\n");
++        errorCode = -ENOMEM;
++        goto spinor_get_resource_err_exit;
++    }
++
++    return 0;
++
++spinor_get_resource_err_exit:
++    return errorCode;
++}
++
++
++static int    amb_spi_nor_probe(struct platform_device *pdev)
++{
++	struct mtd_part_parser_data	ppdata;
++	struct flash_platform_data    data;
++	struct amb_norflash            *flash;
++	struct flash_info        *info;
++	unsigned            i;
++	int errCode = 0;
++	const struct ambid_t *ambid = NULL;;
++
++    flash = kzalloc(sizeof(struct amb_norflash), GFP_KERNEL);
++    if (!flash) {
++        errCode = -ENOMEM;
++        goto amb_spi_nor_probe_exit;
++    }
++
++    mutex_init(&flash->lock);
++    platform_set_drvdata(pdev, flash);
++    flash->dev = &pdev->dev;
++
++	/* set 50Mhz as default spi clock */
++	flash->clk = 50000000;
++    amb_get_resource(flash, pdev);
++    ambspi_init(flash);
++
++	ambid = jedec_probe(flash);
++	if (IS_ERR(ambid))
++			return PTR_ERR(ambid);
++	else {
++		info = (void *)&ambid->driver_data;
++	}
++	data.type = kzalloc(sizeof(32), GFP_KERNEL);
++    strcpy(data.type, ambid->name);
++
++	flash->mtd.name = "amba_spinor";
++    flash->mtd.type = MTD_NORFLASH;
++    flash->mtd.writesize = 1;
++    flash->mtd.flags = MTD_CAP_NORFLASH;
++    flash->mtd.size = info->sector_size * info->n_sectors;
++    flash->mtd._erase = amba_erase;
++    flash->mtd._read = amba_read;
++    flash->mtd._write = amba_write;
++    flash->write_enable = write_enable;
++    flash->wait_till_ready = wait_till_ready;
++
++    /* prefer "small sector" erase if possible */
++    if (info->flags & SECT_4K) {
++        flash->erase_opcode = OPCODE_BE_4K;
++        flash->mtd.erasesize = 4096;
++    } else {
++        flash->erase_opcode = OPCODE_SE;
++        flash->mtd.erasesize = info->sector_size;
++    }
++
++    flash->mtd.flags |= MTD_NO_ERASE;
++
++    flash->page_size = info->page_size;
++    flash->mtd.writebufsize = flash->page_size;
++
++    flash->fast_read = false;
++    flash->command = kzalloc(5, GFP_KERNEL);
++    if(!flash->command) {
++        dev_err((const struct device *)&flash->dev,
++            "SPI NOR driver malloc command error\r\n");
++        errCode = -ENOMEM;
++        goto amb_spi_nor_probe_free_flash;
++    }
++    if (flash->page_size > AMBA_SPINOR_DMA_BUFF_SIZE) {
++        dev_err((const struct device *)&flash->dev,
++            "SPI NOR driver buff size should bigger than nor flash page size \r\n");
++        errCode = -EINVAL;
++        goto amb_spi_nor_probe_free_command;
++    }
++	flash->clk = info->max_clk_hz;
++    ambspi_init(flash);
++
++    if (info->addr_width)
++        flash->addr_width = info->addr_width;
++    else {
++        /* enable 4-byte addressing if the device exceeds 16MiB */
++        if (flash->mtd.size > 0x1000000) {
++            flash->addr_width = 4;
++			/* We have set 4-bytes mode in bootloader */
++            //set_4byte(flash, info->jedec_id, 1);
++			spi_addr_mode = 4;
++        } else {
++			flash->addr_width = 3;
++			spi_addr_mode = 3;
++		}
++    }
++
++	flash->jedec_id	= info->jedec_id;
++    pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
++            ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
++        flash->mtd.name,
++        (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
++        flash->mtd.erasesize, flash->mtd.erasesize / 1024,
++        flash->mtd.numeraseregions);
++
++    if (flash->mtd.numeraseregions)
++        for (i = 0; i < flash->mtd.numeraseregions; i++)
++            pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, "
++                ".erasesize = 0x%.8x (%uKiB), "
++                ".numblocks = %d }\n",
++                i, (long long)flash->mtd.eraseregions[i].offset,
++                flash->mtd.eraseregions[i].erasesize,
++                flash->mtd.eraseregions[i].erasesize / 1024,
++                flash->mtd.eraseregions[i].numblocks);
++
++    ambspi_dma_config(flash);
++	ppdata.of_node = pdev->dev.of_node;
++	errCode = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, NULL, 0);
++	if (errCode < 0)
++		goto amb_spi_nor_probe_free_command;
++
++	check_set_spinor_addr_mode(flash, 0);
++    printk("SPI NOR Controller probed\r\n");
++    return 0;
++
++amb_spi_nor_probe_free_command:
++    kfree(flash->command);
++amb_spi_nor_probe_free_flash:
++    kfree(flash);
++amb_spi_nor_probe_exit:
++    return errCode;
++}
++
++
++static int amb_spi_nor_remove(struct platform_device *pdev)
++{
++
++    struct amb_norflash    *flash = platform_get_drvdata(pdev);
++    int        status;
++
++    /* Clean up MTD stuff. */
++    status = mtd_device_unregister(&flash->mtd);
++    if (status == 0) {
++        kfree(flash->command);
++        dma_free_coherent(flash->dev,
++            AMBA_SPINOR_DMA_BUFF_SIZE,
++            flash->dmabuf, flash->dmaaddr);
++        kfree(flash);
++    }
++    return 0;
++}
++
++static void amb_spi_nor_shutdown(struct platform_device *pdev)
++{
++	struct amb_norflash    *flash = platform_get_drvdata(pdev);
++
++	/* Wait until finished previous write command. */
++	if (wait_till_ready(flash))
++		return;
++
++	/* Send write enable, then erase commands. */
++	//write_enable(flash);
++	switch (JEDEC_MFR(flash->jedec_id)) {
++		case CFI_MFR_MACRONIX:
++		case 0xEF: /* winbond */
++		case 0xC8: /* GD */
++		case CFI_MFR_ST: /*Micron*/
++			flash->command[0] = 0x66;
++			ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
++			flash->command[0] = 0x99;
++			ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
++			return;
++		default:
++			/* Spansion style */
++			/* Set up command buffer. */
++			/* FL01GS use 0xF0 as reset enable command */
++			flash->command[0] = 0xF0;
++			ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
++	}
++}
++
++#ifdef CONFIG_PM
++static int amb_spi_nor_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	int	errorCode = 0;
++	struct amb_norflash	*flash;
++
++	flash = platform_get_drvdata(pdev);
++
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++		__func__, errorCode, state.event);
++
++	return errorCode;
++}
++
++static int amb_spi_nor_resume(struct platform_device *pdev)
++{
++	int	errorCode = 0;
++	struct amb_norflash	*flash;
++
++	flash = platform_get_drvdata(pdev);
++	ambspi_init(flash);
++	if (flash->addr_width == 4)
++		set_4byte(flash, flash->jedec_id, 1);
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
++
++	return errorCode;
++}
++#endif
++
++static const struct of_device_id ambarella_spi_nor_of_match[] = {
++    {.compatible = "ambarella,spinor", },
++    {},
++};
++MODULE_DEVICE_TABLE(of, ambarella_spi_nor_of_match);
++
++static struct platform_driver amb_spi_nor_driver = {
++	.driver = {
++		.name = "ambarella-spinor",
++		.owner = THIS_MODULE,
++		.of_match_table = ambarella_spi_nor_of_match,
++	},
++	.probe = amb_spi_nor_probe,
++	.remove = amb_spi_nor_remove,
++	.shutdown = amb_spi_nor_shutdown,
++#ifdef CONFIG_PM
++	.suspend	= amb_spi_nor_suspend,
++	.resume		= amb_spi_nor_resume,
++#endif
++	/* REVISIT: many of these chips have deep power-down modes, which
++	 * should clearly be entered on suspend() to minimize power use.
++	 * And also when they're otherwise idle...
++	 */
++};
++
++module_platform_driver(amb_spi_nor_driver);
++
++MODULE_AUTHOR("Johnson Diao");
++MODULE_DESCRIPTION("Ambarella Media processor SPI NOR Flash Controller Driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/mtd/devices/spinor.c b/drivers/mtd/devices/spinor.c
+new file mode 100644
+index 00000000..b1af28cf
+--- /dev/null
++++ b/drivers/mtd/devices/spinor.c
+@@ -0,0 +1,494 @@
++/**
++ * system/src/bld/spi_nor.c
++ *
++ * Flash controller functions with spi nor  chips.
++ *
++ * History:
++ *    2013/10/12 - [cddiao] creat
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++#include "spinor.h"
++
++struct spinorcmd_s{
++    int (*init)(void);
++    int (*erase_sector)(u32 sector);
++    int (*write_sector)(u32 sector, u8 *src);
++    int (*write_bst)(u32 sector, u8 *src, u32 *page_size);
++    int (*read)(u32 addr, u32 data_len, const u8 *dst);
++}spinorcmd;
++
++int ambspi_send_cmd(struct amb_norflash *flash, u32 cmd, u32 dummy_len, u32 data, u32 len)
++{
++    u32 tmp = 0;
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, dummy_len);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, len);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = amba_readl(flash->regbase + REG0C);
++    REGPREP(tmp, REG0C_CMD0_MASK, REG0C_CMD0_SHIFT, cmd);
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    if(len){
++        tmp = data;
++        amba_writel(flash->regbase + REG14, tmp);
++    }
++
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG30, tmp);
++
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG3C, tmp);
++
++    tmp = amba_readl(flash->regbase + REG50);
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG38);
++        if (REGDUMP(tmp, REG38_DATALENREACHINTR_MASK, REG38_DATALENREACHINTR_SHIFT) == 1){
++            return 0;
++        }
++    }
++    return -1;
++}
++EXPORT_SYMBOL_GPL(ambspi_send_cmd);
++
++int ambspi_read_reg(struct amb_norflash *flash, u32 datalen, u32 reg, u8 *value)
++{
++    u32 tmp = 0;
++    int i;
++
++    tmp = amba_readl(flash->regbase + REG28);
++    for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
++        amba_readb(flash->regbase + REG200);
++        tmp = amba_readl(flash->regbase + REG28);
++    }
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++    REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 1);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = reg;
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG10, tmp);
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG28);
++        if(REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT) == datalen){
++            break;
++        }
++    }
++
++    for (i = 0; i < datalen; i++){
++        *(value+i) = amba_readb(flash->regbase + REG200);
++    }
++    return 0;
++}
++EXPORT_SYMBOL_GPL(ambspi_read_reg);
++
++int ambspi_dma_config(struct amb_norflash *flash)
++{
++     flash->dmabuf = dma_alloc_coherent(flash->dev, AMBA_SPINOR_DMA_BUFF_SIZE,
++                     &flash->dmaaddr, GFP_KERNEL);
++     if (flash->dmabuf == NULL){
++        dev_err(flash->dev,  "dma_alloc_coherent failed!\n");
++        return -ENOMEM;
++     }
++     return 0;
++}
++
++int ambspi_progdata_dma(struct amb_norflash *flash, u32 srcoffset, u32 dst, u32 len)
++{
++    int done;
++    u32 tmp = 0;
++
++    amba_writel(flash->dmaregbase + 0x00,  0x1a800000);// DMA_ch0_control
++    amba_writel(flash->dmaregbase + 0x0c,  0x0);
++    amba_writel(flash->dmaregbase + 0x04,  flash->dmaaddr + srcoffset);// DMA_ch0_src_addr
++    amba_writel(flash->dmaregbase + 0x08,  (u32)(flash->regbase + REG100));// DMA_ch0_dest_addr
++    amba_writel(flash->dmaregbase + 0x00,  0x9a800000|len);// DMA_ch0_control
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = flash->command[0];
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG30_DATAREACH_MASK, REG30_DATAREACH_SHIFT, 1);
++    amba_writel(flash->regbase + REG30, tmp);
++
++    tmp = dst;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, (256-32));
++    amba_writel(flash->regbase + REG1C, tmp);
++
++    tmp = amba_readl(flash->regbase + REG18);
++    REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 1);
++    REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
++    amba_writel(flash->regbase + REG18, tmp);
++
++    do {
++        tmp = amba_readl(flash->regbase + REG2C);
++        done = REGDUMP(tmp, REG2C_TXFIFOEMP_MASK, REG2C_TXFIFOEMP_SHIFT);
++    }while (done != 0x0);
++
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG3C, tmp);
++
++    tmp = amba_readl(flash->regbase + REG50);
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG38);
++        if (REGDUMP(tmp,
++                REG38_DATALENREACHINTR_MASK,
++                REG38_DATALENREACHINTR_SHIFT) == 1){
++            return 0;
++        }
++    }
++    return -1;
++}
++
++int ambspi_prog_data(struct amb_norflash *flash, u32 srcoffset, u32 dst, u32 len)
++{
++    u32 tmp = 0;
++    int ret = 0;
++    u32 tail = 0, bulk = 0, i = 0;
++
++    tail = len % 32;
++    bulk = len / 32;
++
++    if (bulk >= 1 ){
++        ret = ambspi_progdata_dma(flash, srcoffset, dst, len-tail);
++    }
++    if (ret){
++        return ret;
++    }
++    if (tail){
++        if(bulk >= 1){
++                flash->wait_till_ready(flash);
++                flash->write_enable(flash);
++        }
++
++        tmp = amba_readl(flash->regbase + REG00);
++        REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, tail);
++        REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
++        REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
++        REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++        amba_writel(flash->regbase + REG00, tmp);
++
++        tmp = amba_readl(flash->regbase + REG04);
++        REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
++        REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++        REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++        REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++        REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++        REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++        REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++        amba_writel(flash->regbase + REG04, tmp);
++
++        tmp = flash->command[0];
++        amba_writel(flash->regbase + REG0C, tmp);
++
++        tmp = 0;
++        REGPREP(tmp, REG30_DATAREACH_MASK, REG30_DATAREACH_SHIFT, 1);
++        amba_writel(flash->regbase + REG30, tmp);
++
++        tmp = dst + bulk*32;
++        amba_writel(flash->regbase + REG14, tmp);
++
++        tmp = 0;
++        REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, (256-32));
++        amba_writel(flash->regbase + REG1C, tmp);
++
++        tmp = amba_readl(flash->regbase + REG18);
++        REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
++        REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
++        amba_writel(flash->regbase + REG18, tmp);
++        for (i = 0; i < tail; i++){
++            amba_writeb(flash->regbase + REG100,
++                    *(flash->dmabuf + srcoffset + bulk*32 + i));
++        }
++        tmp = 0x20;
++        amba_writel(flash->regbase + REG3C, tmp);
++
++        tmp = amba_readl(flash->regbase + REG50);
++        REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++        amba_writel(flash->regbase + REG50, tmp);
++        for (;;){
++            tmp = amba_readl(flash->regbase + REG24);
++            if(REGDUMP(tmp, REG24_TXFIFOLV_MASK, REG24_TXFIFOLV_SHIFT) == 0){
++                return 0;
++            }
++            udelay(100);//must delay
++        }
++    }
++    return -1;
++}
++EXPORT_SYMBOL_GPL(ambspi_prog_data);
++
++int ambspi_readdata_dma(struct amb_norflash *flash, u32 from,
++                            u32 len)
++{
++    u32 tmp = 0;
++
++    amba_writel(flash->dmaregbase + 0x10,  0x2a800000);// DMA_ch1_control
++    amba_writel(flash->dmaregbase + 0x1c,  0x0);
++    amba_writel(flash->dmaregbase + 0x14,  (u32)(flash->regbase + REG200));// DMA_ch1_src_addr
++    amba_writel(flash->dmaregbase + 0x18,  flash->dmaaddr);// DMA_ch1_dest_addr
++    amba_writel(flash->dmaregbase + 0x10,  0xaa800000 | len);// DMA_ch1_control
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = flash->command[0];
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = from;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG3C, tmp);
++
++    tmp = (32-1); // must use word.can't use rxfifothlv
++    amba_writel(flash->regbase + REG20, tmp);
++
++    tmp = amba_readl(flash->regbase + REG18);
++    REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 1);
++    REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
++    amba_writel(flash->regbase + REG18, tmp);
++
++    tmp = amba_readl(flash->regbase + REG50);
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG38);
++        if(REGDUMP(tmp,
++                REG38_DATALENREACHINTR_MASK,
++                REG38_DATALENREACHINTR_SHIFT) == 1){
++            return 0;
++        }
++        udelay(10);
++    }
++    return -1;
++}
++int ambspi_read_data(struct amb_norflash *flash, u32 from, u32 len)
++{
++    u32 tmp = 0;
++    int ret = 0;
++    u32 tail = 0, bulk = 0, i = 0;
++    tail = len % 32;
++    bulk = len / 32;
++    if (bulk >= 1){
++        ret = ambspi_readdata_dma(flash, from, len-tail);
++    }
++    if (ret){
++        return ret;
++    }
++    if (tail){
++        tmp = amba_readl(flash->regbase + REG00);
++        REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, tail);
++        REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
++        REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
++        REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++        amba_writel(flash->regbase + REG00, tmp);
++
++        tmp = amba_readl(flash->regbase + REG04);
++        REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
++        REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++        REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
++        REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++        REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++        REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++        REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++        amba_writel(flash->regbase + REG04, tmp);
++
++        tmp = flash->command[0];
++        amba_writel(flash->regbase + REG0C, tmp);
++
++        tmp = from+bulk*32;
++        amba_writel(flash->regbase + REG14, tmp);
++
++        tmp = 0x20;
++        amba_writel(flash->regbase + REG3C, tmp);
++
++        tmp = 31; // the reserved bits must set 0
++        amba_writel(flash->regbase + REG20, tmp);
++
++        tmp = amba_readl(flash->regbase + REG18);
++        REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
++        REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
++        amba_writel(flash->regbase + REG18, tmp);
++
++        tmp = amba_readl(flash->regbase + REG50);
++        REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++        amba_writel(flash->regbase + REG50, tmp);
++
++        for (;;){
++            tmp = amba_readl(flash->regbase + REG28);
++              if(REGDUMP(tmp,
++                REG28_RXFIFOLV_MASK,
++                REG28_RXFIFOLV_SHIFT) == tail){
++                break;
++            }
++        }
++        for (i = 0; i < tail; i++){
++            *(flash->dmabuf+bulk*32+i) = amba_readb(flash->regbase + REG200);
++        }
++        ret = 0;
++    }
++    return ret;
++}
++EXPORT_SYMBOL_GPL(ambspi_read_data);
++
++static u32 get_ssi3_freq_hz(void)
++{
++#define PLL_OUT_ENET   300000000
++	u32 val;
++
++	val = amba_rct_readl(CG_SSI3_REG);
++	if (val & 0x01000000)
++		return 0;
++
++	if (val == 0)
++		val = 1;
++
++	//return (clk_get_rate(clk_get(NULL, "gclk_core")) << 1) / val;
++	return (PLL_OUT_ENET) / val;
++}
++
++int ambspi_init(struct amb_norflash *flash)
++{
++    u32 divider, tmp = 0;
++
++	divider = get_ssi3_freq_hz() / flash->clk;
++	tmp = amba_readl(flash->regbase + REG08);
++	REGPREP(tmp, REG08_CHIPSEL_MASK, REG08_CHIPSEL_SHIFT, ~(1 << SPINOR_DEV));
++	REGPREP(tmp, REG08_CLKDIV_MASK, REG08_CLKDIV_SHIFT, divider);
++	REGPREP(tmp, REG08_FLOWCON_MASK, REG08_FLOWCON_SHIFT, 1);
++	REGPREP(tmp, REG08_HOLDPIN_MASK, REG08_HOLDPIN_SHIFT, 3);
++	amba_writel(flash->regbase + REG08, tmp);
++
++	tmp = amba_readl(flash->regbase + REG00);
++	REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
++	REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++	REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
++	REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++	amba_writel(flash->regbase + REG00, tmp);
++
++	tmp = amba_readl(flash->regbase + REG04);
++	REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++	REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++	REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++	REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++	REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++	REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++	REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++	amba_writel(flash->regbase + REG04, tmp);
++
++	tmp = 0x20;
++	amba_writel(flash->regbase + REG30, tmp);
++
++	tmp = 0;
++	REGPREP(tmp, REG40_TXFIFORESET_MASK, REG40_TXFIFORESET_SHIFT, 1);
++	amba_writel(flash->regbase + REG40, tmp);
++	tmp = 0;
++	REGPREP(tmp, REG44_RXFIFORESET_MASK, REG44_RXFIFORESET_SHIFT, 1);
++	amba_writel(flash->regbase + REG44, tmp);
++
++    /* after reset fifo, the 0x28 will become 0x10,
++    *so , read REG200 times to clear the 0x28,  this is a bug in hardware
++    */
++	while (amba_readl(flash->regbase + REG28) != 0) {
++		tmp = amba_readl(flash->regbase + REG200);
++	}
++
++	tmp = 0;
++	REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, 0x7f);
++	amba_writel(flash->regbase + REG1C, tmp);
++
++	tmp = 0;
++	REGPREP(tmp, REG20_RXFIFOLV_MASK, REG20_RXFIFOLV_SHIFT, 0x7f);
++	amba_writel(flash->regbase + REG20, tmp);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ambspi_init);
+diff --git a/drivers/mtd/devices/spinor.h b/drivers/mtd/devices/spinor.h
+new file mode 100644
+index 00000000..53257016
+--- /dev/null
++++ b/drivers/mtd/devices/spinor.h
+@@ -0,0 +1,235 @@
++/**
++ * system/include/flash/spinor.h
++ *
++ * History:
++ *    2013/10/15 - [Johnson Diao] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/err.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/interrupt.h>
++#include <linux/mutex.h>
++#include <linux/math64.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/mod_devicetable.h>
++
++#include <linux/mtd/cfi.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/of_platform.h>
++
++#include <linux/clk.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmaengine.h>
++#include <plat/dma.h>
++#include <plat/rct.h>
++
++#include <plat/ptb.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/flash.h>
++#include <linux/delay.h>
++
++#define REGPREP(reg,mask,shift,value) (reg=((~mask)&reg)|(value << shift))
++#define REGDUMP(reg,mask,shift) ((reg&mask)>>shift)
++
++#define REG00_DATALEN_SHIFT   0   /*[21:0]    data access length*/
++#define REG00_DATALEN_MASK    0x003fffff
++#define REG00_DUMMYLEN_SHIFT  22  /*[26:22]    dummy cycle length*/
++#define REG00_DUMMYLEN_MASK   0x07c00000
++#define REG00_ADDRLEN_SHIFT   27  /*[29:27]    address length*/
++#define REG00_ADDRLEN_MASK    0x38000000
++#define REG00_CMDLEN_SHIFT    30  /*[31:30]    command length*/
++#define    REG00_CMDLEN_MASK  0xc0000000
++
++#define REG04_READEN_SHIFT   0 /*[0]    data part read mode*/
++#define REG04_READEN_MASK    0x00000001
++#define REG04_WRITEEN_SHIFT  1 /*[1]    data part write mode*/
++#define REG04_WRITEEN_MASK   0x00000002
++#define REG04_RXLANE_SHIFT   9 /*[9] rx lane config*/
++#define REG04_RXLANE_MASK    0x00000200
++#define REG04_DATALANE_SHIFT 10 /*[11:10] number of data lane*/
++#define REG04_DATALANE_MASK  0x00000c00
++#define REG04_ADDRLANE_SHIFT 12 /*[13:12] number of addr lane*/
++#define REG04_ADDRLANE_MASK  0x00003000
++#define REG04_CMDLANE_SHIFT  14 /*[15:14] number of command lane */
++#define REG04_CMDLANE_MASK   0x0000c000
++#define REG04_LSBFRT_SHIFT   24 /*[24]    0-msb first 1-lsb first*/
++#define REG04_LSBFRT_MASK    0x01000000
++#define REG04_DATADTR_SHIFT  28 /*[28]    data double transfer rate*/
++#define REG04_DATADTR_MASK   0x10000000
++#define REG04_DUMMYDTR_SHIFT 29 /*[29]    dummy double transfer rate*/
++#define REG04_DUMMYDTR_MASK  0x20000000
++#define REG04_ADDRDTR_SHIFT  30 /*[30] address double transfer rate*/
++#define REG04_ADDRDTR_MASK   0x40000000
++#define REG04_CMDDTR_SHIFT   31/*[31] command dtr,only reg_clk divider>2*/
++#define REG04_CMDDTR_MASK    0x80000000
++
++#define REG08_RXSPLDELAY_SHIFT   0 /*[4:0]    adjust rx sampling data phase*/
++#define REG08_RXSPLDELAY_MASK    0x0000001f
++#define REG08_CLKDIV_SHIFT       10 /*[17:10]    divide reference clock*/
++#define REG08_CLKDIV_MASK        0x0003fc00
++#define REG08_CHIPSEL_SHIFT      18 /*[25:18]    cen for multiple device 0 for select and vice versa*/
++#define REG08_CHIPSEL_MASK       0x03fc0000
++#define REG08_HOLDSWITCH_SHIFT   26 /*[26]0 for hold switching on switch one ref clock cycle before negative edge*/
++#define REG08_HOLDSWITCH_MASK    0x04000000
++#define REG08_SPICLKPOL_SHIFT    27 /*[27]    clock will remain 1 or 0 in standby mode*/
++#define REG08_SPICLKPOL_MASK     0x08000000
++#define REG08_HOLDPIN_SHIFT      28 /*[30:28]    for flow control purpose*/
++#define REG08_HOLDPIN_MASK       0x70000000
++#define REG08_FLOWCON_SHIFT      31 /*[31]    flow control enable*/
++#define REG08_FLOWCON_MASK       0x80000000
++
++#define REG0C_CMD0_SHIFT 0 /*[7:0]    command for SPI  device*/
++#define REG0C_CMD0_MASK  0x000000ff
++#define REG0C_CMD1_SHIFT 8 /*[15:8]*/
++#define REG0C_CMD1_MASK  0x0000ff00
++#define REG0C_CMD2_SHIFT 16 /*[23:16]*/
++#define REG0C_CMD2_MASK  0x00ff0000
++
++#define REG18_RXDMAEN_SHIFT 0 /*[0]    rx dma enable*/
++#define REG18_RXDMAEN_MASK  0x00000001
++#define REG18_TXDMAEN_SHIFT 1 /*[1]    tx dma enable*/
++#define REG18_TXDMAEN_MASK  0x00000002
++
++#define REG1C_TXFIFOLV_SHIFT  0 /*[8:0]  tx fifo threshold level*/
++#define REG1C_TXFIFOLV_MASK   0x000000ff
++
++#define REG20_RXFIFOLV_SHIFT  0
++#define REG20_RXFIFOLV_MASK   0x000000ff
++
++#define REG24_TXFIFOLV_SHIFT  0
++#define REG24_TXFIFOLV_MASK   0x000000ff
++
++#define REG28_RXFIFOLV_SHIFT 0
++#define REG28_RXFIFOLV_MASK  0x000000ff
++
++#define REG2C_TXFIFONOTFULL_SHIFT 1 /*[1]*/
++#define REG2C_TXFIFONOTFULL_MASK  0x00000002
++#define REG2C_TXFIFOEMP_SHIFT     2 /*[2] tx fifo empty*/
++#define REG2C_TXFIFOEMP_MASK      0x00000004
++#define REG2C_RXFIFONOTEMP_SHIFT  3 /*[3] */
++#define REG2C_RXFIFONOTEMP_MASK   0x00000008
++#define REG2C_RXFIFOFULL_SHIFT    4 /*[4] rx fifo full*/
++#define REG2C_RXFIFOFULL_MASK     0x00000010
++
++#define REG30_TXEMP_SHIFT     0/*[0] tx fifo almost empty*/
++#define REG30_TXEMP_MASK      0x00000001
++#define REG30_TXOVER_SHIFT    1 /*[1]*/
++#define REG30_TXOVER_MASK     0x00000002
++#define REG30_RXUNDER_SHIFT   2/*[2]*/
++#define REG30_RXUNDER_MASK    0x00000004
++#define REG30_RXOVER_SHIFT    3/*[3]*/
++#define REG30_RXOVER_MASK     0x00000008
++#define REG30_RXFULL_SHIFT    4 /*[4]*/
++#define REG30_RXFULL_MASK     0x00000010
++#define REG30_DATAREACH_SHIFT 5 /*[5]*/
++#define REG30_DATAREACH_MASK  0x00000020
++#define REG30_TXUNDER_SHIFT   6/*[6]*/
++#define REG30_TXUNDER_MASK    0x00000040
++
++#define REG38_TXEMPTYINTR_SHIFT     0 /*[0]  tx almost empty*/
++#define REG38_TXEMPTYINTR_MASK      0x00000001
++#define REG38_TXOVERFLOWINTR_SHIFT  1 /*[1] */
++#define REG38_TXOVERFLOWINTR_MASK   0x00000002
++#define REG38_RXUNDERFLOWINTR_SHIFT 2 /*[2]*/
++#define REG38_RXUNDERFLOWINTR_MASK  0x00000004
++#define REG38_RXOVERFLOWINTR_SHIFT  3 /*[3]*/
++#define REG38_RXOVERFLOWINTR_MASK   0x00000008
++#define REG38_RXFULLINTR_SHIFT      4 /*[4] rx fifo almost full*/
++#define REG38_RXFULLINTR_MASK        0x00000010
++#define REG38_DATALENREACHINTR_SHIFT 5 /*[5] transaction done interrupt*/
++#define REG38_DATALENREACHINTR_MASK  0x00000020
++#define REG38_TXUNDERFLOWINTR_SHIFT  6 /*[6] */
++#define REG38_TXUNDERFLOWINTR_MASK   0x00000040
++
++#define REG40_TXFIFORESET_SHIFT  0 /*[0] software reset the tx fifo*/
++#define REG40_TXFIFORESET_MASK   0x00000001
++
++#define REG44_RXFIFORESET_SHIFT  0 /*[0]  software reset the rx fifo*/
++#define REG44_RXFIFORESET_MASK   0x00000001
++
++#define REG50_STRTRX_SHIFT 0 /*[0]    start tx or rx*/
++#define REG50_STRTRX_MASK  0x00000001
++
++#define HAS_IMG_PARTS       15
++#define TOTAL_FW_PARTS        (HAS_IMG_PARTS + HAS_NO_IMG_PARTS)
++
++#define REG00 0x00
++#define REG04 0x04
++#define REG08 0x08
++#define REG0C 0x0c
++#define REG10 0x10
++#define REG14 0x14
++#define REG18 0x18
++#define REG1C 0x1c
++#define REG20 0x20
++#define REG24 0x24
++#define REG28 0x28
++#define REG2C 0x2c
++#define REG30 0x30
++#define REG34 0x34
++#define REG38 0x38
++#define REG3C 0x3C
++#define REG40 0x40
++#define REG44 0x44
++#define REG50 0x50
++#define REG100 0x100
++#define REG200 0x200
++#define DMA_CONTROLLER_OFFSET (0xe0005000)
++
++#if defined(CONFIG_SPI_NOR_CHIP_0)
++#define SPINOR_DEV 0
++#elif defined(CONFIG_SPI_NOR_CHIP_1)
++#define SPINOR_DEV 1
++#elif defined(CONFIG_SPI_NOR_CHIP_2)
++#define SPINOR_DEV 2
++#elif defined(CONFIG_SPI_NOR_CHIP_3)
++#define SPINOR_DEV 3
++#else
++#define SPINOR_DEV 0
++#endif
++
++struct amb_norflash {
++    struct device                *dev;
++    unsigned char __iomem        *regbase;
++    unsigned char __iomem        *dmaregbase;
++    dma_addr_t                   dmaaddr;
++    u8                           *dmabuf;
++    int (*write_enable)(struct amb_norflash *flash);
++    int (*wait_till_ready)(struct amb_norflash *flash);
++    struct mutex                 lock;
++    struct mtd_info              mtd;
++    u16                          page_size;
++    u16                          addr_width;
++    u8                           erase_opcode;
++    u8                           *command;
++    u8                           dummy;
++    u32                          addr;
++	u32							 clk;
++    bool                         fast_read;
++	u32							 jedec_id;
++};
++//the buffer size must align to 32 and smaller than the max size of DMA
++#define AMBA_SPINOR_DMA_BUFF_SIZE    4096
++
++extern int ambspi_init(struct amb_norflash *flash);
++extern int ambspi_read_data(struct amb_norflash *flash,u32 from,u32 len);
++extern int ambspi_send_cmd(struct amb_norflash *flash,u32 cmd,u32 dummy_len,u32 data,u32 len);
++extern int ambspi_prog_data(struct amb_norflash *flash,u32 srcoffset,u32 dst,u32 len);
++extern int ambspi_read_reg(struct amb_norflash *flash,u32 datalen,u32 reg,u8 *value);
++extern int ambspi_dma_config(struct amb_norflash *flash);
+diff --git a/drivers/mtd/mtdblock_ambro.c b/drivers/mtd/mtdblock_ambro.c
+new file mode 100644
+index 00000000..8a506228
+--- /dev/null
++++ b/drivers/mtd/mtdblock_ambro.c
+@@ -0,0 +1,134 @@
++/*
++ * drivers/mtd/mtdblock_ambro.c
++ *
++ * History:
++ *	2014/08/15 - [Cao Rongrong] created file
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/blktrans.h>
++#include <linux/module.h>
++
++struct mtdblk_ambdev {
++	struct mtd_blktrans_dev mbd;
++	unsigned int *block_map;
++	unsigned int blocks;
++};
++
++static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
++			      unsigned long sector, char *buf)
++{
++	struct mtdblk_ambdev *ambdev = container_of(dev, struct mtdblk_ambdev, mbd);
++	unsigned int logic_b, phys_b;
++	loff_t from;
++	size_t retlen;
++
++	logic_b = mtd_div_by_eb(sector * 512, dev->mtd);
++	phys_b = ambdev->block_map[logic_b];
++	from = phys_b * dev->mtd->erasesize + mtd_mod_by_eb(sector * 512, dev->mtd);
++
++	if (mtd_read(dev->mtd, from, 512, &retlen, buf))
++		return 1;
++
++	return 0;
++}
++
++static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
++			      unsigned long sector, char *buf)
++{
++	BUG();
++	return 0;
++}
++
++static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
++{
++	struct mtdblk_ambdev *ambdev;
++	unsigned int blocks, logic_b, phys_b;
++
++	ambdev = kzalloc(sizeof(struct mtdblk_ambdev), GFP_KERNEL);
++	if (!ambdev)
++		return;
++
++	ambdev->mbd.mtd = mtd;
++	ambdev->mbd.devnum = mtd->index;
++
++	ambdev->mbd.size = mtd->size / 512;
++	ambdev->mbd.tr = tr;
++	ambdev->mbd.readonly = 1;
++
++	blocks = mtd_div_by_eb(mtd->size, mtd);
++	ambdev->block_map = kzalloc(blocks * sizeof(unsigned int), GFP_KERNEL);
++	if (!ambdev->block_map) {
++		kfree(ambdev);
++		return;
++	}
++
++	for (logic_b = 0, phys_b = 0; phys_b < blocks; phys_b++) {
++		if (mtd_block_isbad(mtd, phys_b * mtd->erasesize))
++			continue;
++		ambdev->block_map[logic_b] = phys_b;
++		logic_b++;
++	}
++
++	ambdev->blocks = logic_b;
++
++	if (add_mtd_blktrans_dev(&ambdev->mbd)) {
++		kfree(ambdev->block_map);
++		kfree(ambdev);
++	}
++}
++
++static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
++{
++	del_mtd_blktrans_dev(dev);
++}
++
++static struct mtd_blktrans_ops mtdblock_tr = {
++	.name		= "mtdblock",
++	.major		= 31,
++	.part_bits	= 0,
++	.blksize 	= 512,
++	.readsect	= mtdblock_readsect,
++	.writesect	= mtdblock_writesect,
++	.add_mtd	= mtdblock_add_mtd,
++	.remove_dev	= mtdblock_remove_dev,
++	.owner		= THIS_MODULE,
++};
++
++static int __init mtdblock_init(void)
++{
++	pr_info("Ambarella read-only mtdblock\n");
++	return register_mtd_blktrans(&mtdblock_tr);
++}
++
++static void __exit mtdblock_exit(void)
++{
++	deregister_mtd_blktrans(&mtdblock_tr);
++}
++
++module_init(mtdblock_init);
++module_exit(mtdblock_exit);
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Simple read-only block device emulation, with bad block skipped");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 50543f16..f1f18940 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -41,6 +41,20 @@ config MTD_SM_COMMON
+ 	tristate
+ 	default n
+ 
++config MTD_NAND_AMBARELLA
++	tristate "Ambarella Media Soc NAND support"
++	depends on PLAT_AMBARELLA
++	help
++	  This enables the SLC NAND flash controller on the Ambarella
++	  Media SoC.
++
++config MTD_SPINAND_AMBARELLA
++	tristate "Ambarella Media Soc SPI NAND support"
++	depends on PLAT_AMBARELLA
++	help
++	  This enables the SPI NAND flash controller on the Ambarella
++	  Media SoC.
++
+ config MTD_NAND_DENALI
+         tristate "Support Denali NAND controller"
+         help
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index bb818917..d60ff878 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -8,6 +8,8 @@ obj-$(CONFIG_MTD_NAND_BCH)		+= nand_bch.o
+ obj-$(CONFIG_MTD_NAND_IDS)		+= nand_ids.o
+ obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
+ 
++obj-$(CONFIG_MTD_NAND_AMBARELLA)	+= ambarella_nand.o
++
+ obj-$(CONFIG_MTD_NAND_CAFE)		+= cafe_nand.o
+ obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
+ obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
+@@ -50,5 +52,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
+ obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
+ obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
+ obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
++obj-$(CONFIG_MTD_SPINAND_AMBARELLA)	+= ambarella_spinand.o
+ 
+ nand-objs := nand_base.o nand_bbt.o
+diff --git a/drivers/mtd/nand/ambarella_nand.c b/drivers/mtd/nand/ambarella_nand.c
+new file mode 100644
+index 00000000..28f4c5f5
+--- /dev/null
++++ b/drivers/mtd/nand/ambarella_nand.c
+@@ -0,0 +1,2092 @@
++/*
++ * drivers/mtd/ambarella_nand.c
++ *
++ * History:
++ *	2008/04/11 - [Cao Rongrong & Chien-Yang Chen] created file
++ *	2009/01/04 - [Anthony Ginger] Port to 2.6.28
++ *	2012/05/23 - [Ken He] Add the dma engine driver method support
++ *	2012/07/03 - [Ken He] use the individual FDMA for nand
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/semaphore.h>
++#include <linux/slab.h>
++#include <linux/bitrev.h>
++#include <linux/bch.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/of_mtd.h>
++#include <linux/clk.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/nand_ecc.h>
++#include <linux/mtd/partitions.h>
++#include <plat/dma.h>
++#include <plat/nand.h>
++#include <plat/fio.h>
++#include <plat/rct.h>
++#include <plat/event.h>
++
++#define AMBARELLA_NAND_DMA_BUFFER_SIZE	4096
++
++
++struct ambarella_nand_info {
++	struct nand_chip		chip;
++	struct mtd_info			mtd;
++	struct nand_hw_control		controller;
++
++	struct device			*dev;
++	wait_queue_head_t		wq;
++
++	unsigned char __iomem		*regbase;
++	unsigned char __iomem		*fdmaregbase;
++	u32				dmabase;
++	int				suspend;
++	/* dma irq for transferring data between Nand and FIFO */
++	int				dma_irq;
++	int				cmd_irq;
++	/* fdma irq for transferring data between FIFO and Dram */
++	int				fdma_irq;
++	u32				ecc_bits;
++	/* if or not support to read id in 5 cycles */
++	bool				id_cycles_5;
++	bool				pllx2;
++	bool				soft_ecc;
++	bool				nand_wp;
++
++	/* used for software BCH */
++	struct bch_control		*bch;
++	u32				*errloc;
++	u8				*bch_data;
++	u8				read_ecc_rev[13];
++	u8				calc_ecc_rev[13];
++	u8				soft_bch_extra_size;
++
++	dma_addr_t			dmaaddr;
++	u8				*dmabuf;
++	int				dma_bufpos;
++	u32				dma_status;
++	u32				fio_dma_sta;
++	u32				fio_ecc_sta;
++	atomic_t			irq_flag;
++
++	/* saved column/page_addr during CMD_SEQIN */
++	int				seqin_column;
++	int				seqin_page_addr;
++
++	/* Operation parameters for nand controller register */
++	int				err_code;
++	u32				cmd;
++	u32				control_reg;
++	u32				addr_hi;
++	u32				addr;
++	u32				dst;
++	dma_addr_t			buf_phys;
++	dma_addr_t			spare_buf_phys;
++	u32				len;
++	u32				slen;
++	u32				area;
++	u32				ecc;
++	u32				timing[6];
++
++	struct notifier_block		system_event;
++	struct semaphore		system_event_sem;
++
++};
++
++static struct nand_ecclayout amb_oobinfo_512 = {
++	.eccbytes = 5,
++	.eccpos = {6, 7, 8, 9, 10},
++	.oobfree = {{0, 5}, {11, 5}}
++};
++
++static struct nand_ecclayout amb_oobinfo_2048 = {
++	.eccbytes = 20,
++	.eccpos = {8, 9, 10,11, 12,
++		24, 25, 26, 27, 28,
++		40, 41, 42, 43, 44,
++		56, 57, 58, 59, 60},
++	.oobfree = {{1, 7}, {13, 3},
++		{17, 7}, {29, 3},
++		{33, 7}, {45, 3},
++		{49, 7}, {61, 3}}
++};
++
++static struct nand_ecclayout amb_oobinfo_2048_dsm_ecc6 = {
++	.eccbytes = 40,
++	.eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
++		22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
++		38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
++		54, 55, 56, 57, 58, 59, 60, 61, 62, 63},
++	.oobfree = {{1, 5}, {17, 5},
++			{33, 5}, {49, 5}}
++};
++
++static struct nand_ecclayout amb_oobinfo_2048_dsm_ecc8 = {
++	.eccbytes = 52,
++	.eccpos = {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
++		51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
++		83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
++		115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127},
++	.oobfree = {{2, 17}, {34, 17},
++			{66, 17}, {98, 17}}
++};
++
++/* ==========================================================================*/
++#define NAND_TIMING_RSHIFT24BIT(x)	(((x) & 0xff000000) >> 24)
++#define NAND_TIMING_RSHIFT16BIT(x)	(((x) & 0x00ff0000) >> 16)
++#define NAND_TIMING_RSHIFT8BIT(x)	(((x) & 0x0000ff00) >> 8)
++#define NAND_TIMING_RSHIFT0BIT(x)	(((x) & 0x000000ff) >> 0)
++
++#define NAND_TIMING_LSHIFT24BIT(x)	((x) << 24)
++#define NAND_TIMING_LSHIFT16BIT(x)	((x) << 16)
++#define NAND_TIMING_LSHIFT8BIT(x)	((x) << 8)
++#define NAND_TIMING_LSHIFT0BIT(x)	((x) << 0)
++
++static int nand_timing_calc(u32 clk, int minmax, int val)
++{
++	u32 x;
++	int n,r;
++
++	x = val * clk;
++	n = x / 1000;
++	r = x % 1000;
++
++	if (r != 0)
++		n++;
++
++	if (minmax)
++		n--;
++	return n < 1 ? 1 : n;
++}
++
++static inline int nand_amb_is_hw_bch(struct ambarella_nand_info *nand_info)
++{
++	return !nand_info->soft_ecc && nand_info->ecc_bits > 1;
++}
++
++static inline int nand_amb_is_sw_bch(struct ambarella_nand_info *nand_info)
++{
++	return nand_info->soft_ecc && nand_info->ecc_bits > 1;
++}
++
++static void nand_amb_corrected_recovery(struct ambarella_nand_info *nand_info)
++{
++	u32 fio_ctr_reg, fio_dmactr_reg;
++
++	/* FIO reset will just reset FIO registers, but will not affect
++	 * Nand controller. */
++	fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
++	fio_dmactr_reg = amba_readl(nand_info->regbase + FIO_DMACTR_OFFSET);
++	ambarella_fio_rct_reset();
++	amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
++	amba_writel(nand_info->regbase + FIO_DMACTR_OFFSET, fio_dmactr_reg);
++}
++
++static void nand_amb_enable_dsm(struct ambarella_nand_info *nand_info)
++{
++	u32 fio_dsm_ctr = 0, fio_ctr_reg = 0, dma_dsm_ctr = 0;
++	fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
++
++	fio_dsm_ctr |= (FIO_DSM_EN | FIO_DSM_MAJP_2KB);
++	dma_dsm_ctr |= (DMA_DSM_EN | DMA_DSM_MAJP_2KB);
++	fio_ctr_reg |= FIO_CTR_RS;
++	fio_ctr_reg &= ~(FIO_CTR_CO | FIO_CTR_SE | FIO_CTR_ECC_6BIT
++					| FIO_CTR_ECC_8BIT);
++
++	if (nand_info->ecc_bits == 6) {
++		fio_dsm_ctr |= FIO_DSM_SPJP_64B;
++		dma_dsm_ctr |= DMA_DSM_SPJP_64B;
++	} else {
++		u32 nand_ext_ctr_reg = 0;
++		fio_dsm_ctr |= FIO_DSM_SPJP_128B;
++		dma_dsm_ctr |= DMA_DSM_SPJP_128B;
++
++		nand_ext_ctr_reg = amba_readl(nand_info->regbase +
++				FLASH_EX_CTR_OFFSET);
++		nand_ext_ctr_reg |= NAND_EXT_CTR_SP_2X;
++		amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
++					nand_ext_ctr_reg);
++	}
++
++	amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg | FIO_CTR_RR);
++	amba_writel(nand_info->regbase + FIO_DSM_CTR_OFFSET, fio_dsm_ctr);
++	amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
++	amba_writel(nand_info->fdmaregbase + FDMA_DSM_CTR_OFFSET, dma_dsm_ctr);
++
++}
++
++static void nand_amb_enable_bch(struct ambarella_nand_info *nand_info)
++{
++	u32 fio_dsm_ctr = 0, fio_ctr_reg = 0, dma_dsm_ctr = 0;
++	fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
++
++	fio_dsm_ctr |= (FIO_DSM_EN | FIO_DSM_MAJP_2KB);
++	dma_dsm_ctr |= (DMA_DSM_EN | DMA_DSM_MAJP_2KB);
++	fio_ctr_reg |= (FIO_CTR_RS | FIO_CTR_CO | FIO_CTR_SKIP_BLANK);
++
++	if (nand_info->ecc_bits == 6) {
++	  fio_dsm_ctr |= FIO_DSM_SPJP_64B;
++		dma_dsm_ctr |= DMA_DSM_SPJP_64B;
++		fio_ctr_reg |= FIO_CTR_ECC_6BIT;
++	} else {
++		u32 nand_ext_ctr_reg = 0;
++		fio_dsm_ctr |= FIO_DSM_SPJP_128B;
++		dma_dsm_ctr |= DMA_DSM_SPJP_128B;
++		fio_ctr_reg |= FIO_CTR_ECC_8BIT;
++		nand_ext_ctr_reg = amba_readl(nand_info->regbase +
++				FLASH_EX_CTR_OFFSET);
++		nand_ext_ctr_reg |= NAND_EXT_CTR_SP_2X;
++		amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
++					nand_ext_ctr_reg);
++	}
++
++	amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg | FIO_CTR_RR);
++	amba_writel(nand_info->regbase + FIO_DSM_CTR_OFFSET, fio_dsm_ctr);
++	amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
++	amba_writel(nand_info->fdmaregbase + FDMA_DSM_CTR_OFFSET, dma_dsm_ctr);
++
++}
++
++static void nand_amb_disable_bch(struct ambarella_nand_info *nand_info)
++{
++	u32 fio_ctr_reg = 0;
++
++	fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
++	/* Setup FIO Dual Space Mode Control Register */
++	fio_ctr_reg |= FIO_CTR_RS;
++	fio_ctr_reg &= ~(FIO_CTR_CO |
++			 FIO_CTR_ECC_6BIT |
++			 FIO_CTR_ECC_8BIT);
++
++	if (nand_info->ecc_bits == 8) {
++		u32 nand_ext_ctr_reg = 0;
++		nand_ext_ctr_reg = amba_readl(nand_info->regbase +
++					FLASH_EX_CTR_OFFSET);
++		nand_ext_ctr_reg &= ~NAND_EXT_CTR_SP_2X;
++		amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
++					nand_ext_ctr_reg);
++	}
++	amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
++
++	amba_writel(nand_info->regbase + FIO_DSM_CTR_OFFSET, 0);
++	amba_writel(nand_info->fdmaregbase + FDMA_DSM_CTR_OFFSET, 0);
++}
++
++static int count_zero_bits(u8 *buf, int size, int max_bits)
++{
++	int i, zero_bits = 0;
++
++	for (i = 0; i < size; i++) {
++		zero_bits += hweight8(~buf[i]);
++		if (zero_bits > max_bits)
++			break;
++	}
++	return zero_bits;
++}
++
++static int nand_bch_check_blank_page(struct ambarella_nand_info *nand_info, int needset)
++{
++	struct nand_chip *chip = &nand_info->chip;
++	int eccsteps = chip->ecc.steps;
++	int zeroflip = 0;
++	int oob_subset;
++	int zero_bits = 0;
++	u32 i;
++	u8 *bufpos;
++	u8 *bsp;
++
++	bufpos = nand_info->dmabuf;
++	bsp = nand_info->dmabuf + nand_info->mtd.writesize;
++	oob_subset = nand_info->mtd.oobsize / eccsteps;
++
++	for (i = 0; i < eccsteps; i++) {
++		zero_bits = count_zero_bits(bufpos, chip->ecc.size,
++								chip->ecc.strength);
++		if (zero_bits > chip->ecc.strength)
++			return -1;
++
++		if (zero_bits)
++			zeroflip = 1;
++
++		zero_bits += count_zero_bits(bsp, oob_subset,
++								chip->ecc.strength);
++		if (zero_bits > chip->ecc.strength)
++			return -1;
++
++		bufpos += chip->ecc.size;
++		bsp += oob_subset;
++	}
++
++	if (needset && zeroflip)
++		memset(nand_info->dmabuf, 0xff, nand_info->mtd.writesize);
++
++	return zeroflip;
++}
++static void amb_nand_set_timing(struct ambarella_nand_info *nand_info)
++{
++	u8 tcls, tals, tcs, tds;
++	u8 tclh, talh, tch, tdh;
++	u8 twp, twh, twb, trr;
++	u8 trp, treh, trb, tceh;
++	u8 trdelay, tclr, twhr, tir;
++	u8 tww, trhz, tar;
++	u32 i, t, clk, val;
++
++	for (i = 0; i < ARRAY_SIZE(nand_info->timing); i++) {
++		if (nand_info->timing[i] != 0x0)
++			break;
++	}
++	/* if the timing is not setup by Amboot, we leave the timing unchanged */
++	if (i == ARRAY_SIZE(nand_info->timing))
++		return;
++
++	clk = (clk_get_rate(clk_get(NULL, "gclk_core")) / 1000000);
++	if (nand_info->pllx2)
++		clk <<= 1;
++
++	/* timing 0 */
++	t = nand_info->timing[0];
++	tcls = NAND_TIMING_RSHIFT24BIT(t);
++	tals = NAND_TIMING_RSHIFT16BIT(t);
++	tcs = NAND_TIMING_RSHIFT8BIT(t);
++	tds = NAND_TIMING_RSHIFT0BIT(t);
++
++	tcls = nand_timing_calc(clk, 0, tcls);
++	tals = nand_timing_calc(clk, 0, tals);
++	tcs = nand_timing_calc(clk, 0, tcs);
++	tds = nand_timing_calc(clk, 0, tds);
++
++	val = NAND_TIMING_LSHIFT24BIT(tcls) |
++		NAND_TIMING_LSHIFT16BIT(tals) |
++		NAND_TIMING_LSHIFT8BIT(tcs) |
++		NAND_TIMING_LSHIFT0BIT(tds);
++
++	/* use default timing if gclk_core <= 96MHz */
++	if (clk <= 96)
++		val = 0x20202020;
++
++	amba_writel(nand_info->regbase + FLASH_TIM0_OFFSET, val);
++
++	/* timing 1 */
++	t = nand_info->timing[1];
++	tclh = NAND_TIMING_RSHIFT24BIT(t);
++	talh = NAND_TIMING_RSHIFT16BIT(t);
++	tch = NAND_TIMING_RSHIFT8BIT(t);
++	tdh = NAND_TIMING_RSHIFT0BIT(t);
++
++	tclh = nand_timing_calc(clk, 0, tclh);
++	talh = nand_timing_calc(clk, 0, talh);
++	tch = nand_timing_calc(clk, 0, tch);
++	tdh = nand_timing_calc(clk, 0, tdh);
++
++	val = NAND_TIMING_LSHIFT24BIT(tclh) |
++		NAND_TIMING_LSHIFT16BIT(talh) |
++		NAND_TIMING_LSHIFT8BIT(tch) |
++		NAND_TIMING_LSHIFT0BIT(tdh);
++
++	/* use default timing if gclk_core <= 96MHz */
++	if (clk <= 96)
++		val = 0x20202020;
++
++	amba_writel(nand_info->regbase + FLASH_TIM1_OFFSET, val);
++
++	/* timing 2 */
++	t = nand_info->timing[2];
++	twp = NAND_TIMING_RSHIFT24BIT(t);
++	twh = NAND_TIMING_RSHIFT16BIT(t);
++	twb = NAND_TIMING_RSHIFT8BIT(t);
++	trr = NAND_TIMING_RSHIFT0BIT(t);
++
++	twp = nand_timing_calc(clk, 0, twp);
++	twh = nand_timing_calc(clk, 0, twh);
++	twb = nand_timing_calc(clk, 1, twb);
++	trr = nand_timing_calc(clk, 0, trr);
++
++	val = NAND_TIMING_LSHIFT24BIT(twp) |
++		NAND_TIMING_LSHIFT16BIT(twh) |
++		NAND_TIMING_LSHIFT8BIT(twb) |
++		NAND_TIMING_LSHIFT0BIT(trr);
++
++	/* use default timing if gclk_core <= 96MHz */
++	if (clk <= 96)
++		val = 0x20204020;
++
++	amba_writel(nand_info->regbase + FLASH_TIM2_OFFSET, val);
++
++	/* timing 3 */
++	t = nand_info->timing[3];
++	trp = NAND_TIMING_RSHIFT24BIT(t);
++	treh = NAND_TIMING_RSHIFT16BIT(t);
++	trb = NAND_TIMING_RSHIFT8BIT(t);
++	tceh = NAND_TIMING_RSHIFT0BIT(t);
++
++	trp = nand_timing_calc(clk, 0, trp);
++	treh = nand_timing_calc(clk, 0, treh);
++	trb = nand_timing_calc(clk, 1, trb);
++	tceh = nand_timing_calc(clk, 1, tceh);
++
++	val = NAND_TIMING_LSHIFT24BIT(trp) |
++		NAND_TIMING_LSHIFT16BIT(treh) |
++		NAND_TIMING_LSHIFT8BIT(trb) |
++		NAND_TIMING_LSHIFT0BIT(tceh);
++
++	/* use default timing if gclk_core <= 96MHz */
++	if (clk <= 96)
++		val = 0x20202020;
++
++	amba_writel(nand_info->regbase + FLASH_TIM3_OFFSET, val);
++
++	/* timing 4 */
++	t = nand_info->timing[4];
++	trdelay = NAND_TIMING_RSHIFT24BIT(t);
++	tclr = NAND_TIMING_RSHIFT16BIT(t);
++	twhr = NAND_TIMING_RSHIFT8BIT(t);
++	tir = NAND_TIMING_RSHIFT0BIT(t);
++
++	trdelay = trp + treh;
++	tclr = nand_timing_calc(clk, 0, tclr);
++	twhr = nand_timing_calc(clk, 0, twhr);
++	tir = nand_timing_calc(clk, 0, tir);
++
++	val = NAND_TIMING_LSHIFT24BIT(trdelay) |
++		NAND_TIMING_LSHIFT16BIT(tclr) |
++		NAND_TIMING_LSHIFT8BIT(twhr) |
++		NAND_TIMING_LSHIFT0BIT(tir);
++
++	/* use default timing if gclk_core <= 96MHz */
++	if (clk <= 96)
++		val = 0x20202020;
++
++	amba_writel(nand_info->regbase + FLASH_TIM4_OFFSET, val);
++
++	/* timing 5 */
++	t = nand_info->timing[5];
++	tww = NAND_TIMING_RSHIFT16BIT(t);
++	trhz = NAND_TIMING_RSHIFT8BIT(t);
++	tar = NAND_TIMING_RSHIFT0BIT(t);
++
++	tww = nand_timing_calc(clk, 0, tww);
++	trhz = nand_timing_calc(clk, 1, trhz);
++	tar = nand_timing_calc(clk, 0, tar);
++
++
++	val = NAND_TIMING_LSHIFT16BIT(tww) |
++		NAND_TIMING_LSHIFT8BIT(trhz) |
++		NAND_TIMING_LSHIFT0BIT(tar);
++
++	/* use default timing if gclk_core <= 96MHz */
++	if (clk <= 96)
++		val = 0x20202020;
++
++	amba_writel(nand_info->regbase + FLASH_TIM5_OFFSET, val);
++}
++
++static int ambarella_nand_system_event(struct notifier_block *nb,
++	unsigned long val, void *data)
++{
++	int					errorCode = NOTIFY_OK;
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = container_of(nb, struct ambarella_nand_info, system_event);
++
++	switch (val) {
++	case AMBA_EVENT_PRE_CPUFREQ:
++		pr_debug("%s: Pre Change\n", __func__);
++		down(&nand_info->system_event_sem);
++		break;
++
++	case AMBA_EVENT_POST_CPUFREQ:
++		pr_debug("%s: Post Change\n", __func__);
++		amb_nand_set_timing(nand_info);
++		up(&nand_info->system_event_sem);
++		break;
++
++	default:
++		break;
++	}
++
++	return errorCode;
++}
++
++static irqreturn_t nand_fiocmd_isr_handler(int irq, void *dev_id)
++{
++	irqreturn_t				rval = IRQ_NONE;
++	struct ambarella_nand_info		*nand_info;
++	u32					val;
++
++	nand_info = (struct ambarella_nand_info *)dev_id;
++
++	val = amba_readl(nand_info->regbase + FIO_STA_OFFSET);
++
++	if (val & FIO_STA_FI) {
++		amba_writel(nand_info->regbase + FLASH_INT_OFFSET, 0x0);
++
++		atomic_clear_mask(0x1, (unsigned long *)&nand_info->irq_flag);
++		wake_up(&nand_info->wq);
++
++		rval = IRQ_HANDLED;
++	}
++
++	return rval;
++}
++
++/* this dma is used to transfer data between Nand and FIO FIFO. */
++static irqreturn_t nand_fiodma_isr_handler(int irq, void *dev_id)
++{
++	struct ambarella_nand_info		*nand_info;
++	u32					val, fio_dma_sta;
++
++	nand_info = (struct ambarella_nand_info *)dev_id;
++
++	val = amba_readl(nand_info->regbase + FIO_DMACTR_OFFSET);
++
++	if ((val & (FIO_DMACTR_SD | FIO_DMACTR_CF |
++		FIO_DMACTR_XD | FIO_DMACTR_FL)) ==  FIO_DMACTR_FL) {
++		fio_dma_sta = amba_readl(nand_info->regbase + FIO_DMASTA_OFFSET);
++		/* dummy IRQ by S2 chip */
++		if (fio_dma_sta == 0x0)
++			return IRQ_HANDLED;
++
++		nand_info->fio_dma_sta = fio_dma_sta;
++
++		amba_writel(nand_info->regbase + FIO_DMASTA_OFFSET, 0x0);
++
++		if (nand_amb_is_hw_bch(nand_info)) {
++			nand_info->fio_ecc_sta =
++				amba_readl(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET);
++			amba_writel(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET, 0x0);
++		}
++		atomic_clear_mask(0x2, (unsigned long *)&nand_info->irq_flag);
++		wake_up(&nand_info->wq);
++	}
++
++	return IRQ_HANDLED;
++}
++
++/* this dma is used to transfer data between FIO FIFO and Memory. */
++static irqreturn_t ambarella_fdma_isr_handler(int irq, void *dev_id)
++{
++	irqreturn_t				rval = IRQ_NONE;
++	struct ambarella_nand_info		*nand_info;
++	u32					int_src;
++
++	nand_info = (struct ambarella_nand_info *)dev_id;
++
++	int_src = amba_readl(nand_info->fdmaregbase + FDMA_INT_OFFSET);
++
++	if (int_src & (1 << FIO_DMA_CHAN)) {
++		nand_info->dma_status =
++			amba_readl(nand_info->fdmaregbase + FDMA_STA_OFFSET);
++		amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0);
++
++		atomic_clear_mask(0x4, (unsigned long *)&nand_info->irq_flag);
++		wake_up(&nand_info->wq);
++
++		rval = IRQ_HANDLED;
++	}
++
++	return rval;
++}
++
++static void nand_amb_setup_dma_devmem(struct ambarella_nand_info *nand_info)
++{
++	u32					ctrl_val;
++	u32					size = 0;
++
++	/* init and enable fdma to transfer data betwee FIFO and Memory */
++	if (nand_info->len > 16)
++		ctrl_val = DMA_CHANX_CTR_WM | DMA_CHANX_CTR_NI | DMA_NODC_MN_BURST_SIZE;
++	else
++		ctrl_val = DMA_CHANX_CTR_WM | DMA_CHANX_CTR_NI | DMA_NODC_SP_BURST_SIZE;
++
++	ctrl_val |= nand_info->len | DMA_CHANX_CTR_EN;
++	ctrl_val &= ~DMA_CHANX_CTR_D;
++
++	/* Setup main external DMA engine transfer */
++	amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
++
++	amba_writel(nand_info->fdmaregbase + FDMA_SRC_OFFSET, nand_info->dmabase);
++	amba_writel(nand_info->fdmaregbase + FDMA_DST_OFFSET, nand_info->buf_phys);
++
++	if (nand_info->ecc_bits > 1) {
++		/* Setup spare external DMA engine transfer */
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0x0);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_SRC_OFFSET, nand_info->dmabase);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_DST_OFFSET, nand_info->spare_buf_phys);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_CNT_OFFSET, nand_info->slen);
++	}
++
++	amba_writel(nand_info->fdmaregbase + FDMA_CTR_OFFSET, ctrl_val);
++
++	/* init and enable fio-dma to transfer data between Nand and FIFO */
++	amba_writel(nand_info->regbase + FIO_DMAADR_OFFSET, nand_info->addr);
++
++	size = nand_info->len + nand_info->slen;
++	if (size > 16) {
++		ctrl_val = FIO_DMACTR_EN |
++			FIO_DMACTR_FL |
++			FIO_MN_BURST_SIZE |
++			size;
++	} else {
++		ctrl_val = FIO_DMACTR_EN |
++			FIO_DMACTR_FL |
++			FIO_SP_BURST_SIZE |
++			size;
++	}
++	amba_writel(nand_info->regbase + FIO_DMACTR_OFFSET, ctrl_val);
++}
++
++static void nand_amb_setup_dma_memdev(struct ambarella_nand_info *nand_info)
++{
++	u32					ctrl_val, dma_burst_val, fio_burst_val;
++	u32					size = 0;
++
++	if (nand_info->ecc_bits > 1) {
++		dma_burst_val = DMA_NODC_MN_BURST_SIZE8;
++		fio_burst_val = FIO_MN_BURST_SIZE8;
++	} else {
++		dma_burst_val = DMA_NODC_MN_BURST_SIZE;
++		fio_burst_val = FIO_MN_BURST_SIZE;
++	}
++
++	/* init and enable fdma to transfer data betwee FIFO and Memory */
++	if (nand_info->len > 16)
++		ctrl_val = DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI | dma_burst_val;
++	else
++		ctrl_val = DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI | DMA_NODC_SP_BURST_SIZE;
++
++	ctrl_val |= nand_info->len | DMA_CHANX_CTR_EN;
++	ctrl_val &= ~DMA_CHANX_CTR_D;
++
++	/* Setup main external DMA engine transfer */
++	amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
++
++	amba_writel(nand_info->fdmaregbase + FDMA_SRC_OFFSET, nand_info->buf_phys);
++	amba_writel(nand_info->fdmaregbase + FDMA_DST_OFFSET, nand_info->dmabase);
++
++	if (nand_info->ecc_bits > 1) {
++		/* Setup spare external DMA engine transfer */
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0x0);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_SRC_OFFSET, nand_info->spare_buf_phys);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_DST_OFFSET, nand_info->dmabase);
++		amba_writel(nand_info->fdmaregbase + FDMA_SPR_CNT_OFFSET, nand_info->slen);
++	}
++
++	amba_writel(nand_info->fdmaregbase + FDMA_CTR_OFFSET, ctrl_val);
++
++	/* init and enable fio-dma to transfer data between Nand and FIFO */
++	amba_writel(nand_info->regbase + FIO_DMAADR_OFFSET, nand_info->addr);
++
++	size = nand_info->len + nand_info->slen;
++	if (size > 16) {
++		ctrl_val = FIO_DMACTR_EN | FIO_DMACTR_FL | fio_burst_val |
++			FIO_DMACTR_RM | size;
++	} else {
++		ctrl_val = FIO_DMACTR_EN | FIO_DMACTR_FL | FIO_SP_BURST_SIZE |
++			FIO_DMACTR_RM | size;
++	}
++	amba_writel(nand_info->regbase + FIO_DMACTR_OFFSET, ctrl_val);
++}
++
++static int nand_amb_request(struct ambarella_nand_info *nand_info)
++{
++	int					errorCode = 0;
++	u32					cmd;
++	u32					nand_ctr_reg = 0;
++	u32					nand_cmd_reg = 0;
++	u32					fio_ctr_reg = 0;
++	long					timeout;
++
++	if (unlikely(nand_info->suspend == 1)) {
++		dev_err(nand_info->dev, "%s: suspend!\n", __func__);
++		errorCode = -EPERM;
++		goto nand_amb_request_exit;
++	}
++
++	cmd = nand_info->cmd;
++
++	nand_ctr_reg = nand_info->control_reg | NAND_CTR_WAS;
++
++	fio_select_lock(SELECT_FIO_FL);
++
++	if ((nand_info->nand_wp) &&
++		(cmd == NAND_AMB_CMD_ERASE || cmd == NAND_AMB_CMD_COPYBACK ||
++		 cmd == NAND_AMB_CMD_PROGRAM || cmd == NAND_AMB_CMD_READSTATUS))
++			nand_ctr_reg &= ~NAND_CTR_WP;
++
++	switch (cmd) {
++	case NAND_AMB_CMD_RESET:
++		nand_cmd_reg = NAND_AMB_CMD_RESET;
++		amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
++			nand_cmd_reg);
++		break;
++
++	case NAND_AMB_CMD_READID:
++		nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
++		nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_READID;
++
++		if (nand_info->id_cycles_5) {
++			u32 nand_ext_ctr_reg = 0;
++
++			nand_ext_ctr_reg = amba_readl(nand_info->regbase + FLASH_EX_CTR_OFFSET);
++			nand_ext_ctr_reg |= NAND_EXT_CTR_I5;
++			nand_ctr_reg &= ~(NAND_CTR_I4);
++			amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
++				nand_ext_ctr_reg);
++		}
++
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
++			nand_ctr_reg);
++		amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
++			nand_cmd_reg);
++		break;
++
++	case NAND_AMB_CMD_READSTATUS:
++		nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
++		nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_READSTATUS;
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
++			nand_ctr_reg);
++		amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
++			nand_cmd_reg);
++		break;
++
++	case NAND_AMB_CMD_ERASE:
++		nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
++		nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_ERASE;
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
++			nand_ctr_reg);
++		amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
++			nand_cmd_reg);
++		break;
++
++	case NAND_AMB_CMD_COPYBACK:
++		nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
++		nand_ctr_reg |= NAND_CTR_CE;
++		nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_COPYBACK;
++		amba_writel(nand_info->regbase + FLASH_CFI_OFFSET,
++			nand_info->dst);
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
++			nand_ctr_reg);
++		amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
++			nand_cmd_reg);
++		break;
++
++	case NAND_AMB_CMD_READ:
++		nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
++
++		if (nand_amb_is_hw_bch(nand_info)) {
++			/* Setup FIO DMA Control Register */
++			nand_amb_enable_bch(nand_info);
++			/* in dual space mode,enable the SE bit */
++			nand_ctr_reg |= NAND_CTR_SE;
++
++			/* Clean Flash_IO_ecc_rpt_status Register */
++			amba_writel(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET, 0x0);
++		} else if (nand_amb_is_sw_bch(nand_info)) {
++			/* Setup FIO DMA Control Register */
++			nand_amb_enable_dsm(nand_info);
++			/* in dual space mode,enable the SE bit */
++			nand_ctr_reg |= NAND_CTR_SE;
++		} else {
++			if (nand_info->area == MAIN_ECC)
++				nand_ctr_reg |= (NAND_CTR_SE);
++			else if (nand_info->area == SPARE_ONLY ||
++				nand_info->area == SPARE_ECC)
++				nand_ctr_reg |= (NAND_CTR_SE | NAND_CTR_SA);
++
++			fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
++			fio_ctr_reg &= ~(FIO_CTR_CO | FIO_CTR_RS);
++
++			if (nand_info->area == SPARE_ONLY ||
++				nand_info->area == SPARE_ECC  ||
++				nand_info->area == MAIN_ECC)
++				fio_ctr_reg |= (FIO_CTR_RS);
++
++			switch (nand_info->ecc) {
++			case EC_MDSE:
++				nand_ctr_reg |= NAND_CTR_EC_SPARE;
++				fio_ctr_reg |= FIO_CTR_CO;
++				break;
++			case EC_MESD:
++				nand_ctr_reg |= NAND_CTR_EC_MAIN;
++				fio_ctr_reg |= FIO_CTR_CO;
++				break;
++			case EC_MESE:
++				nand_ctr_reg |=	(NAND_CTR_EC_MAIN | NAND_CTR_EC_SPARE);
++				fio_ctr_reg |= FIO_CTR_CO;
++				break;
++			case EC_MDSD:
++			default:
++				break;
++			}
++
++			amba_writel(nand_info->regbase + FIO_CTR_OFFSET,
++						fio_ctr_reg);
++		}
++
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET, nand_ctr_reg);
++		nand_amb_setup_dma_devmem(nand_info);
++
++		break;
++
++	case NAND_AMB_CMD_PROGRAM:
++		nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
++
++		if (nand_amb_is_hw_bch(nand_info)) {
++			/* Setup FIO DMA Control Register */
++			nand_amb_enable_bch(nand_info);
++			/* in dual space mode,enable the SE bit */
++			nand_ctr_reg |= NAND_CTR_SE;
++
++			/* Clean Flash_IO_ecc_rpt_status Register */
++			amba_writel(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET, 0x0);
++		} else if (nand_amb_is_sw_bch(nand_info)) {
++			/* Setup FIO DMA Control Register */
++			nand_amb_enable_dsm(nand_info);
++			/* in dual space mode,enable the SE bit */
++			nand_ctr_reg |= NAND_CTR_SE;
++		} else {
++			if (nand_info->area == MAIN_ECC)
++				nand_ctr_reg |= (NAND_CTR_SE);
++			else if (nand_info->area == SPARE_ONLY ||
++				nand_info->area == SPARE_ECC)
++				nand_ctr_reg |= (NAND_CTR_SE | NAND_CTR_SA);
++
++			fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
++			fio_ctr_reg &= ~(FIO_CTR_CO | FIO_CTR_RS);
++
++			if (nand_info->area == SPARE_ONLY ||
++				nand_info->area == SPARE_ECC  ||
++				nand_info->area == MAIN_ECC)
++				fio_ctr_reg |= (FIO_CTR_RS);
++
++			switch (nand_info->ecc) {
++			case EG_MDSE :
++				nand_ctr_reg |= NAND_CTR_EG_SPARE;
++				break;
++			case EG_MESD :
++				nand_ctr_reg |= NAND_CTR_EG_MAIN;
++				break;
++			case EG_MESE :
++				nand_ctr_reg |= (NAND_CTR_EG_MAIN | NAND_CTR_EG_SPARE);
++				break;
++			case EG_MDSD:
++			default:
++				break;
++			}
++
++			amba_writel(nand_info->regbase + FIO_CTR_OFFSET,
++				fio_ctr_reg);
++		}
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET, nand_ctr_reg);
++		nand_amb_setup_dma_memdev(nand_info);
++
++		break;
++
++	default:
++		dev_warn(nand_info->dev,
++			"%s: wrong command %d!\n", __func__, cmd);
++		errorCode = -EINVAL;
++		goto nand_amb_request_done;
++		break;
++	}
++
++	if (cmd == NAND_AMB_CMD_READ || cmd == NAND_AMB_CMD_PROGRAM) {
++		timeout = wait_event_timeout(nand_info->wq,
++			atomic_read(&nand_info->irq_flag) == 0x0, 1 * HZ);
++		if (timeout <= 0) {
++			errorCode = -EBUSY;
++			dev_err(nand_info->dev, "%s: cmd=0x%x timeout 0x%08x\n",
++				__func__, cmd, atomic_read(&nand_info->irq_flag));
++		} else {
++			dev_dbg(nand_info->dev, "%ld jiffies left.\n", timeout);
++		}
++
++		if (nand_info->dma_status & (DMA_CHANX_STA_OE | DMA_CHANX_STA_ME |
++			DMA_CHANX_STA_BE | DMA_CHANX_STA_RWE |
++			DMA_CHANX_STA_AE)) {
++			dev_err(nand_info->dev,
++				"%s: Errors happend in DMA transaction %d!\n",
++				__func__, nand_info->dma_status);
++			errorCode = -EIO;
++			goto nand_amb_request_done;
++		}
++
++		if (nand_amb_is_hw_bch(nand_info)) {
++			if (cmd == NAND_AMB_CMD_READ) {
++				if (nand_info->fio_ecc_sta & FIO_ECC_RPT_FAIL) {
++					int ret;
++
++					/* Workaround for some chips which will
++					 * report ECC failed for blank page. */
++					if (FIO_SUPPORT_SKIP_BLANK_ECC)
++						ret = -1;
++					else
++						ret = nand_bch_check_blank_page(nand_info, 1);
++
++					if (ret < 0) {
++						nand_info->mtd.ecc_stats.failed++;
++						dev_err(nand_info->dev,
++							"BCH corrected failed (0x%08x), addr is 0x[%x]!\n",
++							nand_info->fio_ecc_sta, nand_info->addr);
++					}
++				} else if (nand_info->fio_ecc_sta & FIO_ECC_RPT_ERR) {
++					unsigned int corrected;
++					corrected = 1;
++					if (NAND_ECC_RPT_NUM_SUPPORT) {
++						corrected = (nand_info->fio_ecc_sta >> 16) & 0x000F;
++						dev_info(nand_info->dev, "BCH correct [%d]bit in block[%d]\n",
++						corrected, (nand_info->fio_ecc_sta & 0x00007FFF));
++					} else {
++						/* once bitflip and data corrected happened, BCH will keep on
++						 * to report bitflip in following read operations, even though
++						 * there is no bitflip happened really. So this is a workaround
++						 * to get it back. */
++						nand_amb_corrected_recovery(nand_info);
++					}
++					nand_info->mtd.ecc_stats.corrected += corrected;
++				}
++			} else if (cmd == NAND_AMB_CMD_PROGRAM) {
++				if (nand_info->fio_ecc_sta & FIO_ECC_RPT_FAIL) {
++					dev_err(nand_info->dev,
++						"BCH program program failed (0x%08x)!\n",
++						nand_info->fio_ecc_sta);
++				}
++			}
++		}
++
++		if ((nand_info->fio_dma_sta & FIO_DMASTA_RE)
++			|| (nand_info->fio_dma_sta & FIO_DMASTA_AE)
++			|| !(nand_info->fio_dma_sta & FIO_DMASTA_DN)) {
++			u32 block_addr;
++			block_addr = nand_info->addr /
++					nand_info->mtd.erasesize *
++					nand_info->mtd.erasesize;
++			dev_err(nand_info->dev,
++				"%s: dma_status=0x%08x, cmd=0x%x, addr_hi=0x%x, "
++				"addr=0x%x, dst=0x%x, buf=0x%x, "
++				"len=0x%x, area=0x%x, ecc=0x%x, "
++				"block addr=0x%x!\n",
++				__func__,
++				nand_info->fio_dma_sta,
++				cmd,
++				nand_info->addr_hi,
++				nand_info->addr,
++				nand_info->dst,
++				nand_info->buf_phys,
++				nand_info->len,
++				nand_info->area,
++				nand_info->ecc,
++				block_addr);
++			errorCode = -EIO;
++			goto nand_amb_request_done;
++		}
++	} else {
++		/* just wait cmd irq, no care about both DMA irqs */
++		timeout = wait_event_timeout(nand_info->wq,
++			(atomic_read(&nand_info->irq_flag) & 0x1) == 0x0, 1 * HZ);
++		if (timeout <= 0) {
++			errorCode = -EBUSY;
++			dev_err(nand_info->dev, "%s: cmd=0x%x timeout 0x%08x\n",
++				__func__, cmd, atomic_read(&nand_info->irq_flag));
++			goto nand_amb_request_done;
++		} else {
++			dev_dbg(nand_info->dev, "%ld jiffies left.\n", timeout);
++
++			if (cmd == NAND_AMB_CMD_READID) {
++				u32 id = amba_readl(nand_info->regbase +
++					FLASH_ID_OFFSET);
++				if (nand_info->id_cycles_5) {
++					u32 id_5 = amba_readl(nand_info->regbase +
++					FLASH_EX_ID_OFFSET);
++					nand_info->dmabuf[4] = (unsigned char) (id_5 & 0xFF);
++				}
++				nand_info->dmabuf[0] = (unsigned char) (id >> 24);
++				nand_info->dmabuf[1] = (unsigned char) (id >> 16);
++				nand_info->dmabuf[2] = (unsigned char) (id >> 8);
++				nand_info->dmabuf[3] = (unsigned char) id;
++			} else if (cmd == NAND_AMB_CMD_READSTATUS) {
++				*nand_info->dmabuf = amba_readl(nand_info->regbase +
++					FLASH_STA_OFFSET);
++			}
++		}
++	}
++
++nand_amb_request_done:
++	atomic_set(&nand_info->irq_flag, 0x7);
++	nand_info->dma_status = 0;
++	/* Avoid to flush previous error info */
++	if (nand_info->err_code == 0)
++		nand_info->err_code = errorCode;
++
++	if ((nand_info->nand_wp) &&
++		(cmd == NAND_AMB_CMD_ERASE || cmd == NAND_AMB_CMD_COPYBACK ||
++		 cmd == NAND_AMB_CMD_PROGRAM || cmd == NAND_AMB_CMD_READSTATUS)) {
++			nand_ctr_reg |= NAND_CTR_WP;
++			amba_writel(nand_info->regbase + FLASH_CTR_OFFSET, nand_ctr_reg);
++	}
++
++	if ((cmd == NAND_AMB_CMD_READ || cmd == NAND_AMB_CMD_PROGRAM)
++		&& nand_amb_is_hw_bch(nand_info))
++		nand_amb_disable_bch(nand_info);
++
++	fio_unlock(SELECT_FIO_FL);
++
++nand_amb_request_exit:
++	return errorCode;
++}
++
++int nand_amb_reset(struct ambarella_nand_info *nand_info)
++{
++	nand_info->cmd = NAND_AMB_CMD_RESET;
++
++	return nand_amb_request(nand_info);
++}
++
++int nand_amb_read_id(struct ambarella_nand_info *nand_info)
++{
++	nand_info->cmd = NAND_AMB_CMD_READID;
++	nand_info->addr_hi = 0;
++	nand_info->addr = 0;
++
++	return nand_amb_request(nand_info);
++}
++
++int nand_amb_read_status(struct ambarella_nand_info *nand_info)
++{
++	nand_info->cmd = NAND_AMB_CMD_READSTATUS;
++	nand_info->addr_hi = 0;
++	nand_info->addr = 0;
++
++	return nand_amb_request(nand_info);
++}
++
++int nand_amb_erase(struct ambarella_nand_info *nand_info, u32 page_addr)
++{
++	int					errorCode = 0;
++	u32					addr_hi;
++	u32					addr;
++	u64					addr64;
++
++	addr64 = (u64)(page_addr * nand_info->mtd.writesize);
++	addr_hi = (u32)(addr64 >> 32);
++	addr = (u32)addr64;
++
++	nand_info->cmd = NAND_AMB_CMD_ERASE;
++	nand_info->addr_hi = addr_hi;
++	nand_info->addr = addr;
++
++	/* Fix dual space mode bug */
++	if (nand_info->ecc_bits > 1)
++		amba_writel(nand_info->regbase + FIO_DMAADR_OFFSET, nand_info->addr);
++
++	errorCode = nand_amb_request(nand_info);
++
++	return errorCode;
++}
++
++int nand_amb_read_data(struct ambarella_nand_info *nand_info,
++	u32 page_addr, dma_addr_t buf_dma, u8 area)
++{
++	int					errorCode = 0;
++	u32					addr_hi;
++	u32					addr;
++	u32					len;
++	u64					addr64;
++	u8					ecc = 0;
++
++	addr64 = (u64)(page_addr * nand_info->mtd.writesize);
++	addr_hi = (u32)(addr64 >> 32);
++	addr = (u32)addr64;
++
++	switch (area) {
++	case MAIN_ONLY:
++		ecc = EC_MDSD;
++		len = nand_info->mtd.writesize;
++		break;
++	case MAIN_ECC:
++		ecc = EC_MESD;
++		len = nand_info->mtd.writesize;
++		break;
++	case SPARE_ONLY:
++		ecc = EC_MDSD;
++		len = nand_info->mtd.oobsize;
++		break;
++	case SPARE_ECC:
++		ecc = EC_MDSE;
++		len = nand_info->mtd.oobsize;
++		break;
++	default:
++		dev_err(nand_info->dev, "%s: Wrong area.\n", __func__);
++		errorCode = -EINVAL;
++		goto nand_amb_read_page_exit;
++		break;
++	}
++
++	nand_info->slen = 0;
++	if (nand_info->ecc_bits > 1) {
++		/* when use BCH, the EG and EC should be 0 */
++		ecc = 0;
++		len = nand_info->mtd.writesize;
++		nand_info->slen = nand_info->mtd.oobsize;
++		nand_info->spare_buf_phys = buf_dma + len;
++	}
++
++	nand_info->cmd = NAND_AMB_CMD_READ;
++	nand_info->addr_hi = addr_hi;
++	nand_info->addr = addr;
++	nand_info->buf_phys = buf_dma;
++	nand_info->len = len;
++	nand_info->area = area;
++	nand_info->ecc = ecc;
++
++	errorCode = nand_amb_request(nand_info);
++
++nand_amb_read_page_exit:
++	return errorCode;
++}
++
++int nand_amb_write_data(struct ambarella_nand_info *nand_info,
++	u32 page_addr, dma_addr_t buf_dma, u8 area)
++{
++	int					errorCode = 0;
++	u32					addr_hi;
++	u32					addr;
++	u32					len;
++	u64					addr64;
++	u8					ecc;
++
++	addr64 = (u64)(page_addr * nand_info->mtd.writesize);
++	addr_hi = (u32)(addr64 >> 32);
++	addr = (u32)addr64;
++
++	switch (area) {
++	case MAIN_ONLY:
++		ecc = EG_MDSD;
++		len = nand_info->mtd.writesize;
++		break;
++	case MAIN_ECC:
++		ecc = EG_MESD;
++		len = nand_info->mtd.writesize;
++		break;
++	case SPARE_ONLY:
++		ecc = EG_MDSD;
++		len = nand_info->mtd.oobsize;
++		break;
++	case SPARE_ECC:
++		ecc = EG_MDSE;
++		len = nand_info->mtd.oobsize;
++		break;
++	default:
++		dev_err(nand_info->dev, "%s: Wrong area.\n", __func__);
++		errorCode = -EINVAL;
++		goto nand_amb_write_page_exit;
++		break;
++	}
++
++	nand_info->slen = 0;
++	if (nand_info->ecc_bits > 1) {
++		/* when use BCH, the EG and EC should be 0 */
++		ecc = 0;
++		len = nand_info->mtd.writesize;
++		nand_info->slen = nand_info->mtd.oobsize;
++		nand_info->spare_buf_phys = buf_dma + len;
++	}
++	nand_info->cmd = NAND_AMB_CMD_PROGRAM;
++	nand_info->addr_hi = addr_hi;
++	nand_info->addr = addr;
++	nand_info->buf_phys = buf_dma;
++	nand_info->len = len;
++	nand_info->area = area;
++	nand_info->ecc = ecc;
++
++	errorCode = nand_amb_request(nand_info);
++
++nand_amb_write_page_exit:
++	return errorCode;
++}
++
++
++/* ==========================================================================*/
++static uint8_t amb_nand_read_byte(struct mtd_info *mtd)
++{
++	struct ambarella_nand_info		*nand_info;
++	uint8_t					*data;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	data = nand_info->dmabuf + nand_info->dma_bufpos;
++	nand_info->dma_bufpos++;
++
++	return *data;
++}
++
++static u16 amb_nand_read_word(struct mtd_info *mtd)
++{
++	struct ambarella_nand_info		*nand_info;
++	u16					*data;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	data = (u16 *)(nand_info->dmabuf + nand_info->dma_bufpos);
++	nand_info->dma_bufpos += 2;
++
++	return *data;
++}
++
++static void amb_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
++{
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	BUG_ON((nand_info->dma_bufpos + len) > AMBARELLA_NAND_DMA_BUFFER_SIZE);
++
++	memcpy(buf, nand_info->dmabuf + nand_info->dma_bufpos, len);
++	nand_info->dma_bufpos += len;
++}
++
++static void amb_nand_write_buf(struct mtd_info *mtd,
++	const uint8_t *buf, int len)
++{
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	BUG_ON((nand_info->dma_bufpos + len) > AMBARELLA_NAND_DMA_BUFFER_SIZE);
++
++	memcpy(nand_info->dmabuf + nand_info->dma_bufpos, buf, len);
++	nand_info->dma_bufpos += len;
++}
++
++static void amb_nand_select_chip(struct mtd_info *mtd, int chip)
++{
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	if (chip > 0) {
++		dev_err(nand_info->dev,
++			"%s: Multi-Chip isn't supported yet.\n", __func__);
++	}
++}
++
++static void amb_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
++{
++
++}
++
++static int amb_nand_dev_ready(struct mtd_info *mtd)
++{
++	struct nand_chip 			*chip = mtd->priv;
++
++	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
++
++	return (chip->read_byte(mtd) & NAND_STATUS_READY) ? 1 : 0;
++}
++
++static int amb_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
++{
++	int					status = 0;
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	/* ambarella nand controller has waited for the command completion,
++	  * but still need to check the nand chip's status
++	  */
++	if (nand_info->err_code)
++		status = NAND_STATUS_FAIL;
++	else {
++		chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
++		status = chip->read_byte(mtd);
++	}
++
++	return status;
++}
++
++static void amb_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
++	int column, int page_addr)
++{
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++	nand_info->err_code = 0;
++
++	switch(command) {
++	case NAND_CMD_RESET:
++		nand_amb_reset(nand_info);
++		break;
++	case NAND_CMD_READID:
++		nand_info->dma_bufpos = 0;
++		nand_amb_read_id(nand_info);
++		break;
++	case NAND_CMD_STATUS:
++		nand_info->dma_bufpos = 0;
++		nand_amb_read_status(nand_info);
++		break;
++	case NAND_CMD_ERASE1:
++		nand_amb_erase(nand_info, page_addr);
++		break;
++	case NAND_CMD_ERASE2:
++		break;
++	case NAND_CMD_READOOB:
++		nand_info->dma_bufpos = column;
++		if (nand_info->ecc_bits > 1) {
++			u8 area = nand_info->soft_ecc ? MAIN_ONLY : MAIN_ECC;
++			nand_info->dma_bufpos = mtd->writesize;
++			nand_amb_read_data(nand_info, page_addr,
++					nand_info->dmaaddr, area);
++		} else {
++			nand_amb_read_data(nand_info, page_addr,
++					nand_info->dmaaddr, SPARE_ONLY);
++		}
++		break;
++	case NAND_CMD_READ0:
++	{
++		u8 area = nand_info->soft_ecc ? MAIN_ONLY : MAIN_ECC;
++
++		nand_info->dma_bufpos = column;
++		nand_amb_read_data(nand_info, page_addr, nand_info->dmaaddr, area);
++		if (nand_info->ecc_bits == 1)
++			nand_amb_read_data(nand_info, page_addr,
++				nand_info->dmaaddr + mtd->writesize, SPARE_ONLY);
++
++		break;
++	}
++	case NAND_CMD_SEQIN:
++		nand_info->dma_bufpos = column;
++		nand_info->seqin_column = column;
++		nand_info->seqin_page_addr = page_addr;
++		break;
++	case NAND_CMD_PAGEPROG:
++	{
++		u32 mn_area, sp_area, offset;
++
++		mn_area = nand_info->soft_ecc ? MAIN_ONLY : MAIN_ECC;
++		sp_area = nand_amb_is_hw_bch(nand_info) ? SPARE_ECC : SPARE_ONLY;
++		offset = (nand_info->ecc_bits > 1) ? 0 : mtd->writesize;
++
++		if (nand_info->seqin_column < mtd->writesize) {
++			nand_amb_write_data(nand_info,
++				nand_info->seqin_page_addr,
++				nand_info->dmaaddr, mn_area);
++			if (nand_info->soft_ecc && nand_info->ecc_bits == 1) {
++				nand_amb_write_data(nand_info,
++					nand_info->seqin_page_addr,
++					nand_info->dmaaddr + mtd->writesize,
++					sp_area);
++			}
++		} else {
++			nand_amb_write_data(nand_info,
++				nand_info->seqin_page_addr,
++				nand_info->dmaaddr + offset,
++				sp_area);
++		}
++		break;
++	}
++	default:
++		dev_err(nand_info->dev, "%s: 0x%x, %d, %d\n",
++				__func__, command, column, page_addr);
++		BUG();
++		break;
++	}
++}
++
++static void amb_nand_hwctl(struct mtd_info *mtd, int mode)
++{
++}
++
++static int amb_nand_calculate_ecc(struct mtd_info *mtd,
++		const u_char *buf, u_char *code)
++{
++	struct ambarella_nand_info *nand_info;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	if (!nand_info->soft_ecc) {
++		memset(code, 0xff, nand_info->chip.ecc.bytes);
++	} else if (nand_info->ecc_bits == 1) {
++		nand_calculate_ecc(mtd, buf, code);
++		/* FIXME: the first two bytes ecc codes are swaped comparing
++		 * to the ecc codes generated by our hardware, so we swap them
++		 * here manually. But I don't know why they were swapped. */
++		swap(code[0], code[1]);
++	} else {
++		u32 i, amb_eccsize;
++
++		/* make it be compatible with hw bch */
++		for (i = 0; i < nand_info->chip.ecc.size; i++)
++			nand_info->bch_data[i] = bitrev8(buf[i]);
++
++		memset(code, 0, nand_info->chip.ecc.bytes);
++
++		amb_eccsize = nand_info->chip.ecc.size + nand_info->soft_bch_extra_size;
++		encode_bch(nand_info->bch, nand_info->bch_data, amb_eccsize, code);
++
++		/* make it be compatible with hw bch */
++		for (i = 0; i < nand_info->chip.ecc.bytes; i++)
++			code[i] = bitrev8(code[i]);
++	}
++
++	return 0;
++}
++
++static int amb_nand_correct_data(struct mtd_info *mtd, u_char *buf,
++		u_char *read_ecc, u_char *calc_ecc)
++{
++	struct ambarella_nand_info *nand_info;
++	int errorCode = 0;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	/* if we use hardware ecc, any errors include DMA error and
++	 * FIO DMA error, we consider it as a ecc error which will tell
++	 * the caller the read fail. We have distinguish all the errors,
++	 * but the nand_read_ecc only check the return value by this
++	 * function. */
++	if (!nand_info->soft_ecc)
++		errorCode = nand_info->err_code;
++	else if (nand_info->ecc_bits == 1)
++		errorCode = nand_correct_data(mtd, buf, read_ecc, calc_ecc);
++	else {
++		struct nand_chip *chip = &nand_info->chip;
++		u32 *errloc = nand_info->errloc;
++		int amb_eccsize, i, count;
++
++		for (i = 0; i < chip->ecc.bytes; i++) {
++			nand_info->read_ecc_rev[i] = bitrev8(read_ecc[i]);
++			nand_info->calc_ecc_rev[i] = bitrev8(calc_ecc[i]);
++		}
++
++		amb_eccsize = chip->ecc.size + nand_info->soft_bch_extra_size;
++		count = decode_bch(nand_info->bch, NULL,
++					amb_eccsize,
++					nand_info->read_ecc_rev,
++					nand_info->calc_ecc_rev,
++					NULL, errloc);
++		if (count > 0) {
++			for (i = 0; i < count; i++) {
++				if (errloc[i] < (amb_eccsize * 8)) {
++					/* error is located in data, correct it */
++					buf[errloc[i] >> 3] ^= (128 >> (errloc[i] & 7));
++				}
++				/* else error in ecc, no action needed */
++
++				dev_dbg(nand_info->dev,
++					"corrected bitflip %u\n", errloc[i]);
++			}
++		} else if (count < 0) {
++			count = nand_bch_check_blank_page(nand_info , 0);
++			if (count < 0)
++				dev_err(nand_info->dev, "ecc unrecoverable error\n");
++			else if (count > 0)
++				memset(buf, 0xff, chip->ecc.size);
++		}
++
++		errorCode = count;
++	}
++
++	return errorCode;
++}
++
++static int amb_nand_write_oob_std(struct mtd_info *mtd,
++	struct nand_chip *chip, int page)
++{
++	struct ambarella_nand_info		*nand_info;
++	int					i, status;
++
++	nand_info = (struct ambarella_nand_info *)mtd->priv;
++
++	/* Our nand controller will write the generated ECC code into spare
++	  * area automatically, so we should mark the ECC code which located
++	  * in the eccpos.
++	  */
++	if (!nand_info->soft_ecc) {
++		for (i = 0; i < chip->ecc.total; i++)
++			chip->oob_poi[chip->ecc.layout->eccpos[i]] = 0xFF;
++	}
++
++	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
++	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
++	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
++	status = chip->waitfunc(mtd, chip);
++
++	return status & NAND_STATUS_FAIL ? -EIO : 0;
++}
++
++/*
++ * The encoding sequence in a byte is "LSB first".
++ *
++ * For each 2K page, there will be 2048 byte main data (B0 ~ B2047) and 64 byte
++ * spare data (B2048 ~ B2111). Thus, each page is divided into 4 BCH blocks.
++ * For example, B0~B511 and B2048~B2063 are grouped as the first BCH block.
++ * B0 will be encoded first and B2053 will be encoded last.
++ *
++ * B2054 ~B2063 are used to store 10B parity data (precisely to say, 78 bits)
++ * The 2 dummy bits are filled as 0 and located at the msb of B2063.
++*/
++static int ambarella_nand_init_soft_bch(struct ambarella_nand_info *nand_info)
++{
++	struct nand_chip *chip = &nand_info->chip;
++	u32 amb_eccsize, eccbytes, m, t;
++
++	amb_eccsize = chip->ecc.size + nand_info->soft_bch_extra_size;
++	eccbytes = chip->ecc.bytes;
++
++	m = fls(1 + 8 * amb_eccsize);
++	t = (eccbytes * 8) / m;
++
++	nand_info->bch = init_bch(m, t, 0);
++	if (!nand_info->bch)
++		return -EINVAL;
++
++	nand_info->errloc = devm_kzalloc(nand_info->dev,
++				t * sizeof(*nand_info->errloc), GFP_KERNEL);
++	if (!nand_info->errloc)
++		return -ENOMEM;
++
++	nand_info->bch_data = devm_kzalloc(nand_info->dev,
++					amb_eccsize, GFP_KERNEL);
++	if (nand_info->bch_data == NULL)
++		return -ENOMEM;
++
++	/* asumming the 6 bytes data in spare area are all 0xff, in other
++	 * words, we don't support to write anything except for ECC code
++	 * into spare are. */
++	memset(nand_info->bch_data + chip->ecc.size,
++				0xff, nand_info->soft_bch_extra_size);
++
++	return 0;
++}
++
++static void ambarella_fio_nand_rct_reset(void)
++{
++	amba_rct_writel(FIO_RESET_REG, FIO_RESET_FIO_RST | FIO_RESET_FLASH_RST);
++	mdelay(5);
++	amba_rct_writel(FIO_RESET_REG, 0x0);
++	mdelay(5);
++}
++
++static void ambarella_nand_init_hw(struct ambarella_nand_info *nand_info)
++{
++	/* reset FIO by RCT */
++	fio_select_lock(SELECT_FIO_FL);
++	ambarella_fio_nand_rct_reset();
++	fio_unlock(SELECT_FIO_FL);
++
++	/* When suspend/resume mode, before exit random read mode,
++	 * we take time for make sure FIO reset well and
++	 * some dma req finished.
++	 */
++	if (nand_info->suspend == 1)
++		mdelay(2);
++	/* Exit random read mode */
++	amba_clrbitsl(nand_info->regbase + FIO_CTR_OFFSET, FIO_CTR_RR);
++	mdelay(1);
++	nand_info->fio_dma_sta = 0;
++
++	/* init fdma to avoid dummy irq */
++	amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
++	amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0);
++	amba_writel(nand_info->fdmaregbase + FDMA_CTR_OFFSET,
++		DMA_CHANX_CTR_WM | DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI);
++
++	if (nand_info->suspend == 1)
++		amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
++			nand_info->control_reg);
++
++	amb_nand_set_timing(nand_info);
++}
++
++static int ambarella_nand_config_flash(struct ambarella_nand_info *nand_info)
++{
++	int					errorCode = 0;
++
++	/* control_reg will be uesd when real operation to NAND is performed */
++
++	/* Calculate row address cycyle according to whether the page number
++	  * of the nand is greater than 65536 */
++	if ((nand_info->chip.chip_shift - nand_info->chip.page_shift) > 16)
++		nand_info->control_reg |= NAND_CTR_P3;
++	else
++		nand_info->control_reg &= ~NAND_CTR_P3;
++
++	nand_info->control_reg &= ~NAND_CTR_SZ_8G;
++	switch (nand_info->chip.chipsize) {
++	case 8 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_64M;
++		break;
++	case 16 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_128M;
++		break;
++	case 32 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_256M;
++		break;
++	case 64 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_512M;
++		break;
++	case 128 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_1G;
++		break;
++	case 256 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_2G;
++		break;
++	case 512 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_4G;
++		break;
++	case 1024 * 1024 * 1024:
++		nand_info->control_reg |= NAND_CTR_SZ_8G;
++		break;
++	default:
++		dev_err(nand_info->dev,
++			"Unexpected NAND flash chipsize %lld. Aborting\n",
++			nand_info->chip.chipsize);
++		errorCode = -ENXIO;
++		break;
++	}
++
++	return errorCode;
++}
++
++static int ambarella_nand_init_chip(struct ambarella_nand_info *nand_info,
++		struct device_node *np)
++{
++	struct nand_chip *chip = &nand_info->chip;
++	u32 poc = ambarella_get_poc();
++
++	/* if ecc is generated by software, the ecc bits num will
++	 * be defined in FDT. */
++	if (!nand_info->soft_ecc) {
++		if (of_find_property(np, "amb,no-bch", NULL)) {
++			nand_info->ecc_bits = 1;
++		} else if (poc & SYS_CONFIG_NAND_ECC_BCH_EN) {
++			if (poc & SYS_CONFIG_NAND_ECC_SPARE_2X)
++				nand_info->ecc_bits = 8;
++			else
++				nand_info->ecc_bits = 6;
++		} else {
++			nand_info->ecc_bits = 1;
++		}
++	}
++
++	dev_info(nand_info->dev, "in %secc-[%d]bit mode\n",
++		nand_info->soft_ecc ? "soft " : "", nand_info->ecc_bits);
++
++	nand_info->control_reg = 0;
++	if (poc & SYS_CONFIG_NAND_READ_CONFIRM)
++		nand_info->control_reg |= NAND_CTR_RC;
++	if (poc & SYS_CONFIG_NAND_PAGE_SIZE)
++		nand_info->control_reg |= (NAND_CTR_C2 | NAND_CTR_SZ_8G);
++	/*
++	  * Always use P3 and I4 to support all NAND,
++	  * but we will adjust them after read ID from NAND. */
++	nand_info->control_reg |= (NAND_CTR_P3 | NAND_CTR_I4 | NAND_CTR_IE);
++	nand_info->id_cycles_5 = NAND_READ_ID5;
++
++	if(nand_info->nand_wp)
++		nand_info->control_reg |= NAND_CTR_WP;
++
++	chip->chip_delay = 0;
++	chip->controller = &nand_info->controller;
++	chip->read_byte = amb_nand_read_byte;
++	chip->read_word = amb_nand_read_word;
++	chip->write_buf = amb_nand_write_buf;
++	chip->read_buf = amb_nand_read_buf;
++	chip->select_chip = amb_nand_select_chip;
++	chip->cmd_ctrl = amb_nand_cmd_ctrl;
++	chip->dev_ready = amb_nand_dev_ready;
++	chip->waitfunc = amb_nand_waitfunc;
++	chip->cmdfunc = amb_nand_cmdfunc;
++	chip->options |= NAND_NO_SUBPAGE_WRITE;
++	if (of_get_nand_on_flash_bbt(np)) {
++		printk(KERN_INFO "ambarella_nand: Use On Flash BBT\n");
++		chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
++	}
++
++	nand_info->mtd.priv = chip;
++	nand_info->mtd.owner = THIS_MODULE;
++
++	return 0;
++}
++
++static int ambarella_nand_init_chipecc(struct ambarella_nand_info *nand_info)
++{
++	struct nand_chip *chip = &nand_info->chip;
++	struct mtd_info	*mtd = &nand_info->mtd;
++	int errorCode = 0;
++
++	/* sanity check */
++	BUG_ON(nand_info->ecc_bits != 1
++		&& nand_info->ecc_bits != 6
++		&& nand_info->ecc_bits != 8);
++	BUG_ON(mtd->writesize != 2048 && mtd->writesize != 512);
++	BUG_ON(nand_info->ecc_bits == 8 && mtd->oobsize < 128);
++
++	chip->ecc.mode = NAND_ECC_HW;
++	chip->ecc.strength = nand_info->ecc_bits;
++
++	switch (nand_info->ecc_bits) {
++	case 8:
++		chip->ecc.size = 512;
++		chip->ecc.bytes = 13;
++		chip->ecc.layout = &amb_oobinfo_2048_dsm_ecc8;
++		nand_info->soft_bch_extra_size = 19;
++		break;
++	case 6:
++		chip->ecc.size = 512;
++		chip->ecc.bytes = 10;
++		chip->ecc.layout = &amb_oobinfo_2048_dsm_ecc6;
++		nand_info->soft_bch_extra_size = 6;
++		break;
++	case 1:
++		chip->ecc.size = 512;
++		chip->ecc.bytes = 5;
++		if (mtd->writesize == 2048)
++			chip->ecc.layout = &amb_oobinfo_2048;
++		else
++			chip->ecc.layout = &amb_oobinfo_512;
++		break;
++	}
++
++	if (nand_amb_is_sw_bch(nand_info)) {
++		errorCode = ambarella_nand_init_soft_bch(nand_info);
++		if (errorCode < 0)
++			return errorCode;
++		/* bootloader may have enabled hw BCH, we must disable it here */
++		nand_amb_enable_dsm(nand_info);
++	}
++
++	chip->ecc.hwctl = amb_nand_hwctl;
++	chip->ecc.calculate = amb_nand_calculate_ecc;
++	chip->ecc.correct = amb_nand_correct_data;
++	chip->ecc.write_oob = amb_nand_write_oob_std;
++
++	return 0;
++}
++
++static int ambarella_nand_get_resource(
++	struct ambarella_nand_info *nand_info, struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct resource *res;
++	int errorCode = 0;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "No mem resource for fio_reg!\n");
++		errorCode = -ENXIO;
++		goto nand_get_resource_err_exit;
++	}
++
++	nand_info->regbase =
++		devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (!nand_info->regbase) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		errorCode = -ENOMEM;
++		goto nand_get_resource_err_exit;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++	if (!res) {
++		dev_err(&pdev->dev, "No mem resource for fdma_reg!\n");
++		errorCode = -ENXIO;
++		goto nand_get_resource_err_exit;
++	}
++
++	nand_info->fdmaregbase =
++		devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (!nand_info->fdmaregbase) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		errorCode = -ENOMEM;
++		goto nand_get_resource_err_exit;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
++	if (!res) {
++		dev_err(&pdev->dev, "No mem resource for fifo base!\n");
++		errorCode = -ENXIO;
++		goto nand_get_resource_err_exit;
++	}
++	nand_info->dmabase = res->start;
++
++	nand_info->cmd_irq = platform_get_irq(pdev, 0);
++	if (nand_info->cmd_irq < 0) {
++		dev_err(&pdev->dev, "no irq for cmd_irq!\n");
++		errorCode = -ENODEV;
++		goto nand_get_resource_err_exit;
++	}
++
++	nand_info->dma_irq = platform_get_irq(pdev, 1);
++	if (nand_info->dma_irq < 0) {
++		dev_err(&pdev->dev, "no irq for dma_irq!\n");
++		errorCode = -ENODEV;
++		goto nand_get_resource_err_exit;
++	}
++
++	nand_info->fdma_irq = platform_get_irq(pdev, 2);
++	if (nand_info->fdma_irq < 0) {
++		dev_err(&pdev->dev, "no irq for fdma_irq!\n");
++		errorCode = -ENODEV;
++		goto nand_get_resource_err_exit;
++	}
++
++	nand_info->nand_wp = !!of_find_property(np, "amb,enable-wp", NULL);
++
++	errorCode = of_property_read_u32_array(np, "amb,timing",
++			nand_info->timing, 6);
++	if (errorCode < 0) {
++		dev_dbg(&pdev->dev, "No timing defined!\n");
++		memset(nand_info->timing, 0x0, sizeof(nand_info->timing));
++	}
++
++	nand_info->pllx2 = !!of_find_property(np, "amb,use-2x-pll", NULL);
++
++	nand_info->ecc_bits = 0;
++	of_property_read_u32(np, "amb,soft-ecc", &nand_info->ecc_bits);
++	if (nand_info->ecc_bits > 0)
++		nand_info->soft_ecc = true;
++
++	ambarella_nand_init_hw(nand_info);
++
++	errorCode = request_irq(nand_info->cmd_irq, nand_fiocmd_isr_handler,
++			IRQF_SHARED | IRQF_TRIGGER_HIGH,
++			"fio_cmd_irq", nand_info);
++	if (errorCode < 0) {
++		dev_err(&pdev->dev, "Could not register fio_cmd_irq %d!\n",
++			nand_info->cmd_irq);
++		goto nand_get_resource_err_exit;
++	}
++
++	errorCode = request_irq(nand_info->dma_irq, nand_fiodma_isr_handler,
++			IRQF_SHARED | IRQF_TRIGGER_HIGH,
++			"fio_dma_irq", nand_info);
++	if (errorCode < 0) {
++		dev_err(&pdev->dev, "Could not register fio_dma_irq %d!\n",
++			nand_info->dma_irq);
++		goto nand_get_resource_free_fiocmd_irq;
++	}
++
++	errorCode = request_irq(nand_info->fdma_irq, ambarella_fdma_isr_handler,
++			IRQF_SHARED | IRQF_TRIGGER_HIGH,
++			"fdma_irq", nand_info);
++	if (errorCode < 0) {
++		dev_err(&pdev->dev, "Could not register fdma_irq %d!\n",
++			nand_info->dma_irq);
++		goto nand_get_resource_free_fiodma_irq;
++	}
++
++	return 0;
++
++nand_get_resource_free_fiodma_irq:
++	free_irq(nand_info->dma_irq, nand_info);
++
++nand_get_resource_free_fiocmd_irq:
++	free_irq(nand_info->cmd_irq, nand_info);
++
++nand_get_resource_err_exit:
++	return errorCode;
++}
++
++static void ambarella_nand_put_resource(struct ambarella_nand_info *nand_info)
++{
++	free_irq(nand_info->fdma_irq, nand_info);
++	free_irq(nand_info->dma_irq, nand_info);
++	free_irq(nand_info->cmd_irq, nand_info);
++}
++
++static int ambarella_nand_probe(struct platform_device *pdev)
++{
++	int					errorCode = 0;
++	struct ambarella_nand_info		*nand_info;
++	struct mtd_info				*mtd;
++	struct mtd_part_parser_data		ppdata = {};
++
++	nand_info = kzalloc(sizeof(struct ambarella_nand_info), GFP_KERNEL);
++	if (nand_info == NULL) {
++		dev_err(&pdev->dev, "kzalloc for nand nand_info failed!\n");
++		errorCode = - ENOMEM;
++		goto ambarella_nand_probe_exit;
++	}
++
++	nand_info->dev = &pdev->dev;
++	spin_lock_init(&nand_info->controller.lock);
++	init_waitqueue_head(&nand_info->controller.wq);
++	init_waitqueue_head(&nand_info->wq);
++	sema_init(&nand_info->system_event_sem, 1);
++	atomic_set(&nand_info->irq_flag, 0x7);
++
++	nand_info->dmabuf = dma_alloc_coherent(nand_info->dev,
++		AMBARELLA_NAND_DMA_BUFFER_SIZE,
++		&nand_info->dmaaddr, GFP_KERNEL);
++	if (nand_info->dmabuf == NULL) {
++		dev_err(&pdev->dev, "dma_alloc_coherent failed!\n");
++		errorCode = -ENOMEM;
++		goto ambarella_nand_probe_free_info;
++	}
++	BUG_ON(nand_info->dmaaddr & 0x7);
++
++	errorCode = ambarella_nand_get_resource(nand_info, pdev);
++	if (errorCode < 0)
++		goto ambarella_nand_probe_free_dma;
++
++	ambarella_nand_init_chip(nand_info, pdev->dev.of_node);
++
++	mtd = &nand_info->mtd;
++	errorCode = nand_scan_ident(mtd, 1, NULL);
++	if (errorCode)
++		goto ambarella_nand_probe_mtd_error;
++
++	errorCode = ambarella_nand_init_chipecc(nand_info);
++	if (errorCode)
++		goto ambarella_nand_probe_mtd_error;
++
++	errorCode = ambarella_nand_config_flash(nand_info);
++	if (errorCode)
++		goto ambarella_nand_probe_mtd_error;
++
++	errorCode = nand_scan_tail(mtd);
++	if (errorCode)
++		goto ambarella_nand_probe_mtd_error;
++
++	mtd->name = "amba_nand";
++
++	ppdata.of_node = pdev->dev.of_node;
++	errorCode = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
++	if (errorCode < 0)
++		goto ambarella_nand_probe_mtd_error;
++
++	platform_set_drvdata(pdev, nand_info);
++
++	nand_info->system_event.notifier_call = ambarella_nand_system_event;
++	ambarella_register_event_notifier(&nand_info->system_event);
++
++	return 0;
++
++ambarella_nand_probe_mtd_error:
++	ambarella_nand_put_resource(nand_info);
++
++ambarella_nand_probe_free_dma:
++	dma_free_coherent(nand_info->dev,
++		AMBARELLA_NAND_DMA_BUFFER_SIZE,
++		nand_info->dmabuf, nand_info->dmaaddr);
++
++ambarella_nand_probe_free_info:
++	kfree(nand_info);
++
++ambarella_nand_probe_exit:
++
++	return errorCode;
++}
++
++static int ambarella_nand_remove(struct platform_device *pdev)
++{
++	int					errorCode = 0;
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = (struct ambarella_nand_info *)platform_get_drvdata(pdev);
++
++	if (nand_info) {
++		ambarella_unregister_event_notifier(&nand_info->system_event);
++
++		nand_release(&nand_info->mtd);
++
++		ambarella_nand_put_resource(nand_info);
++
++		dma_free_coherent(nand_info->dev,
++			AMBARELLA_NAND_DMA_BUFFER_SIZE,
++			nand_info->dmabuf, nand_info->dmaaddr);
++
++		kfree(nand_info);
++	}
++
++	return errorCode;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_nand_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	int					errorCode = 0;
++	struct ambarella_nand_info		*nand_info;
++
++	nand_info = platform_get_drvdata(pdev);
++	nand_info->suspend = 1;
++	disable_irq(nand_info->dma_irq);
++	disable_irq(nand_info->cmd_irq);
++
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++		__func__, errorCode, state.event);
++
++	return errorCode;
++}
++
++static int ambarella_nand_resume(struct platform_device *pdev)
++{
++	int					errorCode = 0;
++	struct ambarella_nand_info		*nand_info;
++	struct mtd_info				*mtd;
++
++	nand_info = platform_get_drvdata(pdev);
++	ambarella_nand_init_hw(nand_info);
++	nand_info->suspend = 0;
++	enable_irq(nand_info->dma_irq);
++	enable_irq(nand_info->cmd_irq);
++	mtd = &nand_info->mtd;
++	errorCode = nand_scan_tail(mtd);
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
++
++	return errorCode;
++}
++#endif
++
++static const struct of_device_id ambarella_nand_of_match[] = {
++	{.compatible = "ambarella,nand", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_nand_of_match);
++
++static struct platform_driver amb_nand_driver = {
++	.probe		= ambarella_nand_probe,
++	.remove		= ambarella_nand_remove,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_nand_suspend,
++	.resume		= ambarella_nand_resume,
++#endif
++	.driver = {
++		.name	= "ambarella-nand",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_nand_of_match,
++	},
++};
++module_platform_driver(amb_nand_driver);
++
++MODULE_AUTHOR("Cao Rongrong & Chien-Yang Chen");
++MODULE_DESCRIPTION("Ambarella Media processor NAND Controller Driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/mtd/nand/ambarella_spinand.c b/drivers/mtd/nand/ambarella_spinand.c
+new file mode 100644
+index 00000000..a7c5f654
+--- /dev/null
++++ b/drivers/mtd/nand/ambarella_spinand.c
+@@ -0,0 +1,1414 @@
++/*
++ * drivers/mtd/ambarella_spinand.c
++ *
++ * History:
++ *    2015/10/26 - [Ken He] created file
++ *
++ * Copyright (C) 2014-2018, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include "ambarella_spinand.h"
++
++#define	MAX_WAIT_JIFFIES               (40 * HZ)
++#define MAX_WAIT_ERASE_JIFFIES         ((HZ * 400)/1000)
++#define AVERAGE_WAIT_JIFFIES           ((HZ * 20)/1000)
++
++#define CACHE_BUF	(2176)
++
++static struct nand_ecclayout ecc_layout_2KB_8bit = {
++       .eccbytes = 64,
++       .eccpos = {
++               64, 65, 66, 67, 68, 69, 70, 71,
++               72, 73, 74, 75, 76, 77, 78, 79,
++			   80, 81, 82, 83, 84, 85, 86, 87,
++			   88, 89, 90, 91, 92, 93, 94, 95,
++			   96, 97, 98, 99, 100, 101, 102, 103,
++			   104, 105, 106, 107, 108, 109, 110, 111,
++			   112, 113, 114, 115, 116, 117, 118, 119,
++			   120, 121, 122, 123, 124, 125, 126, 127
++       },
++       .oobfree = { {1, 63} }
++};
++
++/****************************************************************************/
++static inline struct amb_spinand *mtd_to_amb(struct mtd_info *mtd)
++{
++    return container_of(mtd, struct amb_spinand, mtd);
++}
++
++/* mtd_to_state - obtain the spinand state from the mtd info provided */
++static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
++{
++	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++	struct spinand_state *state = (struct spinand_state *)flash->priv;
++
++	return state;
++}
++/****************************************************************************/
++
++static int ambspinand_send_cmd(struct amb_spinand *flash, u32 cmd, u32 dummy_len, u32 data, u32 len)
++{
++    u32 tmp = 0;
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, dummy_len);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, len);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = amba_readl(flash->regbase + REG0C);
++    REGPREP(tmp, REG0C_CMD0_MASK, REG0C_CMD0_SHIFT, cmd);
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    if(len){
++        tmp = data;
++        amba_writel(flash->regbase + REG14, tmp);
++    }
++
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG30, tmp);
++
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG3C, tmp);
++
++    tmp = amba_readl(flash->regbase + REG50);
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG38);
++        if (REGDUMP(tmp, REG38_DATALENREACHINTR_MASK, REG38_DATALENREACHINTR_SHIFT) == 1){
++            return 0;
++        }
++    }
++    return -1;
++}
++
++static int ambspinand_read_reg(struct amb_spinand *flash, u32 datalen, u32 reg, u8 *value)
++{
++    u32 tmp = 0;
++    int i;
++
++    tmp = amba_readl(flash->regbase + REG28);
++    for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
++        amba_readb(flash->regbase + REG200);
++        tmp = amba_readl(flash->regbase + REG28);
++    }
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++    REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 1);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = reg;
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG10, tmp);
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG28);
++        if(REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT) == datalen){
++            break;
++        }
++    }
++
++    for (i = 0; i < datalen; i++){
++        *(value+i) = amba_readb(flash->regbase + REG200);
++    }
++    return 0;
++}
++
++static int ambspinand_read_feature(struct amb_spinand *flash, u32 cmd, u32 datalen, u32 reg, u8 *value)
++{
++    u32 tmp = 0;
++    int i;
++
++    tmp = amba_readl(flash->regbase + REG28);
++    for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
++        amba_readb(flash->regbase + REG200);
++        tmp = amba_readl(flash->regbase + REG28);
++    }
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 1);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++    REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 1);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = cmd;
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG10, tmp);
++    tmp = reg;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG28);
++        if(REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT) == datalen){
++            break;
++        }
++    }
++
++    for (i = 0; i < datalen; i++){
++        *(value+i) = amba_readb(flash->regbase + REG200);
++    }
++    return 0;
++}
++
++static int ambspinand_set_feature(struct amb_spinand *flash, u32 cmd, u32 datalen, u32 reg, u8 value)
++{
++    u32 tmp = 0;
++/*
++    tmp = amba_readl(flash->regbase + REG28);
++    for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
++        amba_readb(flash->regbase + REG200);
++        tmp = amba_readl(flash->regbase + REG28);
++    }
++*/
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 1);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
++    REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = cmd;
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = 0x0;
++    amba_writel(flash->regbase + REG10, tmp);
++    tmp = reg;
++    amba_writel(flash->regbase + REG14, tmp);
++
++	amba_writeb(flash->regbase + REG100, value);
++    tmp = 0;
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++	for (;;){
++            tmp = amba_readl(flash->regbase + REG24);
++            if(REGDUMP(tmp, REG24_TXFIFOLV_MASK, REG24_TXFIFOLV_SHIFT) == 0){
++                return 0;
++            }
++            udelay(100);//must delay
++    }
++
++    return 0;
++}
++
++static int ambspi_dma_config(struct amb_spinand *flash)
++{
++     flash->dmabuf = dma_alloc_coherent(flash->dev, AMBA_SPINOR_DMA_BUFF_SIZE,
++                     &flash->dmaaddr, GFP_KERNEL);
++     if (flash->dmabuf == NULL){
++        dev_err(flash->dev,  "dma_alloc_coherent failed!\n");
++        return -ENOMEM;
++     }
++     return 0;
++}
++
++static int ambspinand_prog_page(struct amb_spinand *flash, u16 byte_id, u8 *buf, u32 len)
++{
++    int done;
++    u32 tmp = 0;
++
++    amba_writel(flash->dmaregbase + 0x00,  0x1a800000);// DMA_ch0_control
++    amba_writel(flash->dmaregbase + 0x0c,  0x0);
++    amba_writel(flash->dmaregbase + 0x04,  flash->dmaaddr + byte_id);// DMA_ch0_src_addr
++    amba_writel(flash->dmaregbase + 0x08,  (u32)(flash->regbase + REG100));// DMA_ch0_dest_addr
++    amba_writel(flash->dmaregbase + 0x00,  0x9a800000|len);// DMA_ch0_control
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
++    //REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
++    //REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
++	REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 2);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = flash->command[0];
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG30_DATAREACH_MASK, REG30_DATAREACH_SHIFT, 1);
++    amba_writel(flash->regbase + REG30, tmp);
++
++    tmp = byte_id;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, (256-32));
++    amba_writel(flash->regbase + REG1C, tmp);
++
++    tmp = amba_readl(flash->regbase + REG18);
++    REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 1);
++    REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
++    amba_writel(flash->regbase + REG18, tmp);
++
++    do {
++        tmp = amba_readl(flash->regbase + REG2C);
++        done = REGDUMP(tmp, REG2C_TXFIFOEMP_MASK, REG2C_TXFIFOEMP_SHIFT);
++    }while (done != 0x0);
++
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG3C, tmp);
++
++    tmp = amba_readl(flash->regbase + REG50);
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG38);
++        if (REGDUMP(tmp,
++                REG38_DATALENREACHINTR_MASK,
++                REG38_DATALENREACHINTR_SHIFT) == 1){
++            return 0;
++        }
++    }
++    return -1;
++}
++
++static int ambspinand_read_page(struct amb_spinand *flash, u32 offset, u8 *rbuf,
++                            u32 len)
++{
++    u32 tmp = 0;
++
++    amba_writel(flash->dmaregbase + 0x10,  0x2a800000);// DMA_ch1_control
++    amba_writel(flash->dmaregbase + 0x1c,  0x0);
++    amba_writel(flash->dmaregbase + 0x14,  (u32)(flash->regbase + REG200));// DMA_ch1_src_addr
++    amba_writel(flash->dmaregbase + 0x18,  flash->dmaaddr);// DMA_ch1_dest_addr
++    amba_writel(flash->dmaregbase + 0x10,  0xaa800000 | len);// DMA_ch1_control
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
++    //REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
++    //REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
++	REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 3);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++
++    tmp = flash->command[0];
++    amba_writel(flash->regbase + REG0C, tmp);
++
++    tmp = offset;
++    amba_writel(flash->regbase + REG14, tmp);
++
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG3C, tmp);
++
++    tmp = (32-1); // must use word.can't use rxfifothlv
++    amba_writel(flash->regbase + REG20, tmp);
++
++    tmp = amba_readl(flash->regbase + REG18);
++    REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 1);
++    REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
++    amba_writel(flash->regbase + REG18, tmp);
++
++    tmp = amba_readl(flash->regbase + REG50);
++    REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
++    amba_writel(flash->regbase + REG50, tmp);
++
++    for (;;){
++        tmp = amba_readl(flash->regbase + REG38);
++        if(REGDUMP(tmp,
++                REG38_DATALENREACHINTR_MASK,
++                REG38_DATALENREACHINTR_SHIFT) == 1){
++            return 0;
++        }
++        udelay(10);
++    }
++    return -1;
++}
++#if 0
++static u32 get_ssi3_freq_hz(void)
++{
++	#define PLL_OUT_ENET   300000000
++	u32 val;
++
++	val = amba_rct_readl(CG_SSI3_REG);
++	if (val & 0x01000000)
++		return 0;
++
++	if (val == 0)
++		val = 1;
++
++	//return (clk_get_rate(clk_get(NULL, "gclk_core")) << 1) / val;
++	return (PLL_OUT_ENET) / val;
++}
++#endif
++static int ambspinand_init(struct amb_spinand *flash)
++{
++    u32 tmp = 0;
++#if 0
++	u32 divider;
++	divider = get_ssi3_freq_hz() / flash->clk;
++    tmp = amba_readl(flash->regbase + REG08);
++    REGPREP(tmp, REG08_CHIPSEL_MASK, REG08_CHIPSEL_SHIFT, ~(1 << SPINOR_DEV));
++    REGPREP(tmp, REG08_CLKDIV_MASK, REG08_CLKDIV_SHIFT, divider);
++    REGPREP(tmp, REG08_FLOWCON_MASK, REG08_FLOWCON_SHIFT, 1);
++    REGPREP(tmp, REG08_HOLDPIN_MASK, REG08_HOLDPIN_SHIFT, 3);
++    amba_writel(flash->regbase + REG08, tmp);
++
++    tmp = amba_readl(flash->regbase + REG00);
++    REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
++    REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
++    REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
++    amba_writel(flash->regbase + REG00, tmp);
++
++    tmp = amba_readl(flash->regbase + REG04);
++    REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
++    REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
++    REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
++    REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
++    REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
++    REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
++    amba_writel(flash->regbase + REG04, tmp);
++#endif
++    tmp = 0x20;
++    amba_writel(flash->regbase + REG30, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG40_TXFIFORESET_MASK, REG40_TXFIFORESET_SHIFT, 1);
++    amba_writel(flash->regbase + REG40, tmp);
++    tmp = 0;
++    REGPREP(tmp, REG44_RXFIFORESET_MASK, REG44_RXFIFORESET_SHIFT, 1);
++    amba_writel(flash->regbase + REG44, tmp);
++
++    /* after reset fifo, the 0x28 will become 0x10,
++    *so , read REG200 times to clear the 0x28,  this is a bug in hardware
++    */
++	while (amba_readl(flash->regbase + REG28) != 0) {
++        tmp = amba_readl(flash->regbase + REG200);
++    }
++
++    tmp = 0;
++    REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, 0x7f);
++    amba_writel(flash->regbase + REG1C, tmp);
++
++    tmp = 0;
++    REGPREP(tmp, REG20_RXFIFOLV_MASK, REG20_RXFIFOLV_SHIFT, 0x7f);
++    amba_writel(flash->regbase + REG20, tmp);
++
++    return 0;
++}
++/* spi nand function end */
++
++/****************************************************************************/
++/*
++ * spinand_write_enable - send command to enable write or erase of
++ * the nand cells.
++ * Before one can write or erase the nand cells, the write enable
++ * has to be set. After write or erase, the write enable bit is
++ * automatically cleared.
++ */
++static int spinand_write_enable(struct amb_spinand *flash)
++{
++    int ret;
++
++	flash->command[0] = SPI_NAND_WRITE_ENABLE;
++	ret = ambspinand_send_cmd(flash, flash->command[0], 0, 0, 0);
++	if (ret < 0) {
++		   dev_err(flash->dev, "Write Enable SPI NAND failed!\n");
++	}
++	return ret;
++}
++
++/*
++ * spinand_get_feature - send command to get feature register
++ * spinand_set_feature - send command to set feature register
++ *
++ * The GET FEATURES (0Fh) and SET FEATURES (1Fh) commands are used to
++ * alter the device behavior from the default power-on behavior.
++ * These commands use a 1-byte feature address to determine which feature
++ * is to be read or modified
++ */
++static int spinand_get_feature(struct amb_spinand *flash, u8 feature_reg,
++                                                               u8 *value)
++{
++	u32 cmd;
++	int ret;
++
++	cmd = SPI_NAND_GET_FEATURE_INS;
++
++	/* Check the register address */
++	if (feature_reg != SPI_NAND_PROTECTION_REG_ADDR &&
++		feature_reg != SPI_NAND_FEATURE_EN_REG_ADDR &&
++		feature_reg != SPI_NAND_STATUS_REG_ADDR &&
++		feature_reg != SPI_NAND_DS_REG_ADDR)
++			return -1;
++
++	ret = ambspinand_read_feature(flash, cmd, 1, feature_reg, value);
++	if (ret < 0)
++		dev_err(flash->dev, "Error %d read feature reg.\n", ret);
++	return ret;
++}
++
++static int spinand_set_feature(struct amb_spinand *flash, u8 feature_reg,
++                                                               u8 value)
++{
++	int ret;
++	u32 cmd;
++
++	cmd = SPI_NAND_SET_FEATURE;
++
++	/* Check the register address */
++	if (feature_reg != SPI_NAND_PROTECTION_REG_ADDR &&
++		feature_reg != SPI_NAND_FEATURE_EN_REG_ADDR &&
++		feature_reg != SPI_NAND_STATUS_REG_ADDR &&
++		feature_reg != SPI_NAND_DS_REG_ADDR)
++			return -1;
++
++	ret = ambspinand_set_feature(flash, cmd, 1, feature_reg, value);
++	if (ret < 0)
++		dev_err(flash->dev, "Error %d set feture reg.\n", ret);
++
++	return ret;
++}
++/*
++ * spinand_get_status
++ * spinand_get_protection
++ * spinand_get_feature_en
++ * spinand_get_driver_strength
++ *
++ * Read the specific feature register using spinand_get_feature
++ */
++static inline int
++spinand_get_status(struct amb_spinand *flash, u8 *value)
++{
++	return
++	spinand_get_feature(flash, SPI_NAND_STATUS_REG_ADDR, value);
++}
++static inline int
++spinand_get_protection(struct amb_spinand *flash, u8 *value)
++{
++	return
++	spinand_get_feature(flash, SPI_NAND_PROTECTION_REG_ADDR, value);
++}
++static inline int
++spinand_get_feature_en(struct amb_spinand *flash, u8 *value)
++{
++	return
++	spinand_get_feature(flash, SPI_NAND_FEATURE_EN_REG_ADDR, value);
++}
++static inline int
++spinand_get_driver_strength(struct amb_spinand *flash, u8 *value)
++{
++	return
++	spinand_get_feature(flash, SPI_NAND_DS_REG_ADDR, value);
++}
++/*
++ * spinand_set_status
++ * spinand_set_protection
++ * spinand_set_feature_en
++ *
++ * Set the specific feature register using spinand_set_feature
++ */
++static inline int
++spinand_set_status(struct amb_spinand *flash, u8 value)
++{
++	return
++	spinand_set_feature(flash, SPI_NAND_STATUS_REG_ADDR, value);
++}
++static inline int
++spinand_set_protection(struct amb_spinand *flash, u8 value)
++{
++	return
++	spinand_set_feature(flash, SPI_NAND_PROTECTION_REG_ADDR, value);
++}
++static inline int
++spinand_set_feature_en(struct amb_spinand *flash, u8 value)
++{
++	return
++	spinand_set_feature(flash, SPI_NAND_FEATURE_EN_REG_ADDR, value);
++}
++static inline int
++spinand_set_driver_strength(struct amb_spinand *flash, u8 value)
++{
++	return
++	spinand_set_feature(flash, SPI_NAND_DS_REG_ADDR, value);
++}
++/*
++ * is_spinand_busy - check the operation in progress bit and return
++ * if NAND chip is busy or not.
++ * This function checks the Operation In Progress (OIP) bit to
++ * determine whether the NAND memory is busy with a program execute,
++ * page read, block erase or reset command.
++ */
++static inline int is_spinand_busy(struct amb_spinand *flash)
++{
++	u8 status;
++	int ret;
++
++	/* Read the status register and check the OIP bit */
++	ret = spinand_get_status(flash, &status);
++	if (ret)
++		return ret;
++
++	if (status & SPI_NAND_OIP)
++		return 1;
++	else
++		return 0;
++}
++
++/* wait_execution_complete - wait for the current operation to finish */
++static inline int wait_execution_complete(struct amb_spinand *flash,
++                                                       u32 timeout)
++{
++	int ret;
++	unsigned long deadline = jiffies + timeout;
++
++	do {
++		ret = is_spinand_busy(flash);
++		if (!ret)
++			return 0;
++		if (ret < 0)
++			return ret;
++	} while (!time_after_eq(jiffies, deadline));
++
++	return -1;
++}
++
++static int spinand_enable_ecc(struct amb_spinand *flash)
++{
++	uint8_t feature_reg = 0;
++	int ret = 0;
++
++	ret = spinand_get_feature_en(flash, &feature_reg);
++	if (ret < 0)
++		return ret;
++	return spinand_set_feature_en(flash, feature_reg | SPI_NAND_ECC_EN);
++}
++#if 0
++static int spinand_disable_ecc(struct amb_spinand *flash)
++{
++	uint8_t feature_reg = 0;
++	int ret = 0;
++
++	ret = spinand_get_feature_en(flash, &feature_reg);
++	if (ret < 0)
++		return ret;
++	return spinand_set_feature_en(flash, feature_reg & (~SPI_NAND_ECC_EN));
++}
++#endif
++/*
++ * spinand_read_id - Read SPI nand ID
++ * Byte 0: Manufacture ID
++ * Byte 1: Device ID 1
++ * Byte 2: Device ID 2
++ */
++static int spinand_read_id(struct amb_spinand *flash, u8 *id)
++{
++	int ret;
++	u8 nand_id[3];
++	u32 cmd;
++
++	cmd = SPI_NAND_READ_ID;
++	ret = ambspinand_read_reg(flash,3, cmd, nand_id);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d reading id\n", ret);
++		return ret;
++	}
++	id[0] = nand_id[0];
++	id[1] = nand_id[1];
++	id[2] = nand_id[2];
++
++	return ret;
++}
++
++/* spinand_reset - send RESET command to NAND device */
++static void spinand_reset(struct amb_spinand *flash)
++{
++	int ret;
++
++	flash->command[0] = SPI_NAND_RESET;
++	ret = ambspinand_send_cmd(flash, flash->command[0], 0, 0, 0);
++	if (ret < 0) {
++		   dev_err(flash->dev, "Reset SPI NAND failed!\n");
++		   return;
++	}
++
++	/* OIP status can be read from 300ns after reset*/
++	udelay(1);
++	/* Wait for execution to complete */
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0)
++			dev_err(flash->dev, "%s: Wait execution complete failed!\n",
++				__func__);
++		else
++			dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
++				__func__);
++	}
++}
++
++/*
++ * spinand_erase_block - erase a block
++ * The erase can specify the block to be erased
++ * (block_id >= 0, block_id < no_blocks)
++ * no_blocks depends on the size of the flash
++ * Command sequence: WRITE ENBALE, BLOCK ERASE,
++ * GET FEATURES command to read the status register
++ */
++static int spinand_erase_block(struct amb_spinand *flash, u32 page)
++{
++	int ret;
++	u8 status;
++
++	/* Enable capability of erasing NAND cells */
++	ret = spinand_write_enable(flash);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d on write enable.\n",
++					(int) ret);
++		return ret;
++	}
++
++	/* Set up command buffer. */
++	flash->command[0] = SPI_NAND_BLOCK_ERASE_INS;
++	ambspinand_send_cmd(flash, flash->command[0], 0, page, 3);
++
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when erasing block.\n",
++					(int) ret);
++		return ret;
++	}
++
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0) {
++			dev_err(flash->dev, "%s: Wait execution complete failed!\n",
++					__func__);
++			return ret;
++		} else {
++			dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
++					__func__);
++			return -1;
++		}
++	}
++
++	/* Check status register for erase fail bit */
++	ret = spinand_get_status(flash, &status);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d reading status register.\n",
++					(int) ret);
++		return ret;
++	}
++	if (status & SPI_NAND_EF) {
++		dev_err(flash->dev, "Erase fail on block %d\n", (page/64));
++		return -1;
++	}
++	return 0;
++}
++
++/*
++ * spinand_read_page_to_cache - send command to read data from the device and
++ * into the internal cache
++ * The read can specify the page to be read into cache
++ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
++ * no_blocks and no_pages_per_block depend on the size of the flash
++ */
++static int spinand_read_page_to_cache(struct amb_spinand *flash, u32 page_id)
++{
++	int ret = 0;
++	/* Set up command buffer. */
++	flash->command[0] = SPI_NAND_PAGE_READ_INS;
++	ret = ambspinand_send_cmd(flash, flash->command[0], 0, page_id, 3);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when read page 0x%x to cache.\n",
++					page_id, (int) ret);
++    }
++	return ret;
++}
++
++/*
++ * spinand_read_from_cache - send command to read out the data from the
++ * cache register
++ * The read can specify a byte offset within the page
++ * (byte_id >= 0, byte_id < size_of_page)
++ * The read can specify a length to be read (len > 0 && len < size_of_page)
++ * size_of_page depends on the size of the flash
++ */
++static int spinand_read_from_cache(struct amb_spinand *flash,
++                                       u32 byte_id, int len, u8 *rbuf)
++{
++	int ret;
++
++	flash->command[0] = SPI_NAND_READ_CACHE_INS;
++	ret = ambspinand_read_page(flash, byte_id, rbuf, len);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when read from cache.\n",
++			   (int) ret);
++	}
++	return ret;
++}
++
++/*
++ * spinand_read_page - read data from the flash by first reading the
++ * corresponding page into the internal cache and after reading out the
++ * data from it.
++ * The read can specify the page to be read into cache
++ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
++ * no_blocks and no_pages_per_block depend on the size of the flash
++ * The read can specify a byte offset within the page
++ * (byte_id >= 0, byte_id < size_of_page)
++ * The read can specify a length to be read (len > 0 && len < size_of_page)
++ * size_of_page depends on the size of the flash
++ */
++static int spinand_read_page(struct amb_spinand *flash, u32 page_id,
++                               u32 offset, int len, u8 *rbuf)
++{
++	int ret;
++	u8 status;
++
++	/* Read page from device to internal cache */
++	ret = spinand_read_page_to_cache(flash, page_id);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d reading page to cache.\n",
++				ret);
++		return ret;
++	}
++
++	/* Wait until the operation completes or a timeout occurs. */
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0) {
++			dev_err(flash->dev, "%s: Wait execution complete failed!\n",
++						__func__);
++			return ret;
++		} else {
++			dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
++						__func__);
++			return -1;
++		}
++	}
++
++	/* Check status register for uncorrectable errors */
++	ret = spinand_get_status(flash, &status);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d reading status register.\n",
++					(int) ret);
++		return ret;
++	}
++	status &= SPI_NAND_ECC_UNABLE_TO_CORRECT;
++	if (status  == SPI_NAND_ECC_UNABLE_TO_CORRECT) {
++		dev_err(flash->dev, "ECC error reading page %d.\n",
++					page_id);
++		return -1;
++	}
++
++	/* Read page from internal cache to our buffers */
++	ret = spinand_read_from_cache(flash, offset, len, rbuf);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d reading from cache.\n",
++			(int) ret);
++		return ret;
++	}
++
++	return ret;
++}
++
++/*
++ * spinand_program_data_to_cache - send command to program data to cache
++ * The write can specify a byte offset within the page
++ * (byte_id >= 0, byte_id < size_of_page)
++ * The write can specify a length to be written
++ * (len > 0 && len < size_of_page)
++ * size_of_page depends on the size of the flash
++ */
++static int spinand_program_data_to_cache(struct amb_spinand *flash,
++                                               u16 byte_id, int len, u8 *wbuf)
++{
++	int ret = 0;
++
++	flash->command[0] = SPI_NAND_PROGRAM_LOAD_INS;
++	ret = ambspinand_prog_page(flash, byte_id, wbuf, len);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when program to cache.\n",
++			   (int) ret);
++	}
++	return ret;
++}
++
++/*
++ * spinand_program_execute - writes a page from cache to NAND array
++ * The write can specify the page to be programmed
++ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
++ * no_blocks and no_pages_per_block depend on the size of the flash
++ */
++static int spinand_program_execute(struct amb_spinand *flash, u32 page_id)
++{
++	int ret;
++
++	flash->command[0] = SPI_NAND_PROGRAM_EXEC_INS;
++	ret = ambspinand_send_cmd(flash, flash->command[0], 0, page_id, 3);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when read page 0x%x to cache.\n",
++				   page_id, (int) ret);
++	}
++	return ret;
++}
++
++/*
++ * spinand_program_page - secquence to program a page
++ * The write can specify the page to be programmed
++ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
++ * no_blocks and no_pages_per_block depend on the size of the flash
++ * The write can specify a byte offset within the page
++ * (byte_id >= 0, byte_id < size_of_page)
++ * The write can specify a length to be written
++ * (len > 0 && len < size_of_page)
++ * size_of_page depends on the size of the flash
++ * Command sequence: WRITE ENABLE, PROGRAM LOAD, PROGRAM EXECUTE,
++ * GET FEATURE command to read the status
++ */
++static int spinand_program_page(struct amb_spinand *flash,
++               u32 page_id, u16 offset, int len, u8 *buf)
++{
++	int ret;
++	u8 status;
++	uint8_t *wbuf;
++
++	wbuf = buf;
++
++	/* Issue program cache command */
++	ret = spinand_program_data_to_cache(flash, offset, len, wbuf);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when programming cache.\n",
++					(int) ret);
++		return ret;
++	}
++
++	/* Enable capability of programming NAND cells */
++	ret = spinand_write_enable(flash);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d on write enable.\n",
++					(int) ret);
++		return ret;
++	}
++
++	/* Issue program execute command */
++	ret = spinand_program_execute(flash, page_id);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d when programming NAND cells.\n",
++					(int) ret);
++		return ret;
++	}
++
++	/* Wait until the operation completes or a timeout occurs. */
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0) {
++			dev_err(flash->dev, "%s: Wait execution complete failed!\n",
++						__func__);
++			return ret;
++		} else {
++			dev_err(flash->dev, "%s Wait execution complete timedout!\n",
++						__func__);
++			return -1;
++		}
++	}
++
++	/* Check status register for program fail bit */
++	ret = spinand_get_status(flash, &status);
++	if (ret < 0) {
++		dev_err(flash->dev, "Error %d reading status register.\n",
++					(int) ret);
++		return ret;
++	}
++	if (status & SPI_NAND_PF) {
++		dev_err(flash->dev, "Program failed on page %d\n", page_id);
++		return -1;
++	}
++
++	return 0;
++}
++
++static int spinand_write_page_hwecc(struct mtd_info *mtd,
++               struct nand_chip *chip, const uint8_t *buf, int oob_required)
++{
++	chip->write_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
++	return 0;
++}
++
++static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
++               uint8_t *buf, int oob_required, int page)
++{
++	u8 status;
++	int ret;
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++
++	/* Read data and OOB area */
++	chip->read_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
++	if (oob_required)
++		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
++
++	/* Wait until the operation completes or a timeout occurs. */
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0) {
++			pr_err("%s: Wait execution complete failed!\n",
++					__func__);
++			return ret;
++		} else {
++			pr_err("%s: Wait execution complete timedout!\n",
++					__func__);
++			return -1;
++		}
++	}
++
++	/* Check status register for uncorrectable errors */
++	ret = spinand_get_status(flash, &status);
++	if (ret < 0) {
++		pr_err("Error %d reading status register.\n", ret);
++		return ret;
++	}
++	status &= SPI_NAND_ECC_UNABLE_TO_CORRECT;
++	if (status  == SPI_NAND_ECC_UNABLE_TO_CORRECT) {
++		pr_info("ECC error reading page.\n");
++		mtd->ecc_stats.failed++;
++	}
++	if (status && (status != SPI_NAND_ECC_UNABLE_TO_CORRECT))
++		mtd->ecc_stats.corrected++;
++	return 0;
++}
++
++static void amb_spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
++                               int column, int page)
++{
++	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++	struct spinand_state *state = (struct spinand_state *)flash->priv;
++
++	switch (command) {
++		case NAND_CMD_READ1:
++		case NAND_CMD_READ0:
++			state->buf_ptr = 0;
++			spinand_read_page(flash, page, 0, mtd->writesize,
++								flash->dmabuf);
++			break;
++		case NAND_CMD_READOOB:
++			state->buf_ptr = 0;
++			spinand_read_page(flash, page, mtd->writesize, mtd->oobsize,
++								flash->dmabuf);
++			break;
++		case NAND_CMD_RNDOUT:
++			state->buf_ptr = column;
++			break;
++		case NAND_CMD_READID:
++			state->buf_ptr = 0;
++			spinand_read_id(flash, (u8 *)flash->dmabuf);
++			break;
++		case NAND_CMD_PARAM:
++			state->buf_ptr = 0;
++			break;
++		/* ERASE1 performs the entire erase operation*/
++		case NAND_CMD_ERASE1:
++			//printk("spinand erase 1 command page 0x%x \n", page);
++			spinand_erase_block(flash, page);
++			break;
++		case NAND_CMD_ERASE2:
++			//printk("spinand erase 2 command page 0x%x \n", page);
++			break;
++		/* SEQIN sets up the addr buffer and all registers except the length */
++		case NAND_CMD_SEQIN:
++			state->col = column;
++			state->row = page;
++			state->buf_ptr = 0;
++			break;
++		/* PAGEPROG reuses all of the setup from SEQIN and adds the length */
++		case NAND_CMD_PAGEPROG:
++			spinand_program_page(flash, state->row, state->col,
++									state->buf_ptr, flash->dmabuf);
++			break;
++		case NAND_CMD_STATUS:
++			spinand_get_status(flash, flash->dmabuf);
++			if (!(flash->dmabuf[0] & 0x80))
++				flash->dmabuf[0] = 0x80;
++			state->buf_ptr = 0;
++			break;
++		/* RESET command */
++		case NAND_CMD_RESET:
++			spinand_reset(flash);
++			break;
++		default:
++			dev_err(flash->dev, "Command 0x%x not implementd or unknown.\n",
++					command);
++		}
++}
++
++static int ambarella_spinand_get_resource(struct amb_spinand *flash,
++				struct platform_device *pdev)
++{
++    struct resource *res;
++    int errorCode = 0;
++
++    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++    if (!res) {
++        dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
++        errorCode = -ENXIO;
++        goto spinand_get_resource_err_exit;
++    }
++
++    flash->regbase =
++        devm_ioremap(&pdev->dev, res->start, resource_size(res));
++    if (!flash->regbase) {
++        dev_err(&pdev->dev, "devm_ioremap() failed\n");
++        errorCode = -ENOMEM;
++        goto spinand_get_resource_err_exit;
++    }
++
++    res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++    if (!res) {
++        dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
++        errorCode = -ENXIO;
++        goto spinand_get_resource_err_exit;
++    }
++
++    flash->dmaregbase =
++        devm_ioremap(&pdev->dev, res->start, resource_size(res));
++    if (!flash->dmaregbase) {
++        dev_err(&pdev->dev, "devm_ioremap() failed\n");
++        errorCode = -ENOMEM;
++        goto spinand_get_resource_err_exit;
++    }
++
++    return 0;
++
++spinand_get_resource_err_exit:
++    return errorCode;
++}
++
++static int amb_spinand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
++{
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++	int state = chip->state;
++	u32 timeout;
++
++	if (state == FL_ERASING)
++		timeout = MAX_WAIT_ERASE_JIFFIES;
++	else
++		timeout = AVERAGE_WAIT_JIFFIES;
++	return wait_execution_complete(flash, timeout);
++}
++
++static void amb_spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
++{
++	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++	struct spinand_state *state = (struct spinand_state *)flash->priv;
++
++	memcpy(flash->dmabuf + state->buf_ptr, buf, len);
++	state->buf_ptr += len;
++}
++
++static void amb_spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
++{
++	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++	struct spinand_state *state = (struct spinand_state *)flash->priv;
++
++	memcpy(buf, flash->dmabuf + state->buf_ptr, len);
++	state->buf_ptr += len;
++}
++
++static uint8_t amb_spinand_read_byte(struct mtd_info *mtd)
++{
++	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
++	struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
++	struct spinand_state *state = (struct spinand_state *)flash->priv;
++	u8 data;
++
++	data = flash->dmabuf[state->buf_ptr];
++	state->buf_ptr++;
++	return data;
++}
++
++static void amb_spinand_select_chip(struct mtd_info *mtd, int dev)
++{
++}
++
++static int ambarella_spinand_init_chip(struct amb_spinand *flash,
++		struct device_node *np)
++{
++	struct nand_chip *chip = &flash->chip;
++
++	chip->read_byte = amb_spinand_read_byte;
++	chip->write_buf = amb_spinand_write_buf;
++	chip->read_buf = amb_spinand_read_buf;
++	chip->select_chip = amb_spinand_select_chip;
++	chip->waitfunc = amb_spinand_waitfunc;
++	chip->cmdfunc = amb_spinand_cmdfunc;
++	chip->options |= (NAND_CACHEPRG | NAND_NO_SUBPAGE_WRITE);
++	//chip->options |= NAND_CACHEPRG;
++	chip->priv = flash;
++	chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
++
++	flash->mtd.priv = chip;
++	flash->mtd.name = "amba_spinand";
++	flash->mtd.owner = THIS_MODULE;
++	flash->mtd.writebufsize = flash->mtd.writesize;
++	flash->mtd.type = MTD_NANDFLASH;
++
++	return 0;
++}
++
++static int ambarella_spinand_init_chipecc(struct amb_spinand *flash)
++{
++	int ret = 0;
++
++	struct nand_chip *chip = &flash->chip;
++
++	chip->ecc.mode	= NAND_ECC_HW;
++	chip->ecc.size	= 0x200;
++	chip->ecc.bytes	= 16;
++	chip->ecc.steps	= 0x4;
++
++	chip->ecc.strength = 8;
++	chip->ecc.total	= chip->ecc.steps * chip->ecc.bytes;
++	chip->ecc.layout = &ecc_layout_2KB_8bit;
++	chip->ecc.read_page = spinand_read_page_hwecc;
++	chip->ecc.write_page = spinand_write_page_hwecc;
++	ret = spinand_enable_ecc(flash);
++
++	return ret;
++}
++
++static int ambarella_spinand_probe(struct platform_device *pdev)
++{
++	struct mtd_info	*mtd;
++	struct mtd_part_parser_data	ppdata;
++	struct amb_spinand	*flash;
++	struct spinand_state *state;
++	int	errCode = 0;
++
++	flash = kzalloc(sizeof(struct amb_spinand), GFP_KERNEL);
++	if (!flash) {
++		errCode = -ENOMEM;
++		goto ambarella_spinand_probe_exit;
++	}
++
++	state = kzalloc(sizeof(struct spinand_state), GFP_KERNEL);
++	if (!state) {
++		errCode = -ENOMEM;
++		goto ambarella_spinand_probe_free_flash;
++	}
++	flash->priv = state;
++	state->buf_ptr = 0;
++
++    mutex_init(&flash->lock);
++    platform_set_drvdata(pdev, flash);
++    flash->dev = &pdev->dev;
++
++	/* set 50Mhz as default spi clock */
++	flash->clk = 50000000;
++    ambarella_spinand_get_resource(flash, pdev);
++    ambspinand_init(flash);
++
++	ambarella_spinand_init_chipecc(flash);
++	ambarella_spinand_init_chip(flash, pdev->dev.of_node);
++
++	mtd = &flash->mtd;
++
++	flash->command = kzalloc(5, GFP_KERNEL);
++    if(!flash->command) {
++        dev_err((const struct device *)&flash->dev,
++            "SPI NAND driver malloc command error\r\n");
++        errCode = -ENOMEM;
++        goto ambarella_spinand_probe_free_state;
++    }
++	//flash->clk = info->max_clk_hz;
++    ambspinand_init(flash);
++    ambspi_dma_config(flash);
++
++	spinand_set_protection(flash, SPI_NAND_PROTECTED_ALL_UNLOCKED);
++
++	if (nand_scan(mtd, 1))
++		return -ENXIO;
++
++	ppdata.of_node = pdev->dev.of_node;
++	errCode = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, NULL, 0);
++	if (errCode < 0)
++		goto ambarella_spinand_probe_free_command;
++
++    printk("AMBARELLA SPINAND probed \n");
++    return 0;
++
++ambarella_spinand_probe_free_command:
++    kfree(flash->command);
++ambarella_spinand_probe_free_state:
++	kfree(state);
++ambarella_spinand_probe_free_flash:
++    kfree(flash);
++ambarella_spinand_probe_exit:
++    return errCode;
++}
++
++
++static int ambarella_spinand_remove(struct platform_device *pdev)
++{
++	struct amb_spinand    *flash = platform_get_drvdata(pdev);
++	int        status;
++
++	if (flash) {
++		/* Clean up MTD stuff. */
++		status = mtd_device_unregister(&flash->mtd);
++		if (status == 0) {
++			kfree(flash->command);
++			dma_free_coherent(flash->dev,
++				AMBA_SPINOR_DMA_BUFF_SIZE,
++				flash->dmabuf, flash->dmaaddr);
++			kfree(flash);
++		}
++	}
++    return 0;
++}
++
++static void ambarella_spinand_shutdown(struct platform_device *pdev)
++{
++	int ret;
++	struct amb_spinand    *flash = platform_get_drvdata(pdev);
++
++	/* Wait until finished previous write command. */
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0) {
++			dev_err(flash->dev, "%s: Wait execution complete failed!\n",
++					__func__);
++			return;
++		} else
++			dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
++					__func__);
++	}
++	/* Workaround for the spinand software reboot */
++	spinand_read_page_to_cache(flash, 0);
++	ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
++	if (ret) {
++		if (ret < 0)
++			dev_err(flash->dev, "%s: Wait execution complete failed!\n",
++					__func__);
++		else
++			dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
++					__func__);
++	}
++	return;
++}
++
++static const struct of_device_id ambarella_spinand_of_match[] = {
++    {.compatible = "ambarella,spinand", },
++    {},
++};
++MODULE_DEVICE_TABLE(of, ambarella_spinand_of_match);
++
++static struct platform_driver amb_spinand_driver = {
++	.probe = ambarella_spinand_probe,
++	.remove = ambarella_spinand_remove,
++	.driver = {
++		.name = "ambarella-spinand",
++		.owner = THIS_MODULE,
++		.of_match_table = ambarella_spinand_of_match,
++	},
++	.shutdown = ambarella_spinand_shutdown,
++};
++
++module_platform_driver(amb_spinand_driver);
++
++MODULE_AUTHOR("Ken He");
++MODULE_DESCRIPTION("Ambarella Media processor SPI NAND Flash Controller Driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/mtd/nand/ambarella_spinand.h b/drivers/mtd/nand/ambarella_spinand.h
+new file mode 100644
+index 00000000..d00bb4d9
+--- /dev/null
++++ b/drivers/mtd/nand/ambarella_spinand.h
+@@ -0,0 +1,386 @@
++/**
++ * ambarella_spinand.h
++ *
++ * History:
++ *    2015/10/26 - [Ken He] created file
++ *
++ * Copyright 2014-2018 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __LINUX_AMBARELLA_SPINAND_H__
++#define __LINUX_AMBARELLA_SPINAND_H__
++
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/err.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/interrupt.h>
++#include <linux/mutex.h>
++#include <linux/math64.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/mod_devicetable.h>
++
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++#include <linux/of_platform.h>
++
++#include <linux/clk.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmaengine.h>
++#include <plat/dma.h>
++#include <plat/rct.h>
++
++#include <plat/ptb.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/flash.h>
++#include <linux/delay.h>
++
++#define REGPREP(reg,mask,shift,value) (reg=((~mask)&reg)|(value << shift))
++#define REGDUMP(reg,mask,shift) ((reg&mask)>>shift)
++
++#define REG00_DATALEN_SHIFT   0   /*[21:0]    data access length*/
++#define REG00_DATALEN_MASK    0x003fffff
++#define REG00_DUMMYLEN_SHIFT  22  /*[26:22]    dummy cycle length*/
++#define REG00_DUMMYLEN_MASK   0x07c00000
++#define REG00_ADDRLEN_SHIFT   27  /*[29:27]    address length*/
++#define REG00_ADDRLEN_MASK    0x38000000
++#define REG00_CMDLEN_SHIFT    30  /*[31:30]    command length*/
++#define    REG00_CMDLEN_MASK  0xc0000000
++
++#define REG04_READEN_SHIFT   0 /*[0]    data part read mode*/
++#define REG04_READEN_MASK    0x00000001
++#define REG04_WRITEEN_SHIFT  1 /*[1]    data part write mode*/
++#define REG04_WRITEEN_MASK   0x00000002
++#define REG04_RXLANE_SHIFT   9 /*[9] rx lane config*/
++#define REG04_RXLANE_MASK    0x00000200
++#define REG04_DATALANE_SHIFT 10 /*[11:10] number of data lane*/
++#define REG04_DATALANE_MASK  0x00000c00
++#define REG04_ADDRLANE_SHIFT 12 /*[13:12] number of addr lane*/
++#define REG04_ADDRLANE_MASK  0x00003000
++#define REG04_CMDLANE_SHIFT  14 /*[15:14] number of command lane */
++#define REG04_CMDLANE_MASK   0x0000c000
++#define REG04_LSBFRT_SHIFT   24 /*[24]    0-msb first 1-lsb first*/
++#define REG04_LSBFRT_MASK    0x01000000
++#define REG04_DATADTR_SHIFT  28 /*[28]    data double transfer rate*/
++#define REG04_DATADTR_MASK   0x10000000
++#define REG04_DUMMYDTR_SHIFT 29 /*[29]    dummy double transfer rate*/
++#define REG04_DUMMYDTR_MASK  0x20000000
++#define REG04_ADDRDTR_SHIFT  30 /*[30] address double transfer rate*/
++#define REG04_ADDRDTR_MASK   0x40000000
++#define REG04_CMDDTR_SHIFT   31/*[31] command dtr,only reg_clk divider>2*/
++#define REG04_CMDDTR_MASK    0x80000000
++
++#define REG08_RXSPLDELAY_SHIFT   0 /*[4:0]    adjust rx sampling data phase*/
++#define REG08_RXSPLDELAY_MASK    0x0000001f
++#define REG08_CLKDIV_SHIFT       10 /*[17:10]    divide reference clock*/
++#define REG08_CLKDIV_MASK        0x0003fc00
++#define REG08_CHIPSEL_SHIFT      18 /*[25:18]    cen for multiple device 0 for select and vice versa*/
++#define REG08_CHIPSEL_MASK       0x03fc0000
++#define REG08_HOLDSWITCH_SHIFT   26 /*[26]0 for hold switching on switch one ref clock cycle before negative edge*/
++#define REG08_HOLDSWITCH_MASK    0x04000000
++#define REG08_SPICLKPOL_SHIFT    27 /*[27]    clock will remain 1 or 0 in standby mode*/
++#define REG08_SPICLKPOL_MASK     0x08000000
++#define REG08_HOLDPIN_SHIFT      28 /*[30:28]    for flow control purpose*/
++#define REG08_HOLDPIN_MASK       0x70000000
++#define REG08_FLOWCON_SHIFT      31 /*[31]    flow control enable*/
++#define REG08_FLOWCON_MASK       0x80000000
++
++#define REG0C_CMD0_SHIFT 0 /*[7:0]    command for SPI  device*/
++#define REG0C_CMD0_MASK  0x000000ff
++#define REG0C_CMD1_SHIFT 8 /*[15:8]*/
++#define REG0C_CMD1_MASK  0x0000ff00
++#define REG0C_CMD2_SHIFT 16 /*[23:16]*/
++#define REG0C_CMD2_MASK  0x00ff0000
++
++#define REG18_RXDMAEN_SHIFT 0 /*[0]    rx dma enable*/
++#define REG18_RXDMAEN_MASK  0x00000001
++#define REG18_TXDMAEN_SHIFT 1 /*[1]    tx dma enable*/
++#define REG18_TXDMAEN_MASK  0x00000002
++
++#define REG1C_TXFIFOLV_SHIFT  0 /*[8:0]  tx fifo threshold level*/
++#define REG1C_TXFIFOLV_MASK   0x000000ff
++
++#define REG20_RXFIFOLV_SHIFT  0
++#define REG20_RXFIFOLV_MASK   0x000000ff
++
++#define REG24_TXFIFOLV_SHIFT  0
++#define REG24_TXFIFOLV_MASK   0x000000ff
++
++#define REG28_RXFIFOLV_SHIFT 0
++#define REG28_RXFIFOLV_MASK  0x000000ff
++
++#define REG2C_TXFIFONOTFULL_SHIFT 1 /*[1]*/
++#define REG2C_TXFIFONOTFULL_MASK  0x00000002
++#define REG2C_TXFIFOEMP_SHIFT     2 /*[2] tx fifo empty*/
++#define REG2C_TXFIFOEMP_MASK      0x00000004
++#define REG2C_RXFIFONOTEMP_SHIFT  3 /*[3] */
++#define REG2C_RXFIFONOTEMP_MASK   0x00000008
++#define REG2C_RXFIFOFULL_SHIFT    4 /*[4] rx fifo full*/
++#define REG2C_RXFIFOFULL_MASK     0x00000010
++
++#define REG30_TXEMP_SHIFT     0/*[0] tx fifo almost empty*/
++#define REG30_TXEMP_MASK      0x00000001
++#define REG30_TXOVER_SHIFT    1 /*[1]*/
++#define REG30_TXOVER_MASK     0x00000002
++#define REG30_RXUNDER_SHIFT   2/*[2]*/
++#define REG30_RXUNDER_MASK    0x00000004
++#define REG30_RXOVER_SHIFT    3/*[3]*/
++#define REG30_RXOVER_MASK     0x00000008
++#define REG30_RXFULL_SHIFT    4 /*[4]*/
++#define REG30_RXFULL_MASK     0x00000010
++#define REG30_DATAREACH_SHIFT 5 /*[5]*/
++#define REG30_DATAREACH_MASK  0x00000020
++#define REG30_TXUNDER_SHIFT   6/*[6]*/
++#define REG30_TXUNDER_MASK    0x00000040
++
++#define REG38_TXEMPTYINTR_SHIFT     0 /*[0]  tx almost empty*/
++#define REG38_TXEMPTYINTR_MASK      0x00000001
++#define REG38_TXOVERFLOWINTR_SHIFT  1 /*[1] */
++#define REG38_TXOVERFLOWINTR_MASK   0x00000002
++#define REG38_RXUNDERFLOWINTR_SHIFT 2 /*[2]*/
++#define REG38_RXUNDERFLOWINTR_MASK  0x00000004
++#define REG38_RXOVERFLOWINTR_SHIFT  3 /*[3]*/
++#define REG38_RXOVERFLOWINTR_MASK   0x00000008
++#define REG38_RXFULLINTR_SHIFT      4 /*[4] rx fifo almost full*/
++#define REG38_RXFULLINTR_MASK        0x00000010
++#define REG38_DATALENREACHINTR_SHIFT 5 /*[5] transaction done interrupt*/
++#define REG38_DATALENREACHINTR_MASK  0x00000020
++#define REG38_TXUNDERFLOWINTR_SHIFT  6 /*[6] */
++#define REG38_TXUNDERFLOWINTR_MASK   0x00000040
++
++#define REG40_TXFIFORESET_SHIFT  0 /*[0] software reset the tx fifo*/
++#define REG40_TXFIFORESET_MASK   0x00000001
++
++#define REG44_RXFIFORESET_SHIFT  0 /*[0]  software reset the rx fifo*/
++#define REG44_RXFIFORESET_MASK   0x00000001
++
++#define REG50_STRTRX_SHIFT 0 /*[0]    start tx or rx*/
++#define REG50_STRTRX_MASK  0x00000001
++
++#define HAS_IMG_PARTS       15
++#define TOTAL_FW_PARTS        (HAS_IMG_PARTS + HAS_NO_IMG_PARTS)
++
++#define REG00 0x00
++#define REG04 0x04
++#define REG08 0x08
++#define REG0C 0x0c
++#define REG10 0x10
++#define REG14 0x14
++#define REG18 0x18
++#define REG1C 0x1c
++#define REG20 0x20
++#define REG24 0x24
++#define REG28 0x28
++#define REG2C 0x2c
++#define REG30 0x30
++#define REG34 0x34
++#define REG38 0x38
++#define REG3C 0x3C
++#define REG40 0x40
++#define REG44 0x44
++#define REG50 0x50
++#define REG100 0x100
++#define REG200 0x200
++#define DMA_CONTROLLER_OFFSET (0xe0005000)
++
++#if defined(CONFIG_SPI_NOR_CHIP_0)
++#define SPINOR_DEV 0
++#elif defined(CONFIG_SPI_NOR_CHIP_1)
++#define SPINOR_DEV 1
++#elif defined(CONFIG_SPI_NOR_CHIP_2)
++#define SPINOR_DEV 2
++#elif defined(CONFIG_SPI_NOR_CHIP_3)
++#define SPINOR_DEV 3
++#else
++#define SPINOR_DEV 0
++#endif
++
++struct amb_spinand {
++    struct device                *dev;
++    unsigned char __iomem        *regbase;
++    unsigned char __iomem        *dmaregbase;
++    dma_addr_t                   dmaaddr;
++    u8                           *dmabuf;
++    int (*write_enable)(struct amb_spinand *flash);
++    int (*wait_till_ready)(struct amb_spinand *flash);
++    struct mutex                 lock;
++    struct mtd_info              mtd;
++    u16                          page_size;
++    u16                          addr_width;
++    u8                           erase_opcode;
++    u8                           *command;
++    u8                           dummy;
++    u32                          addr;
++	u32							 clk;
++    bool                         fast_read;
++	u32							 jedec_id;
++	struct nand_chip			chip;
++	void						*priv;
++};
++//the buffer size must align to 32 and smaller than the max size of DMA
++#define AMBA_SPINOR_DMA_BUFF_SIZE    4096
++
++/* SPI NAND Command Set Definitions */
++enum {
++	SPI_NAND_WRITE_ENABLE			= 0x06,
++	SPI_NAND_WRITE_DISABLE			= 0x04,
++	SPI_NAND_GET_FEATURE_INS		= 0x0F,
++	SPI_NAND_SET_FEATURE			= 0x1F,
++	SPI_NAND_PAGE_READ_INS			= 0x13,
++	SPI_NAND_READ_CACHE_INS			= 0x03,
++	SPI_NAND_FAST_READ_CACHE_INS		= 0x0B,
++	SPI_NAND_READ_CACHE_X2_INS		= 0x3B,
++	SPI_NAND_READ_CACHE_X4_INS		= 0x6B,
++	SPI_NAND_READ_CACHE_DUAL_IO_INS		= 0xBB,
++	SPI_NAND_READ_CACHE_QUAD_IO_INS		= 0xEB,
++	SPI_NAND_READ_ID			= 0x9F,
++	SPI_NAND_PROGRAM_LOAD_INS		= 0x02,
++	SPI_NAND_PROGRAM_LOAD4_INS		= 0x32,
++	SPI_NAND_PROGRAM_EXEC_INS		= 0x10,
++	SPI_NAND_PROGRAM_LOAD_RANDOM_INS	= 0x84,
++	SPI_NAND_PROGRAM_LOAD_RANDOM4_INS	= 0xC4,
++	SPI_NAND_BLOCK_ERASE_INS		= 0xD8,
++	SPI_NAND_RESET				= 0xFF
++};
++
++/* Feature registers */
++enum feature_register {
++	SPI_NAND_PROTECTION_REG_ADDR	= 0xA0,
++	SPI_NAND_FEATURE_EN_REG_ADDR	= 0xB0,
++	SPI_NAND_STATUS_REG_ADDR	= 0xC0,
++	SPI_NAND_DS_REG_ADDR		= 0xD0,
++};
++/*
++ * SR7 - reserved
++ * SR6 - ECC status 2
++ * SR5 - ECC status 1
++ * SR4 - ECC status 0
++ *
++ * ECCS provides ECC status as follows:
++ * 000b = No bit errors were detected during the previous read algorithm.
++ * 001b = bit error was detected and corrected, error bit number < 3.
++ * 010b = bit error was detected and corrected, error bit number = 4.
++ * 011b = bit error was detected and corrected, error bit number = 5.
++ * 100b = bit error was detected and corrected, error bit number = 6.
++ * 101b = bit error was detected and corrected, error bit number = 7.
++ * 110b = bit error was detected and corrected, error bit number = 8.
++ * 111b = bit error was detected and not corrected.
++ *
++ * SR3 - P_Fail Program fail
++ * SR2 - E_Fail Erase fail
++ * SR1 - WEL - Write enable latch
++ * SR0 - OIP - Operation in progress
++ */
++enum {
++	SPI_NAND_ECCS2	= 0x40,
++	SPI_NAND_ECCS1	= 0x20,
++	SPI_NAND_ECCS0	= 0x10,
++	SPI_NAND_PF	= 0x08,
++	SPI_NAND_EF	= 0x04,
++	SPI_NAND_WEL	= 0x02,
++	SPI_NAND_OIP	= 0x01
++};
++
++enum {
++	SPI_NAND_ECC_NO_ERRORS = 0x00,
++	SPI_NAND_ECC_UNABLE_TO_CORRECT =
++		SPI_NAND_ECCS0 | SPI_NAND_ECCS1 | SPI_NAND_ECCS2
++};
++
++/*
++ * Feature enable register description: SPI_NAND_FEATURE_EN_REG_ADDR
++ *
++ * FR7 - OTP protect
++ * FR6 - OTP enable
++ * FR5 - reserved
++ * FR4 - ECC enable
++ * FR3 - reserved
++ * FR2 - reserved
++ * FR1 - reserved
++ * FR0 - Quad operation enable
++ */
++enum {
++	SPI_NAND_QUAD_EN	= 0x01,
++	SPI_NAND_ECC_EN		= 0x10,
++	SPI_NAND_OTP_EN		= 0x40,
++	SPI_NAND_OTP_PRT	= 0x80
++};
++
++/*
++ * Protection register description: SPI_NAND_PROTECTION_REG_ADDR
++ *
++ * BL7 - BRWD
++ * BL6 - reserved
++ * BL5 - Block protect 2
++ * BL4 - Block protect 1
++ * BL3 - Block protect 0
++ * BL2 - INV
++ * BL1 - CMP
++ * BL0 - reserved
++ */
++enum {
++	SPI_NAND_BRWD	= 0x80,
++	SPI_NAND_BP2	= 0x20,
++	SPI_NAND_BP1	= 0x10,
++	SPI_NAND_BP0	= 0x08,
++	SPI_NAND_INV	= 0x04,
++	SPI_NAND_CMP	= 0x02
++};
++
++enum protected_rows {
++	/* All unlocked : 000xx */
++	SPI_NAND_PROTECTED_ALL_UNLOCKED	= 0x00,
++	SPI_NAND_UPPER_1_64_LOCKED	= 0x04,
++	SPI_NAND_LOWER_63_64_LOCKED	= 0x05,
++	SPI_NAND_LOWER_1_64_LOCKED	= 0x06,
++	SPI_NAND_UPPER_63_64_LOCKED	= 0x07,
++	SPI_NAND_UPPER_1_32_LOCKED	= 0x08,
++	SPI_NAND_LOWER_31_32_LOCKED	= 0x09,
++	SPI_NAND_LOWER_1_32_LOCKED	= 0x0A,
++	SPI_NAND_UPPER_31_32_LOCKED	= 0x0B,
++	SPI_NAND_UPPER_1_16_LOCKED	= 0x0C,
++	SPI_NAND_LOWER_15_16_LOCKED	= 0x0D,
++	SPI_NAND_LOWER_1_16_LOCKED	= 0x0E,
++	SPI_NAND_UPPER_15_16_LOCKED	= 0x0F,
++	SPI_NAND_UPPER_1_8_LOCKED	= 0x10,
++	SPI_NAND_LOWER_7_8_LOCKED	= 0x11,
++	SPI_NAND_LOWER_1_8_LOCKED	= 0x12,
++	SPI_NAND_UPPER_7_8_LOCKED	= 0x13,
++	SPI_NAND_UPPER_1_4_LOCKED	= 0x14,
++	SPI_NAND_LOWER_3_4_LOCKED	= 0x15,
++	SPI_NAND_LOWER_1_4_LOCKED	= 0x16,
++	SPI_NAND_UPPER_3_4_LOCKED	= 0x17,
++	SPI_NAND_UPPER_1_2_LOCKED	= 0x18,
++	SPI_NAND_BLOCK_0_LOCKED		= 0x19,
++	SPI_NAND_LOWER_1_2_LOCKED	= 0x1A,
++	SPI_NAND_BLOCK_0_LOCKED1	= 0x1B,
++	/* All locked (default) : 111xx */
++	SPI_NAND_PROTECTED_ALL_LOCKED	= 0x1C,
++
++};
++
++struct spinand_info{
++	struct	nand_ecclayout *ecclayout;
++	void	*priv;
++};
++
++struct spinand_state{
++	u32 col; /* offset in page */
++	u32 row; /* page number */
++	int	buf_ptr;
++};
++
++#endif /* __LINUX_AMBARELLA_SPINAND_H__ */
+diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
+index 683813a4..201808cf 100644
+--- a/drivers/mtd/nand/nand_ids.c
++++ b/drivers/mtd/nand/nand_ids.c
+@@ -44,6 +44,66 @@ struct nand_flash_dev nand_flash_ids[] = {
+ 		{ .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
+ 		  SZ_8K, SZ_8K, SZ_2M, 0, 8, 640},
+ 
++	{"TC58NVG0S3H 1G 3.3V 8-bit",
++		{ .id = {0x98, 0xf1, 0x80, 0x15, 0x72} },
++		  SZ_2K, SZ_128, SZ_128K, 0, 5, 128},
++
++	{"TC58NVG1S3H 2G 3.3V 8-bit",
++		{ .id = {0x98, 0xda, 0x90, 0x15, 0x76} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"S34ML02G2 2G 3.3V 8-bit",
++		{ .id = {0x01, 0xda, 0x90, 0x95, 0x46} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"S34ML04G2 4G 3.3V 8-bit",
++		{ .id = {0x01, 0xdc, 0x90, 0x95, 0x56} },
++		  SZ_2K, SZ_512, SZ_128K, 0, 5, 128},
++
++	{"S34MS02G2 2G 1.8V 8-bit",
++		{ .id = {0x01, 0xaa, 0x90, 0x15, 0x46} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"MT29F2G08ABAFA 2G 3.3V 8-bit",
++		{ .id = {0x2c, 0xda, 0x90, 0x95, 0x04} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"MT29F2G08ABAGA 2G 3.3V 8-bit",
++		{ .id = {0x2c, 0xda, 0x90, 0x95, 0x06} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"H27U2G8F2D 2G 3.3V 8-bit",
++		{ .id = {0xad, 0xda, 0x90, 0x95, 0x46} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"W29N02KV 2G 3.3V 8-bit",
++		{ .id = {0xef, 0xda, 0x10, 0x95, 0x06} },
++		  SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
++
++	{"GD9FU1G8F2A 1G 3.3V 8-bit",
++		{ .id = {0xc8, 0xf1, 0x80, 0x1d, 0x42} },
++		  SZ_2K, SZ_128, SZ_128K, 0, 5, 128},
++
++	{"GD9FS1G8F2A 1G 1.8V 8-bit",
++		{ .id = {0xc8, 0xa1, 0x80, 0x15, 0x42} },
++		  SZ_2K, SZ_128, SZ_128K, 0, 5, 128},
++
++	{"GD5F1GQ4UCY1G SPINAND 1Gb 3.3V 8-bit",
++		{ .id = {0xc8, 0xb1, 0x48} },
++		SZ_2K, SZ_128, SZ_128K, LP_OPTIONS, 3, 128},
++
++	{"GD5F1GQ4UFY1G SPINAND 1Gb 3.3V 8-bit",
++		{ .id = {0xc8, 0xb3, 0x48} },
++		SZ_2K, SZ_128, SZ_128K, LP_OPTIONS, 3, 128},
++
++	{"GD5F2GQ4UCY1G SPINAND 2Gb 3.3V 8-bit",
++		{ .id = {0xc8, 0xb2, 0x48} },
++		SZ_2K, SZ_256, SZ_128K, LP_OPTIONS, 3, 128},
++
++	{"HYF1GQ4UBACAE SPINAND 1Gb 3.3V 8-bit",
++		{ .id = {0xc9, 0x59, 0x1b} },
++		SZ_2K, SZ_128, SZ_128K, LP_OPTIONS, 3, 128},
++
+ 	LEGACY_ID_NAND("NAND 4MiB 5V 8-bit",   0x6B, 4, SZ_8K, SP_OPTIONS),
+ 	LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
+ 	LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE5, 4, SZ_8K, SP_OPTIONS),
+@@ -169,6 +229,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
+ 	{NAND_MFR_AMD, "AMD/Spansion"},
+ 	{NAND_MFR_MACRONIX, "Macronix"},
+ 	{NAND_MFR_EON, "Eon"},
++	{NAND_MFR_GD,"GigdDevice"},
+ 	{0x0, "Unknown"}
+ };
+ 
+diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
+index ed956e08..f03fcaa1 100644
+--- a/drivers/net/ethernet/Kconfig
++++ b/drivers/net/ethernet/Kconfig
+@@ -21,6 +21,7 @@ source "drivers/net/ethernet/3com/Kconfig"
+ source "drivers/net/ethernet/adaptec/Kconfig"
+ source "drivers/net/ethernet/aeroflex/Kconfig"
+ source "drivers/net/ethernet/alteon/Kconfig"
++source "drivers/net/ethernet/ambarella/Kconfig"
+ source "drivers/net/ethernet/amd/Kconfig"
+ source "drivers/net/ethernet/apple/Kconfig"
+ source "drivers/net/ethernet/atheros/Kconfig"
+diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
+index 8268d85f..834537fb 100644
+--- a/drivers/net/ethernet/Makefile
++++ b/drivers/net/ethernet/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_NET_VENDOR_8390) += 8390/
+ obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
+ obj-$(CONFIG_GRETH) += aeroflex/
+ obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
++obj-$(CONFIG_NET_VENDOR_AMBARELLA) += ambarella/
+ obj-$(CONFIG_NET_VENDOR_AMD) += amd/
+ obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
+ obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
+diff --git a/drivers/net/ethernet/ambarella/Kconfig b/drivers/net/ethernet/ambarella/Kconfig
+new file mode 100644
+index 00000000..2a0c0b72
+--- /dev/null
++++ b/drivers/net/ethernet/ambarella/Kconfig
+@@ -0,0 +1,23 @@
++#
++# AMBARELLA network device configuration
++#
++
++config NET_VENDOR_AMBARELLA
++	tristate "Ambarella 10/100/1000 GMAC Ethernet support"
++	depends on PLAT_AMBARELLA
++	select CRC32
++	select PHYLIB
++	select MII
++	help
++	  This driver supports Ambarella 10/100/1000 GMAC Ethernet.
++
++config NET_VENDOR_AMBARELLA_INTEN_TUE
++	bool "Enable Transmit Buffer Unavailable Interrupt"
++	default n
++	depends on NET_VENDOR_AMBARELLA
++	help
++	  Enable ETH_DMA_INTEN_TUE will downgrade the performance in most case,
++	  but you will get a quick response especially in GMII mode.
++
++	  If you are not sure, say N here.
++
+diff --git a/drivers/net/ethernet/ambarella/Makefile b/drivers/net/ethernet/ambarella/Makefile
+new file mode 100644
+index 00000000..e2e9c09e
+--- /dev/null
++++ b/drivers/net/ethernet/ambarella/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the Ambarella network device drivers
++#
++
++obj-$(CONFIG_NET_VENDOR_AMBARELLA)		+= ambarella_eth.o
+diff --git a/drivers/net/ethernet/ambarella/ambarella_eth.c b/drivers/net/ethernet/ambarella/ambarella_eth.c
+new file mode 100644
+index 00000000..a081bd33
+--- /dev/null
++++ b/drivers/net/ethernet/ambarella/ambarella_eth.c
+@@ -0,0 +1,2597 @@
++/*
++ * /drivers/net/ethernet/ambarella/ambarella_eth_normal.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ * Copyright (C) 2004-2011, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/of.h>
++#include <linux/of_net.h>
++#include <linux/of_mdio.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/spinlock.h>
++#include <linux/crc32.h>
++#include <linux/time.h>
++#include <linux/mii.h>
++#include <linux/phy.h>
++#include <linux/ethtool.h>
++
++#include <asm/dma.h>
++
++#include <mach/hardware.h>
++#include <plat/eth.h>
++#include <plat/rct.h>
++/* ==========================================================================*/
++#define AMBETH_NAPI_WEIGHT		32
++#define AMBETH_TX_WATCHDOG		(2 * HZ)
++#define AMBETH_MII_RETRY_CNT		200
++#define AMBETH_FC_PAUSE_TIME		1954
++
++#define AMBETH_PACKET_MAXFRAME		(1536)
++#define AMBETH_RX_COPYBREAK		(1518)
++#define AMBETH_RX_RNG_MIN		(8)
++#define AMBETH_TX_RNG_MIN		(4)
++#define AMBETH_PHY_REG_SIZE		(32)
++
++#define AMBETH_RXDMA_STATUS	(ETH_DMA_STATUS_OVF | ETH_DMA_STATUS_RI | \
++				ETH_DMA_STATUS_RU | ETH_DMA_STATUS_RPS | \
++				ETH_DMA_STATUS_RWT)
++#define AMBETH_RXDMA_INTEN	(ETH_DMA_INTEN_OVE | ETH_DMA_INTEN_RIE | \
++				ETH_DMA_INTEN_RUE | ETH_DMA_INTEN_RSE | \
++				ETH_DMA_INTEN_RWE)
++#define AMBETH_TXDMA_STATUS	(ETH_DMA_STATUS_TI | ETH_DMA_STATUS_TPS | \
++				ETH_DMA_STATUS_TU | ETH_DMA_STATUS_TJT | \
++				ETH_DMA_STATUS_UNF)
++#if defined(CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE)
++#define AMBETH_TXDMA_INTEN	(ETH_DMA_INTEN_TIE | ETH_DMA_INTEN_TSE | \
++				ETH_DMA_INTEN_TUE | ETH_DMA_INTEN_TJE | \
++				ETH_DMA_INTEN_UNE)
++#else
++#define AMBETH_TXDMA_INTEN	(ETH_DMA_INTEN_TIE | ETH_DMA_INTEN_TSE | \
++				ETH_DMA_INTEN_TJE | ETH_DMA_INTEN_UNE)
++#endif
++#define AMBETH_DMA_INTEN	(ETH_DMA_INTEN_NIE | ETH_DMA_INTEN_AIE | \
++				ETH_DMA_INTEN_FBE | AMBETH_RXDMA_INTEN | \
++				AMBETH_TXDMA_INTEN)
++
++/* ==========================================================================*/
++struct ambeth_rng_info {
++	struct sk_buff			*skb;
++	dma_addr_t			mapping;
++};
++
++struct ambeth_tx_rngmng {
++	unsigned int			cur_tx;
++	unsigned int			dirty_tx;
++	struct ambeth_rng_info		*rng_tx;
++	struct ambeth_desc		*desc_tx;
++};
++
++struct ambeth_rx_rngmng {
++	unsigned int			cur_rx;
++	unsigned int			dirty_rx;
++	struct ambeth_rng_info		*rng_rx;
++	struct ambeth_desc		*desc_rx;
++};
++
++struct ambeth_info {
++	unsigned int			rx_count;
++	struct ambeth_rx_rngmng		rx;
++	unsigned int			tx_count;
++	unsigned int			tx_irq_low;
++	unsigned int			tx_irq_high;
++	struct ambeth_tx_rngmng		tx;
++	dma_addr_t			rx_dma_desc;
++	dma_addr_t			tx_dma_desc;
++	spinlock_t			lock;
++	int				oldspeed;
++	int				oldduplex;
++	int				oldlink;
++	int				oldpause;
++	int				oldasym_pause;
++	u32				flow_ctr;
++
++	struct net_device_stats		stats;
++	struct napi_struct		napi;
++	struct net_device		*ndev;
++
++	struct mii_bus			new_bus;
++	struct phy_device		*phydev;
++	int				pwr_gpio;
++	u8				pwr_gpio_active;
++	int				rst_gpio;
++	u8				rst_gpio_active;
++	u32				phy_supported;
++	u32				fixed_speed; /* only for phy-less */
++
++	unsigned char __iomem		*regbase;
++	u32				msg_enable;
++
++	u32				mdio_gpio : 1,
++					phy_enabled : 1,
++					ipc_tx : 1,
++					ipc_rx : 1,
++					dump_tx : 1,
++					dump_rx : 1,
++					dump_rx_free : 1,
++					dump_rx_all : 1;
++	int				clk_direction;
++};
++
++/* ==========================================================================*/
++static int msg_level = -1;
++module_param (msg_level, int, 0);
++MODULE_PARM_DESC (msg_level, "Override default message level");
++
++/* ==========================================================================*/
++static void amba_set_eth_desc(struct ambeth_desc *desc, u32 val) {
++	u32 status = 0, length = 0;
++
++	if(ETH_ENHANCED) {
++		if(val & ETH_TDES_IC)
++			status |= ETH_ENHANCED_TDES0_IC;
++		if(val & ETH_TDES_LS)
++			status |= ETH_ENHANCED_TDES0_LS;
++		if(val & ETH_TDES_FS)
++			status |= ETH_ENHANCED_TDES0_FS;
++		if(val & ETH_TDES_TCH)
++			status |= ETH_ENHANCED_TDES0_TCH;
++		if(val & ETH_TDES_CIC)
++			status |= ETH_ENHANCED_TDES0_CIC_V2;
++
++		desc->status |= status;
++	} else {
++		if(val & ETH_TDES_IC)
++			length |= ETH_TDES1_IC;
++		if(val & ETH_TDES_LS)
++			length |= ETH_TDES1_LS;
++		if(val & ETH_TDES_FS)
++			length |= ETH_TDES1_FS;
++		if(val & ETH_TDES_TCH)
++			length |= ETH_TDES1_TCH;
++		if(val & ETH_TDES_CIC)
++			length |= ETH_TDES1_CIC_TUI | ETH_TDES1_CIC_HDR;
++
++		desc->length |= length;
++	}
++
++}
++
++static void ambhw_dump(struct ambeth_info *lp)
++{
++	u32 i;
++	unsigned int dirty_diff;
++	u32 entry;
++
++	dirty_diff = (lp->rx.cur_rx - lp->rx.dirty_rx);
++	entry = (lp->rx.cur_rx % lp->rx_count);
++	dev_info(&lp->ndev->dev, "RX Info: cur_rx[%u], dirty_rx[%u],"
++		" diff[%u], entry[%u].\n", lp->rx.cur_rx, lp->rx.dirty_rx,
++		dirty_diff, entry);
++	for (i = 0; i < lp->rx_count; i++) {
++		dev_info(&lp->ndev->dev, "RX Info: RX descriptor[%u] "
++			"0x%08x 0x%08x 0x%08x 0x%08x.\n", i,
++			lp->rx.desc_rx[i].status, lp->rx.desc_rx[i].length,
++			lp->rx.desc_rx[i].buffer1, lp->rx.desc_rx[i].buffer2);
++	}
++	dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
++	entry = (lp->tx.cur_tx % lp->tx_count);
++	dev_info(&lp->ndev->dev, "TX Info: cur_tx[%u], dirty_tx[%u],"
++		" diff[%u], entry[%u].\n", lp->tx.cur_tx, lp->tx.dirty_tx,
++		dirty_diff, entry);
++	for (i = 0; i < lp->tx_count; i++) {
++		dev_info(&lp->ndev->dev, "TX Info: TX descriptor[%u] "
++			"0x%08x 0x%08x 0x%08x 0x%08x.\n", i,
++			lp->tx.desc_tx[i].status, lp->tx.desc_tx[i].length,
++			lp->tx.desc_tx[i].buffer1, lp->tx.desc_tx[i].buffer2);
++	}
++	for (i = 0; i <= 21; i++) {
++		dev_dbg(&lp->ndev->dev, "GMAC[%d]: 0x%08x.\n", i,
++		amba_readl(lp->regbase + ETH_MAC_CFG_OFFSET + (i << 2)));
++	}
++	for (i = 0; i <= 54; i++) {
++		dev_dbg(&lp->ndev->dev, "GDMA[%d]: 0x%08x.\n", i,
++		amba_readl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET + (i << 2)));
++	}
++}
++
++static inline int ambhw_dma_reset(struct ambeth_info *lp)
++{
++	int ret_val = 0;
++	u32 counter = 0;
++
++	amba_setbitsl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
++		ETH_DMA_BUS_MODE_SWR);
++	do {
++		if (counter++ > 100) {
++			ret_val = -EIO;
++			break;
++		}
++		mdelay(1);
++	} while (amba_tstbitsl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
++		ETH_DMA_BUS_MODE_SWR));
++
++	if (ret_val && netif_msg_drv(lp))
++		dev_err(&lp->ndev->dev, "DMA Error: Check PHY.\n");
++
++	return ret_val;
++}
++
++static inline void ambhw_dma_int_enable(struct ambeth_info *lp)
++{
++	amba_writel(lp->regbase + ETH_DMA_INTEN_OFFSET, AMBETH_DMA_INTEN);
++}
++
++static inline void ambhw_dma_int_disable(struct ambeth_info *lp)
++{
++	amba_writel(lp->regbase + ETH_DMA_INTEN_OFFSET, 0);
++}
++
++static inline void ambhw_dma_rx_start(struct ambeth_info *lp)
++{
++	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_SR);
++}
++
++static inline void ambhw_dma_rx_stop(struct ambeth_info *lp)
++{
++	unsigned int irq_status;
++	int i = 1300;
++
++	amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_SR);
++	do {
++		udelay(1);
++		irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
++	} while ((irq_status & ETH_DMA_STATUS_RS_MASK) && --i);
++	if ((i <= 0) && netif_msg_drv(lp)) {
++		dev_err(&lp->ndev->dev,
++			"DMA Error: Stop RX status=0x%x, opmode=0x%x.\n",
++			amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
++			amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
++	}
++}
++
++static inline void ambhw_dma_tx_start(struct ambeth_info *lp)
++{
++	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_ST);
++}
++
++static inline void ambhw_dma_tx_stop(struct ambeth_info *lp)
++{
++	unsigned int irq_status;
++	int i = 1300;
++
++	amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_ST);
++	do {
++		udelay(1);
++		irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
++	} while ((irq_status & ETH_DMA_STATUS_TS_MASK) && --i);
++	if ((i <= 0) && netif_msg_drv(lp)) {
++		dev_err(&lp->ndev->dev,
++			"DMA Error: Stop TX status=0x%x, opmode=0x%x.\n",
++			amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
++			amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
++	}
++	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_FTF);
++}
++
++static inline void ambhw_dma_tx_restart(struct ambeth_info *lp, u32 entry)
++{
++	lp->tx.desc_tx[entry].status = 0;
++	amba_set_eth_desc(&lp->tx.desc_tx[entry], ETH_TDES_IC);
++	lp->tx.desc_tx[entry].status |= ETH_TDES0_OWN;
++	amba_writel(lp->regbase + ETH_DMA_TX_DESC_LIST_OFFSET,
++		(u32)lp->tx_dma_desc + (entry * sizeof(struct ambeth_desc)));
++	if (netif_msg_tx_err(lp)) {
++		dev_err(&lp->ndev->dev, "TX Error: restart %u.\n", entry);
++		ambhw_dump(lp);
++	}
++	ambhw_dma_tx_start(lp);
++}
++
++static inline void ambhw_dma_tx_poll(struct ambeth_info *lp)
++{
++	amba_writel(lp->regbase + ETH_DMA_TX_POLL_DMD_OFFSET, 0x01);
++}
++
++static inline void ambhw_stop_tx_rx(struct ambeth_info *lp)
++{
++	unsigned int irq_status;
++	int i = 1300;
++
++	amba_clrbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_RE);
++	amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET,
++		(ETH_DMA_OPMODE_SR | ETH_DMA_OPMODE_ST));
++	do {
++		udelay(1);
++		irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
++	} while ((irq_status & (ETH_DMA_STATUS_TS_MASK |
++		ETH_DMA_STATUS_RS_MASK)) && --i);
++	if ((i <= 0) && netif_msg_drv(lp)) {
++		dev_err(&lp->ndev->dev,
++			"DMA Error: Stop TX/RX status=0x%x, opmode=0x%x.\n",
++			amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
++			amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
++	}
++	amba_clrbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_TE);
++}
++
++static inline void ambhw_set_dma_desc(struct ambeth_info *lp)
++{
++	amba_writel(lp->regbase + ETH_DMA_RX_DESC_LIST_OFFSET,
++		lp->rx_dma_desc);
++	amba_writel(lp->regbase + ETH_DMA_TX_DESC_LIST_OFFSET,
++		lp->tx_dma_desc);
++}
++
++static inline phy_interface_t ambhw_get_interface(struct ambeth_info *lp)
++{
++	return amba_tstbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
++		ETH_MAC_CFG_PS) ? PHY_INTERFACE_MODE_MII :
++		PHY_INTERFACE_MODE_GMII;
++}
++
++static inline void ambhw_set_hwaddr(struct ambeth_info *lp, u8 *hwaddr)
++{
++	u32 val;
++
++	val = (hwaddr[5] << 8) | hwaddr[4];
++	amba_writel(lp->regbase + ETH_MAC_MAC0_HI_OFFSET, val);
++	udelay(4);
++	val = (hwaddr[3] << 24) | (hwaddr[2] << 16) |
++		(hwaddr[1] << 8) | hwaddr[0];
++	amba_writel(lp->regbase + ETH_MAC_MAC0_LO_OFFSET, val);
++}
++
++static inline void ambhw_get_hwaddr(struct ambeth_info *lp, u8 *hwaddr)
++{
++	u32 hval;
++	u32 lval;
++
++	hval = amba_readl(lp->regbase + ETH_MAC_MAC0_HI_OFFSET);
++	lval = amba_readl(lp->regbase + ETH_MAC_MAC0_LO_OFFSET);
++	hwaddr[5] = ((hval >> 8) & 0xff);
++	hwaddr[4] = ((hval >> 0) & 0xff);
++	hwaddr[3] = ((lval >> 24) & 0xff);
++	hwaddr[2] = ((lval >> 16) & 0xff);
++	hwaddr[1] = ((lval >> 8) & 0xff);
++	hwaddr[0] = ((lval >> 0) & 0xff);
++}
++
++static void ambeth_fc_resolve(struct ambeth_info *lp);
++
++static inline void ambhw_set_link_mode_speed(struct ambeth_info *lp)
++{
++	u32 val;
++
++	val = amba_readl(lp->regbase + ETH_MAC_CFG_OFFSET);
++	switch (lp->oldspeed) {
++	case SPEED_1000:
++		val &= ~(ETH_MAC_CFG_PS);
++		break;
++	case SPEED_100:
++		val |= ETH_MAC_CFG_PS;
++		val |= ETH_MAC_CFG_FES;
++		break;
++	case SPEED_10:
++		val |= ETH_MAC_CFG_PS;
++		val &= ~(ETH_MAC_CFG_FES);
++		break;
++	default:
++		break;
++	}
++	if (lp->oldduplex) {
++		val &= ~(ETH_MAC_CFG_DO);
++		val |= ETH_MAC_CFG_DM;
++	} else {
++		val &= ~(ETH_MAC_CFG_DM);
++		val |= ETH_MAC_CFG_DO;
++	}
++	amba_writel(lp->regbase + ETH_MAC_CFG_OFFSET, val);
++	ambeth_fc_resolve(lp);
++}
++
++static inline int ambhw_enable(struct ambeth_info *lp)
++{
++	int ret_val = 0;
++	u32 val;
++
++	ret_val = ambhw_dma_reset(lp);
++	if (ret_val)
++		goto ambhw_init_exit;
++
++	ambhw_set_hwaddr(lp, lp->ndev->dev_addr);
++
++	val = ETH_DMA_BUS_MODE_FB | ETH_DMA_BUS_MODE_PBL_32 |
++		ETH_DMA_BUS_MODE_DA_RX;
++
++	if(ETH_ENHANCED)
++		val |= ETH_DMA_BUS_MODE_ATDS;
++
++	amba_writel(lp->regbase + ETH_DMA_BUS_MODE_OFFSET, val);
++	amba_writel(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET, 0);
++
++	val = ETH_DMA_OPMODE_TTC_256 | ETH_DMA_OPMODE_RTC_64 |
++		ETH_DMA_OPMODE_FUF | ETH_DMA_OPMODE_TSF;
++	amba_writel(lp->regbase + ETH_DMA_OPMODE_OFFSET, val);
++	amba_writel(lp->regbase + ETH_MAC_CFG_OFFSET,
++		(ETH_MAC_CFG_TE | ETH_MAC_CFG_RE));
++
++	/*
++	 * (512 bits / N) * pause_time = actual pause time
++	 * ex:
++	 *     512 bits / 1 Gbps * 1954 = ~0.0010 sec = 1 ms
++	 *     512 bits / 100 Mbps * 1954 = ~0.010 sec = 10 ms
++	 */
++	amba_writel(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET,
++		ETH_MAC_FLOW_CTR_PLT_256 |
++		ETH_MAC_FLOW_CTR_PT(AMBETH_FC_PAUSE_TIME));
++
++	if (lp->ipc_rx) {
++		amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET,
++				ETH_DMA_OPMODE_RSF);
++		amba_setbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
++				ETH_MAC_CFG_IPC);
++	}
++
++	if (lp->dump_rx_all) {
++		amba_setbitsl(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET,
++				ETH_MAC_FRAME_FILTER_RA);
++	}
++
++	if(ETH_ENHANCED)
++		amba_writel(lp->regbase + ETH_MAC_INTERRUPT_MASK_OFFSET,0xFFFFFFFF);
++
++	amba_writel(lp->regbase + ETH_DMA_STATUS_OFFSET,
++		amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET));
++
++ambhw_init_exit:
++	return ret_val;
++}
++
++static inline void ambhw_disable(struct ambeth_info *lp)
++{
++	ambhw_stop_tx_rx(lp);
++	ambhw_dma_int_disable(lp);
++}
++
++static void ambhw_dump_buffer(const char *msg,
++	unsigned char *data, unsigned int length)
++{
++	unsigned int i;
++
++	if (msg)
++		printk("%s", msg);
++	for (i = 0; i < length; i++) {
++		if (i % 16 == 0) {
++			printk("\n%03X:", i);
++		}
++		printk(" %02x", data[i]);
++	}
++	printk("\n");
++}
++
++/* ==========================================================================*/
++static int ambhw_mdio_read(struct mii_bus *bus,
++	int mii_id, int regnum)
++{
++	struct ambeth_info *lp = bus->priv;
++	int val, cnt;
++
++	for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
++		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
++			ETH_MAC_GMII_ADDR_GB))
++			break;
++		udelay(10);
++	}
++	if ((cnt <= 0) && netif_msg_hw(lp)) {
++		dev_err(&lp->ndev->dev, "MII Error: Preread tmo!\n");
++		val = 0xFFFFFFFF;
++		goto ambhw_mdio_read_exit;
++	}
++
++	val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
++	val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GB;
++	amba_writel(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET, val);
++
++	for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
++		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
++			ETH_MAC_GMII_ADDR_GB))
++			break;
++		udelay(10);
++	}
++	if ((cnt <= 0) && netif_msg_hw(lp)) {
++		dev_err(&lp->ndev->dev, "MII Error: Postread tmo!\n");
++		val = 0xFFFFFFFF;
++		goto ambhw_mdio_read_exit;
++	}
++
++	val = amba_readl(lp->regbase + ETH_MAC_GMII_DATA_OFFSET);
++
++ambhw_mdio_read_exit:
++	if (netif_msg_hw(lp))
++		dev_info(&lp->ndev->dev,
++			"MII Read: addr[0x%02x], reg[0x%02x], val[0x%04x].\n",
++			mii_id, regnum, val);
++
++	return val;
++}
++
++static int ambhw_mdio_write(struct mii_bus *bus,
++	int mii_id, int regnum, u16 value)
++{
++	int ret_val = 0;
++	struct ambeth_info *lp;
++	int val;
++	int cnt = 0;
++
++	lp = (struct ambeth_info *)bus->priv;
++
++	if (netif_msg_hw(lp))
++		dev_info(&lp->ndev->dev,
++			"MII Write: id[0x%02x], add[0x%02x], val[0x%04x].\n",
++			mii_id, regnum, value);
++
++	for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
++		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
++			ETH_MAC_GMII_ADDR_GB))
++			break;
++		udelay(10);
++	}
++	if ((cnt <= 0) && netif_msg_hw(lp)) {
++		dev_err(&lp->ndev->dev, "MII Error: Prewrite tmo!\n");
++		ret_val = -EIO;
++		goto ambhw_mdio_write_exit;
++	}
++
++	val = value;
++	amba_writel(lp->regbase + ETH_MAC_GMII_DATA_OFFSET, val);
++	val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
++	val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GW |
++		ETH_MAC_GMII_ADDR_GB;
++	amba_writel(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET, val);
++
++	for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
++		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
++			ETH_MAC_GMII_ADDR_GB))
++			break;
++		udelay(10);
++	}
++	if ((cnt <= 0) && netif_msg_hw(lp)) {
++		dev_err(&lp->ndev->dev, "MII Error: Postwrite tmo!\n");
++		ret_val = -EIO;
++		goto ambhw_mdio_write_exit;
++	}
++
++ambhw_mdio_write_exit:
++	return ret_val;
++}
++
++static int ambhw_mdio_reset(struct mii_bus *bus)
++{
++	struct ambeth_info *lp = bus->priv;
++	int ret_val = 0;
++
++	if (netif_msg_hw(lp)) {
++		dev_info(&lp->ndev->dev, "MII Info: Power gpio = %d, "
++			"Reset gpio = %d.\n", lp->pwr_gpio, lp->rst_gpio);
++	}
++
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio))
++		gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio))
++		gpio_set_value_cansleep(lp->rst_gpio, !lp->rst_gpio_active);
++
++	/* waiting for PHY working stable, this delay is a must */
++	msleep(50);
++
++	return ret_val;
++}
++
++/* ==========================================================================*/
++static void ambeth_adjust_link(struct net_device *ndev)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	struct phy_device *phydev = lp->phydev;
++	int need_update = 0;
++	unsigned long flags;
++
++	spin_lock_irqsave(&lp->lock, flags);
++
++	if (phydev->link) {
++		if (phydev->duplex != lp->oldduplex) {
++			need_update = 1;
++			lp->oldduplex = phydev->duplex;
++		}
++		if (phydev->speed != lp->oldspeed) {
++			switch (phydev->speed) {
++			case SPEED_1000:
++			case SPEED_100:
++			case SPEED_10:
++				need_update = 1;
++				lp->oldspeed = phydev->speed;
++				break;
++			default:
++				if (netif_msg_link(lp))
++					dev_warn(&lp->ndev->dev,
++						"Unknown Speed(%d).\n",
++						phydev->speed);
++				break;
++			}
++		}
++		if (phydev->pause != lp->oldpause ||
++		    phydev->asym_pause != lp->oldasym_pause) {
++			lp->oldpause = phydev->pause;
++			lp->oldasym_pause = phydev->asym_pause;
++			need_update = 1;
++		}
++		if (lp->oldlink != phydev->link) {
++			need_update = 1;
++			lp->oldlink = phydev->link;
++		}
++	} else if (lp->oldlink) {
++		need_update = 1;
++		lp->oldlink = PHY_DOWN;
++		lp->oldspeed = 0;
++		lp->oldduplex = -1;
++	}
++
++	if (need_update) {
++		ambhw_set_link_mode_speed(lp);
++		if (netif_msg_link(lp))
++			phy_print_status(phydev);
++	}
++	spin_unlock_irqrestore(&lp->lock, flags);
++}
++
++static void ambeth_fc_config(struct ambeth_info *lp)
++{
++	u32 sup, adv, flow_ctr;
++
++	sup = lp->phydev->supported;
++	adv = lp->phydev->advertising;
++	flow_ctr = lp->flow_ctr;
++
++	sup |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
++	adv &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
++
++	sup &= lp->phy_supported;
++
++	if (!(sup & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)))
++		goto unsupported;
++
++        if (lp->fixed_speed != SPEED_UNKNOWN)
++		goto autoneg_unsupported;
++
++	if (!(sup & SUPPORTED_Autoneg) ||
++	    !(flow_ctr & AMBARELLA_ETH_FC_AUTONEG))
++		goto autoneg_unsupported;
++
++	if (flow_ctr & AMBARELLA_ETH_FC_RX) {
++		/*
++		 * Being able to decode pause frames is sufficently to
++		 * advertise that we support both sym. and asym. pause.
++		 * It doesn't matter if send pause frame or not.
++                 */
++		adv |= (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
++		goto done;
++	}
++
++	if (flow_ctr & AMBARELLA_ETH_FC_TX) {
++		/* Tell the link parter that we do send the pause frame. */
++		adv |= ADVERTISED_Asym_Pause;
++		goto done;
++	}
++	goto done;
++
++autoneg_unsupported:
++	/* Sanitize the config value */
++	lp->flow_ctr &= ~AMBARELLA_ETH_FC_AUTONEG;
++
++	/* Advertise nothing about pause frame */
++	adv &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
++	goto done;
++
++unsupported:
++	/* Sanitize the config value */
++	lp->flow_ctr &= ~(AMBARELLA_ETH_FC_AUTONEG |
++					 AMBARELLA_ETH_FC_RX |
++					 AMBARELLA_ETH_FC_TX);
++done:
++	lp->phydev->advertising = adv;
++	lp->phydev->supported = sup;
++	dev_info(&lp->ndev->dev, "adv: sym %d, asym: %d\n",
++		 !!(adv & ADVERTISED_Pause),
++		 !!(adv & ADVERTISED_Asym_Pause));
++}
++
++static void ambeth_fc_resolve(struct ambeth_info *lp)
++{
++	u32 flow_ctr, fc, old_fc;
++
++	flow_ctr = lp->flow_ctr;
++
++	if (!(flow_ctr & AMBARELLA_ETH_FC_AUTONEG))
++		goto force_setting;
++
++	fc = old_fc = amba_readl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET);
++
++	dev_info(&lp->ndev->dev, "lp: sym: %d, asym: %d\n",
++		 lp->phydev->pause, lp->phydev->asym_pause);
++	/*
++	 * Decode pause frames only if user specified, and the link
++	 * partner could send them on the same time.
++	 */
++	if ((flow_ctr & AMBARELLA_ETH_FC_RX) &&
++	    (lp->phydev->pause || lp->phydev->asym_pause))
++		fc |= ETH_MAC_FLOW_CTR_RFE;
++	else
++		fc &= ~ETH_MAC_FLOW_CTR_RFE;
++
++	/*
++	 * Send pause frames only if user specified, and the link
++	 * partner can resopnds to them on the same time.
++	 */
++	if ((flow_ctr & AMBARELLA_ETH_FC_TX) && lp->phydev->pause)
++		fc |= ETH_MAC_FLOW_CTR_TFE;
++	else
++		fc &= ~ETH_MAC_FLOW_CTR_TFE;
++
++	if (fc != old_fc)
++		amba_writel(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET, fc);
++
++	return;
++
++force_setting:
++
++	if (flow_ctr & AMBARELLA_ETH_FC_TX)
++		amba_setbitsl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET,
++			ETH_MAC_FLOW_CTR_TFE);
++
++	if (flow_ctr & AMBARELLA_ETH_FC_RX)
++		amba_setbitsl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET,
++			ETH_MAC_FLOW_CTR_RFE);
++}
++
++static int ambeth_phy_start(struct ambeth_info *lp)
++{
++	struct net_device *ndev = lp->ndev;
++	struct phy_device *phydev = lp->phydev;
++	phy_interface_t intf;
++	int ret_val = 0;
++	unsigned long flags;
++
++	if (lp->phy_enabled)
++		return 0;
++
++	lp->oldlink = PHY_DOWN;
++	lp->oldspeed = 0;
++	lp->oldduplex = -1;
++
++	/* Fixed Link mode: we allow all valid fixed_speed,
++	   even HW can not support the speed. */
++	switch (lp->fixed_speed) {
++	case SPEED_1000:
++	case SPEED_100:
++	case SPEED_10:
++		lp->oldlink = PHY_RUNNING;
++		lp->oldspeed = lp->fixed_speed;
++		lp->oldduplex = DUPLEX_FULL;
++		ambhw_set_link_mode_speed(lp);
++		dev_notice(&lp->ndev->dev, "Fixed Link - %d/%s\n", lp->oldspeed,
++			((lp->oldduplex == DUPLEX_FULL) ? "Full" : "Half"));
++		netif_carrier_on(ndev);
++		goto ambeth_init_phy_exit;
++		break;
++	default:
++		break;
++	}
++
++	intf = ambhw_get_interface(lp);
++	ret_val = phy_connect_direct(ndev, phydev, &ambeth_adjust_link, intf);
++	if (ret_val) {
++		dev_err(&lp->ndev->dev, "Could not attach to PHY!\n");
++		goto ambeth_init_phy_exit;
++	}
++
++	phydev->supported &= lp->phy_supported;
++	phydev->advertising = phydev->supported;
++
++	spin_lock_irqsave(&lp->lock, flags);
++	lp->phy_enabled = 1;
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	ambeth_fc_config(lp);
++	ret_val = phy_start_aneg(phydev);
++
++	ambeth_fc_resolve(lp);
++
++ambeth_init_phy_exit:
++	return ret_val;
++}
++
++static void ambeth_phy_stop(struct ambeth_info *lp)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&lp->lock, flags);
++	lp->phy_enabled = 0;
++	lp->oldlink = PHY_DOWN;
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	phy_disconnect(lp->phydev);
++}
++
++static inline int ambeth_rx_rngmng_check_skb(struct ambeth_info *lp, u32 entry)
++{
++	int ret_val = 0;
++	dma_addr_t mapping;
++	struct sk_buff *skb;
++
++	if (lp->rx.rng_rx[entry].skb == NULL) {
++		skb = netdev_alloc_skb(lp->ndev, AMBETH_PACKET_MAXFRAME);
++		if (skb == NULL) {
++			if (netif_msg_drv(lp))
++				dev_err(&lp->ndev->dev,
++				"RX Error: netdev_alloc_skb.\n");
++			ret_val = -ENOMEM;
++			goto ambeth_rx_rngmng_skb_exit;
++		}
++		mapping = dma_map_single(&lp->ndev->dev, skb->data,
++			AMBETH_PACKET_MAXFRAME, DMA_FROM_DEVICE);
++		lp->rx.rng_rx[entry].skb = skb;
++		lp->rx.rng_rx[entry].mapping = mapping;
++		lp->rx.desc_rx[entry].buffer1 = mapping;
++	}
++
++ambeth_rx_rngmng_skb_exit:
++	return ret_val;
++}
++
++static inline void ambeth_rx_rngmng_init(struct ambeth_info *lp)
++{
++	int i;
++
++	lp->rx.cur_rx = 0;
++	lp->rx.dirty_rx = 0;
++	for (i = 0; i < lp->rx_count; i++) {
++		if (ambeth_rx_rngmng_check_skb(lp, i))
++			break;
++		lp->rx.desc_rx[i].status = ETH_RDES0_OWN;
++		lp->rx.desc_rx[i].length = (ETH_RDES1_RCH |
++			ETH_RDES1_RBS1x(AMBETH_PACKET_MAXFRAME));
++		lp->rx.desc_rx[i].buffer2 = (u32)lp->rx_dma_desc +
++			((i + 1) * sizeof(struct ambeth_desc));
++	}
++	lp->rx.desc_rx[lp->rx_count - 1].buffer2 = (u32)lp->rx_dma_desc;
++}
++
++static inline void ambeth_rx_rngmng_refill(struct ambeth_info *lp)
++{
++	u32 i;
++	unsigned int dirty_diff;
++	u32 entry;
++
++	dirty_diff = (lp->rx.cur_rx - lp->rx.dirty_rx);
++	for (i = 0; i < dirty_diff; i++) {
++		entry = lp->rx.dirty_rx % lp->rx_count;
++		if (ambeth_rx_rngmng_check_skb(lp, entry))
++			break;
++		lp->rx.desc_rx[entry].status = ETH_RDES0_OWN;
++		lp->rx.dirty_rx++;
++	}
++}
++
++static inline void ambeth_rx_rngmng_del(struct ambeth_info *lp)
++{
++	int i;
++	dma_addr_t mapping;
++	struct sk_buff *skb;
++
++	for (i = 0; i < lp->rx_count; i++) {
++		if (lp->rx.rng_rx) {
++			skb = lp->rx.rng_rx[i].skb;
++			mapping = lp->rx.rng_rx[i].mapping;
++			lp->rx.rng_rx[i].skb = NULL;
++			lp->rx.rng_rx[i].mapping = 0;
++			if (mapping) {
++				dma_unmap_single(&lp->ndev->dev, mapping,
++					AMBETH_PACKET_MAXFRAME,
++					DMA_FROM_DEVICE);
++			}
++			if (skb) {
++				dev_kfree_skb(skb);
++			}
++		}
++		if (lp->rx.desc_rx) {
++			lp->rx.desc_rx[i].status = 0;
++			lp->rx.desc_rx[i].length = 0;
++			lp->rx.desc_rx[i].buffer1 = 0xBADF00D0;
++			lp->rx.desc_rx[i].buffer2 = 0xBADF00D0;
++		}
++	}
++}
++
++static inline void ambeth_tx_rngmng_init(struct ambeth_info *lp)
++{
++	u32 i;
++
++	lp->tx.cur_tx = 0;
++	lp->tx.dirty_tx = 0;
++	for (i = 0; i < lp->tx_count; i++) {
++		lp->tx.rng_tx[i].mapping = 0;
++		lp->tx.desc_tx[i].length = 0;
++		amba_set_eth_desc(&lp->tx.desc_tx[i], ETH_TDES_LS | ETH_TDES_FS
++			| ETH_TDES_TCH);
++		lp->tx.desc_tx[i].buffer1 = 0;
++		lp->tx.desc_tx[i].buffer2 = (u32)lp->tx_dma_desc +
++			((i + 1) * sizeof(struct ambeth_desc));
++	}
++	lp->tx.desc_tx[lp->tx_count - 1].buffer2 = (u32)lp->tx_dma_desc;
++}
++
++static inline void ambeth_tx_rngmng_del(struct ambeth_info *lp)
++{
++	u32 i;
++	dma_addr_t mapping;
++	struct sk_buff *skb;
++
++	for (i = 0; i < lp->tx_count; i++) {
++		if (lp->tx.rng_tx) {
++			skb = lp->tx.rng_tx[i].skb;
++			mapping = lp->tx.rng_tx[i].mapping;
++			lp->tx.rng_tx[i].skb = NULL;
++			lp->tx.rng_tx[i].mapping = 0;
++			if (skb) {
++				dma_unmap_single(&lp->ndev->dev, mapping,
++					skb->len, DMA_TO_DEVICE);
++				dev_kfree_skb(skb);
++			}
++		}
++		if (lp->tx.desc_tx) {
++			lp->tx.desc_tx[i].status = 0;
++			lp->tx.desc_tx[i].length = 0;
++			lp->tx.desc_tx[i].buffer1 = 0xBADF00D0;
++			lp->tx.desc_tx[i].buffer2 = 0xBADF00D0;
++		}
++	}
++}
++
++static inline void ambeth_check_dma_error(struct ambeth_info *lp,
++	u32 irq_status)
++{
++	u32 miss_ov = 0;
++
++	if (unlikely(irq_status & ETH_DMA_STATUS_AIS)) {
++		if (irq_status & (ETH_DMA_STATUS_RU | ETH_DMA_STATUS_OVF))
++			miss_ov = amba_readl(lp->regbase +
++				ETH_DMA_MISS_FRAME_BOCNT_OFFSET);
++
++		if (irq_status & ETH_DMA_STATUS_FBI) {
++			if (netif_msg_drv(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Fatal Bus Error 0x%x.\n",
++				(irq_status & ETH_DMA_STATUS_EB_MASK));
++		}
++		if (irq_status & ETH_DMA_STATUS_ETI) {
++			if (netif_msg_tx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Early Transmit.\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_RWT) {
++			if (netif_msg_rx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Receive Watchdog Timeout.\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_RPS) {
++			if (netif_msg_rx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Receive Process Stopped.\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_RU) {
++			if (miss_ov & ETH_DMA_MISS_FRAME_BOCNT_FRAME) {
++				lp->stats.rx_dropped +=
++					ETH_DMA_MISS_FRAME_BOCNT_HOST(miss_ov);
++			}
++			if (netif_msg_rx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Receive Buffer Unavailable, %u.\n",
++				ETH_DMA_MISS_FRAME_BOCNT_HOST(miss_ov));
++		}
++		if (irq_status & ETH_DMA_STATUS_UNF) {
++			if (netif_msg_tx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Transmit Underflow.\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_OVF) {
++			if (miss_ov & ETH_DMA_MISS_FRAME_BOCNT_FIFO) {
++				lp->stats.rx_fifo_errors +=
++					ETH_DMA_MISS_FRAME_BOCNT_APP(miss_ov);
++			}
++			if (netif_msg_rx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Receive FIFO Overflow, %u.\n",
++				ETH_DMA_MISS_FRAME_BOCNT_APP(miss_ov));
++		}
++		if (irq_status & ETH_DMA_STATUS_TJT) {
++			lp->stats.tx_errors++;
++			if (netif_msg_drv(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Transmit Jabber Timeout.\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_TPS) {
++			if (netif_msg_tx_err(lp))
++				dev_err(&lp->ndev->dev,
++				"DMA Error: Transmit Process Stopped.\n");
++		}
++		if (netif_msg_tx_err(lp) || netif_msg_rx_err(lp)) {
++			dev_err(&lp->ndev->dev, "DMA Error: Abnormal: 0x%x.\n",
++				irq_status);
++			ambhw_dump(lp);
++		}
++	}
++}
++
++static inline void ambeth_pause_frame(struct ambeth_info *lp)
++{
++	u32					fc;
++
++	fc = amba_readl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET);
++	if (!(fc & ETH_MAC_FLOW_CTR_TFE))
++		return;
++
++	fc |= ETH_MAC_FLOW_CTR_FCBBPA;
++
++	amba_writel(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET, fc);
++}
++
++static inline void ambeth_interrupt_rx(struct ambeth_info *lp, u32 irq_status)
++{
++	if (irq_status & AMBETH_RXDMA_STATUS) {
++		amba_clrbitsl(lp->regbase + ETH_DMA_INTEN_OFFSET,
++			AMBETH_RXDMA_INTEN);
++		napi_schedule(&lp->napi);
++	}
++}
++
++static inline void ambeth_interrupt_gmac(struct ambeth_info *lp, u32 irq_status)
++{
++	if(ETH_ENHANCED) {
++		u32 tmp_reg;
++
++		if (irq_status & ETH_DMA_STATUS_GPI) {
++			dev_vdbg(&lp->ndev->dev, "ETH_DMA_STATUS_GPI\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_GMI) {
++			dev_vdbg(&lp->ndev->dev, "ETH_DMA_STATUS_GMI\n");
++		}
++		if (irq_status & ETH_DMA_STATUS_GLI) {
++			dev_vdbg(&lp->ndev->dev, "ETH_DMA_STATUS_GLI\n");
++			tmp_reg = amba_readl(lp->regbase +
++				ETH_MAC_INTERRUPT_STATUS_OFFSET);
++			dev_vdbg(&lp->ndev->dev,
++				"ETH_MAC_INTERRUPT_STATUS_OFFSET = 0x%08X\n",tmp_reg);
++			tmp_reg = amba_readl(lp->regbase +
++				ETH_MAC_INTERRUPT_MASK_OFFSET);
++			dev_vdbg(&lp->ndev->dev,
++				"ETH_MAC_INTERRUPT_MASK_OFFSET = 0x%08X\n",tmp_reg);
++			tmp_reg = amba_readl(lp->regbase +
++				ETH_MAC_AN_STATUS_OFFSET);
++			dev_vdbg(&lp->ndev->dev,
++				"ETH_MAC_AN_STATUS_OFFSET = 0x%08X\n",tmp_reg);
++			tmp_reg = amba_readl(lp->regbase +
++				ETH_MAC_RGMII_CS_OFFSET);
++			dev_vdbg(&lp->ndev->dev,
++				"ETH_MAC_RGMII_CS_OFFSET = 0x%08X\n",tmp_reg);
++			tmp_reg = amba_readl(lp->regbase +
++				ETH_MAC_GPIO_OFFSET);
++			dev_vdbg(&lp->ndev->dev,
++				"ETH_MAC_GPIO_OFFSET = 0x%08X\n",tmp_reg);
++		}
++
++	}
++}
++
++static inline u32 ambeth_check_tdes0_status(struct ambeth_info *lp,
++	unsigned int status)
++{
++	u32 tx_retry = 0;
++
++	if (status & ETH_TDES0_JT) {
++		lp->stats.tx_heartbeat_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "TX Error: Jabber Timeout.\n");
++	}
++	if (status & ETH_TDES0_FF) {
++		lp->stats.tx_dropped++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "TX Error: Frame Flushed.\n");
++	}
++	if (status & ETH_TDES0_PCE) {
++		lp->stats.tx_fifo_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"TX Error: Payload Checksum Error.\n");
++	}
++	if (status & ETH_TDES0_LCA) {
++		lp->stats.tx_carrier_errors++;
++		dev_err(&lp->ndev->dev, "TX Error: Loss of Carrier.\n");
++	}
++	if (status & ETH_TDES0_NC) {
++		lp->stats.tx_carrier_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "TX Error: No Carrier.\n");
++	}
++	if (status & ETH_TDES0_LCO) {
++		lp->stats.tx_aborted_errors++;
++		lp->stats.collisions++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "TX Error: Late Collision.\n");
++	}
++	if (status & ETH_TDES0_EC) {
++		lp->stats.tx_aborted_errors++;
++		lp->stats.collisions += ETH_TDES0_CC(status);
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"TX Error: Excessive Collision %u.\n",
++			ETH_TDES0_CC(status));
++	}
++	if (status & ETH_TDES0_VF) {
++		if (netif_msg_drv(lp))
++			dev_info(&lp->ndev->dev, "TX Info: VLAN Frame.\n");
++	}
++	if (status & ETH_TDES0_ED) {
++		lp->stats.tx_fifo_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"TX Error: Excessive Deferral.\n");
++	}
++	if (status & ETH_TDES0_UF) {
++		tx_retry = 1;
++		if (netif_msg_tx_err(lp)) {
++			dev_err(&lp->ndev->dev, "TX Error: Underflow Error.\n");
++			ambhw_dump(lp);
++		}
++	}
++	if (status & ETH_TDES0_DB) {
++		lp->stats.tx_fifo_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "TX Error: Deferred Bit.\n");
++	}
++
++	return tx_retry;
++}
++
++static inline void ambeth_interrupt_tx(struct ambeth_info *lp, u32 irq_status)
++{
++	u32 i;
++	unsigned int dirty_diff;
++	u32 entry;
++	u32 status;
++
++	if (irq_status & AMBETH_TXDMA_STATUS) {
++		dev_vdbg(&lp->ndev->dev, "cur_tx[%u], dirty_tx[%u], 0x%x.\n",
++			lp->tx.cur_tx, lp->tx.dirty_tx, irq_status);
++		dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
++		for (i = 0; i < dirty_diff; i++) {
++			entry = (lp->tx.dirty_tx % lp->tx_count);
++			status = lp->tx.desc_tx[entry].status;
++
++			if (status & ETH_TDES0_OWN)
++				break;
++
++			if (unlikely(status & ETH_TDES0_ES)) {
++				if ((status & ETH_TDES0_ES_MASK) ==
++					ETH_TDES0_ES) {
++					break;
++				}
++				if (ambeth_check_tdes0_status(lp, status)) {
++					ambhw_dma_tx_stop(lp);
++					ambhw_dma_tx_restart(lp, entry);
++					ambhw_dma_tx_poll(lp);
++					break;
++				} else {
++					lp->stats.tx_errors++;
++				}
++			} else {
++				if (unlikely(status & ETH_TDES0_IHE)) {
++					if (netif_msg_drv(lp))
++						dev_err(&lp->ndev->dev,
++						"TX Error: IP Header Error.\n");
++				}
++				lp->stats.tx_bytes +=
++					lp->tx.rng_tx[entry].skb->len;
++				lp->stats.tx_packets++;
++			}
++
++			dma_unmap_single(&lp->ndev->dev,
++				lp->tx.rng_tx[entry].mapping,
++				lp->tx.rng_tx[entry].skb->len,
++				DMA_TO_DEVICE);
++			dev_kfree_skb_irq(lp->tx.rng_tx[entry].skb);
++			lp->tx.rng_tx[entry].skb = NULL;
++			lp->tx.rng_tx[entry].mapping = 0;
++			lp->tx.dirty_tx++;
++		}
++		dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
++		if (dirty_diff && (irq_status & ETH_DMA_STATUS_TU)) {
++			ambhw_dma_tx_poll(lp);
++		}
++		if (likely(dirty_diff < lp->tx_irq_low)) {
++			netif_wake_queue(lp->ndev);
++		}
++		dev_vdbg(&lp->ndev->dev, "cur_tx[%u], dirty_tx[%u], 0x%x.\n",
++			lp->tx.cur_tx, lp->tx.dirty_tx, irq_status);
++	}
++}
++
++static irqreturn_t ambeth_interrupt(int irq, void *dev_id)
++{
++	struct net_device *ndev;
++	struct ambeth_info *lp;
++	u32 irq_status;
++	unsigned long flags;
++
++	ndev = (struct net_device *)dev_id;
++	lp = netdev_priv(ndev);
++
++	spin_lock_irqsave(&lp->lock, flags);
++	irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
++	ambeth_check_dma_error(lp, irq_status);
++	ambeth_interrupt_gmac(lp, irq_status);
++	ambeth_interrupt_rx(lp, irq_status);
++	ambeth_interrupt_tx(lp, irq_status);
++	amba_writel(lp->regbase + ETH_DMA_STATUS_OFFSET, irq_status);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	return IRQ_HANDLED;
++}
++
++static int ambeth_start_hw(struct net_device *ndev)
++{
++	int ret_val = 0;
++	struct ambeth_info *lp;
++	unsigned long flags;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio)) {
++		gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
++		msleep(200);
++		gpio_set_value_cansleep(lp->rst_gpio, !lp->rst_gpio_active);
++	}
++
++	spin_lock_irqsave(&lp->lock, flags);
++	ret_val = ambhw_enable(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++	if (ret_val)
++		goto ambeth_start_hw_exit;
++
++	lp->rx.rng_rx = kmalloc((sizeof(struct ambeth_rng_info) *
++		lp->rx_count), GFP_KERNEL);
++	if (lp->rx.rng_rx == NULL) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "alloc rng_rx fail.\n");
++		ret_val = -ENOMEM;
++		goto ambeth_start_hw_exit;
++	}
++	lp->rx.desc_rx = dma_alloc_coherent(&lp->ndev->dev,
++		(sizeof(struct ambeth_desc) * lp->rx_count),
++		&lp->rx_dma_desc, GFP_KERNEL);
++	if (lp->rx.desc_rx == NULL) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"dma_alloc_coherent desc_rx fail.\n");
++		ret_val = -ENOMEM;
++		goto ambeth_start_hw_exit;
++	}
++	memset(lp->rx.rng_rx, 0,
++		(sizeof(struct ambeth_rng_info) * lp->rx_count));
++	memset(lp->rx.desc_rx, 0,
++		(sizeof(struct ambeth_desc) * lp->rx_count));
++	ambeth_rx_rngmng_init(lp);
++
++	lp->tx.rng_tx = kmalloc((sizeof(struct ambeth_rng_info) *
++		lp->tx_count), GFP_KERNEL);
++	if (lp->tx.rng_tx == NULL) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "alloc rng_tx fail.\n");
++		ret_val = -ENOMEM;
++		goto ambeth_start_hw_exit;
++	}
++	lp->tx.desc_tx = dma_alloc_coherent(&lp->ndev->dev,
++		(sizeof(struct ambeth_desc) * lp->tx_count),
++		&lp->tx_dma_desc, GFP_KERNEL);
++	if (lp->tx.desc_tx == NULL) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"dma_alloc_coherent desc_tx fail.\n");
++		ret_val = -ENOMEM;
++		goto ambeth_start_hw_exit;
++	}
++	memset(lp->tx.rng_tx, 0,
++		(sizeof(struct ambeth_rng_info) * lp->tx_count));
++	memset(lp->tx.desc_tx, 0,
++		(sizeof(struct ambeth_desc) * lp->tx_count));
++	ambeth_tx_rngmng_init(lp);
++
++	spin_lock_irqsave(&lp->lock, flags);
++	ambhw_set_dma_desc(lp);
++	ambhw_dma_rx_start(lp);
++	ambhw_dma_tx_start(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++ambeth_start_hw_exit:
++	return ret_val;
++}
++
++static void ambeth_stop_hw(struct net_device *ndev)
++{
++	struct ambeth_info *lp;
++	unsigned long flags;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++
++	spin_lock_irqsave(&lp->lock, flags);
++	ambhw_disable(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	ambeth_tx_rngmng_del(lp);
++	if (lp->tx.desc_tx) {
++		dma_free_coherent(&lp->ndev->dev,
++			(sizeof(struct ambeth_desc) * lp->tx_count),
++			lp->tx.desc_tx, lp->tx_dma_desc);
++		lp->tx.desc_tx = NULL;
++	}
++	if (lp->tx.rng_tx) {
++		kfree(lp->tx.rng_tx);
++		lp->tx.rng_tx = NULL;
++	}
++
++	ambeth_rx_rngmng_del(lp);
++	if (lp->rx.desc_rx) {
++		dma_free_coherent(&lp->ndev->dev,
++			(sizeof(struct ambeth_desc) * lp->rx_count),
++			lp->rx.desc_rx, lp->rx_dma_desc);
++		lp->rx.desc_rx = NULL;
++	}
++	if (lp->rx.rng_rx) {
++		kfree(lp->rx.rng_rx);
++		lp->rx.rng_rx = NULL;
++	}
++
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio))
++		gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
++}
++
++static int ambeth_open(struct net_device *ndev)
++{
++	int ret_val = 0;
++	struct ambeth_info *lp;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++
++	ret_val = ambeth_start_hw(ndev);
++	if (ret_val)
++		goto ambeth_open_exit;
++
++	ret_val = request_irq(ndev->irq, ambeth_interrupt,
++		IRQF_SHARED | IRQF_TRIGGER_HIGH, ndev->name, ndev);
++	if (ret_val) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"Request_irq[%d] fail.\n", ndev->irq);
++		goto ambeth_open_exit;
++	}
++
++	napi_enable(&lp->napi);
++	netif_start_queue(ndev);
++	ambhw_dma_int_enable(lp);
++
++	netif_carrier_off(ndev);
++	ret_val = ambeth_phy_start(lp);
++	if (ret_val) {
++		netif_stop_queue(ndev);
++		napi_disable(&lp->napi);
++		free_irq(ndev->irq, ndev);
++	}
++
++ambeth_open_exit:
++	if (ret_val) {
++		ambeth_stop_hw(ndev);
++	}
++
++	return ret_val;
++}
++
++static int ambeth_stop(struct net_device *ndev)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	int ret_val = 0;
++
++	netif_stop_queue(ndev);
++	napi_disable(&lp->napi);
++	free_irq(ndev->irq, ndev);
++	ambeth_phy_stop(lp);
++	netif_carrier_off(ndev);
++	ambeth_stop_hw(ndev);
++
++	return ret_val;
++}
++
++static int ambeth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++	int ret_val = 0;
++	struct ambeth_info *lp;
++	dma_addr_t mapping;
++	u32 entry;
++	unsigned int dirty_diff;
++	u32 tx_flag;
++	unsigned long flags;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++	tx_flag = ETH_TDES_LS | ETH_TDES_FS | ETH_TDES_TCH;
++
++	spin_lock_irqsave(&lp->lock, flags);
++	dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
++	entry = (lp->tx.cur_tx % lp->tx_count);
++	if (dirty_diff == lp->tx_irq_high) {
++		tx_flag |= ETH_TDES_IC;
++	} else if (dirty_diff == (lp->tx_count - 1)) {
++		netif_stop_queue(ndev);
++		tx_flag |= ETH_TDES_IC;
++	} else if (dirty_diff >= lp->tx_count) {
++		netif_stop_queue(ndev);
++		ret_val = -ENOMEM;
++		ambhw_dma_tx_poll(lp);
++		spin_unlock_irqrestore(&lp->lock, flags);
++		dev_err(&lp->ndev->dev, "TX Error: TX OV.\n");
++		goto ambeth_hard_start_xmit_exit;
++	}
++	if (unlikely(lp->dump_tx))
++		ambhw_dump_buffer(__func__, skb->data, skb->len);
++
++	mapping = dma_map_single(&lp->ndev->dev,
++		skb->data, skb->len, DMA_TO_DEVICE);
++	if (lp->ipc_tx && (skb->ip_summed == CHECKSUM_PARTIAL)) {
++		tx_flag |= ETH_TDES_CIC;
++	}
++
++	lp->tx.rng_tx[entry].skb = skb;
++	lp->tx.rng_tx[entry].mapping = mapping;
++	lp->tx.desc_tx[entry].buffer1 = mapping;
++	lp->tx.desc_tx[entry].length = ETH_TDES1_TBS1x(skb->len);
++	lp->tx.desc_tx[entry].status = 0;
++	amba_set_eth_desc(&lp->tx.desc_tx[entry], tx_flag);
++	lp->tx.desc_tx[entry].status |= ETH_TDES0_OWN;
++
++	lp->tx.cur_tx++;
++	ambhw_dma_tx_poll(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	ndev->trans_start = jiffies;
++	dev_vdbg(&lp->ndev->dev, "TX Info: cur_tx[%u], dirty_tx[%u], "
++		"entry[%u], len[%u], data_len[%u], ip_summed[%u], "
++		"csum_start[%u], csum_offset[%u].\n",
++		lp->tx.cur_tx, lp->tx.dirty_tx, entry, skb->len, skb->data_len,
++		skb->ip_summed, skb->csum_start, skb->csum_offset);
++
++ambeth_hard_start_xmit_exit:
++	return ret_val;
++}
++
++static void ambeth_timeout(struct net_device *ndev)
++{
++	struct ambeth_info *lp;
++	unsigned long flags;
++	u32 irq_status;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++
++	dev_info(&lp->ndev->dev, "OOM Info:...\n");
++	spin_lock_irqsave(&lp->lock, flags);
++	irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
++	ambeth_interrupt_tx(lp, irq_status | AMBETH_TXDMA_STATUS);
++	ambhw_dump(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	netif_wake_queue(ndev);
++}
++
++static struct net_device_stats *ambeth_get_stats(struct net_device *ndev)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++
++	return &lp->stats;
++}
++
++static void ambhw_dump_rx(struct ambeth_info *lp, u32 status, u32 entry)
++{
++	short pkt_len;
++	struct sk_buff *skb;
++	dma_addr_t mapping;
++
++	pkt_len = ETH_RDES0_FL(status) - 4;
++	if (unlikely(pkt_len > AMBETH_RX_COPYBREAK)) {
++		dev_warn(&lp->ndev->dev, "Bogus packet size %u.\n", pkt_len);
++		pkt_len = AMBETH_RX_COPYBREAK;
++	}
++
++	skb = lp->rx.rng_rx[entry].skb;
++	mapping = lp->rx.rng_rx[entry].mapping;
++	if (likely(skb && mapping)) {
++		dma_unmap_single(&lp->ndev->dev, mapping,
++			AMBETH_PACKET_MAXFRAME, DMA_FROM_DEVICE);
++		skb_put(skb, pkt_len);
++		lp->rx.rng_rx[entry].skb = NULL;
++		lp->rx.rng_rx[entry].mapping = 0;
++		ambhw_dump_buffer(__func__, skb->data, skb->len);
++		dev_kfree_skb(skb);
++	}
++}
++
++static inline void ambeth_check_rdes0_status(struct ambeth_info *lp,
++	u32 status, u32 entry)
++{
++	if (status & ETH_RDES0_DE) {
++		lp->stats.rx_frame_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"RX Error: Descriptor Error.\n");
++	}
++	if (status & ETH_RDES0_SAF) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"RX Error: Source Address Filter Fail.\n");
++	}
++	if (status & ETH_RDES0_LE) {
++		lp->stats.rx_length_errors++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "RX Error: Length Error.\n");
++	}
++	if (status & ETH_RDES0_OE) {
++		lp->stats.rx_over_errors++;
++		if (netif_msg_rx_err(lp))
++			dev_err(&lp->ndev->dev, "RX Error: Overflow Error.\n");
++	}
++	if (status & ETH_RDES0_VLAN) {
++		if (netif_msg_drv(lp))
++			dev_info(&lp->ndev->dev, "RX Info: VLAN.\n");
++	}
++	if (status & ETH_RDES0_IPC) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"RX Error: IPC Checksum/Giant Frame.\n");
++	}
++	if (status & ETH_RDES0_LC) {
++		lp->stats.collisions++;
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev, "RX Error: Late Collision.\n");
++	}
++	if (status & ETH_RDES0_FT) {
++		if (netif_msg_rx_err(lp))
++			dev_info(&lp->ndev->dev,
++			"RX Info: Ethernet-type frame.\n");
++	}
++	if (status & ETH_RDES0_RWT) {
++		if (netif_msg_drv(lp))
++			dev_err(&lp->ndev->dev,
++			"RX Error: Watchdog Timeout.\n");
++	}
++	if (status & ETH_RDES0_RE) {
++		lp->stats.rx_errors++;
++		if (netif_msg_rx_err(lp))
++			dev_err(&lp->ndev->dev, "RX Error: Receive.\n");
++	}
++	if (status & ETH_RDES0_DBE) {
++		if (amba_tstbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
++			ETH_MAC_CFG_PS)) {
++			lp->stats.rx_length_errors++;
++			if (netif_msg_drv(lp))
++				dev_err(&lp->ndev->dev,
++				"RX Error: Dribble Bit.\n");
++		}
++	}
++	if (status & ETH_RDES0_CE) {
++		lp->stats.rx_crc_errors++;
++		if (netif_msg_rx_err(lp)) {
++			dev_err(&lp->ndev->dev, "RX Error: CRC.\n");
++		}
++	}
++	if (status & ETH_RDES0_RX) {
++		if (netif_msg_drv(lp)) {
++			dev_err(&lp->ndev->dev,
++			"RX Error: Rx MAC Address/Payload Checksum.\n");
++			if (lp->dump_rx)
++				ambhw_dump_rx(lp, status, entry);
++		}
++	}
++}
++
++static inline void ambeth_napi_rx(struct ambeth_info *lp, u32 status, u32 entry)
++{
++	short pkt_len;
++	struct sk_buff *skb;
++	dma_addr_t mapping;
++
++	pkt_len = ETH_RDES0_FL(status) - 4;
++	skb = lp->rx.rng_rx[entry].skb;
++	mapping = lp->rx.rng_rx[entry].mapping;
++	if (likely(skb && mapping)) {
++		dma_unmap_single(&lp->ndev->dev, mapping,
++			AMBETH_PACKET_MAXFRAME, DMA_FROM_DEVICE);
++		skb_put(skb, pkt_len);
++		skb->protocol = eth_type_trans(skb, lp->ndev);
++		if(ETH_ENHANCED == 0) {
++			if (lp->ipc_rx) {
++				if ((status & ETH_RDES0_COE_MASK) ==
++					ETH_RDES0_COE_NOCHKERROR) {
++					skb->ip_summed = CHECKSUM_UNNECESSARY;
++				} else {
++					skb->ip_summed = CHECKSUM_NONE;
++					if (netif_msg_rx_err(lp)) {
++						dev_err(&lp->ndev->dev,
++						"RX Error: RDES0_COE[0x%x].\n", status);
++					}
++				}
++			}
++
++		}
++
++		if (unlikely(lp->dump_rx)) {
++			ambhw_dump_buffer(__func__, (skb->data - 14),
++				(skb->len + 14));
++		}
++		if (unlikely(lp->dump_rx_free))
++			kfree_skb(skb);
++		else
++			netif_receive_skb(skb);
++
++		lp->rx.rng_rx[entry].skb = NULL;
++		lp->rx.rng_rx[entry].mapping = 0;
++		lp->ndev->last_rx = jiffies;
++		lp->stats.rx_packets++;
++		lp->stats.rx_bytes += pkt_len;
++		lp->rx.cur_rx++;
++	} else {
++		if (netif_msg_drv(lp)) {
++			dev_err(&lp->ndev->dev,
++			"RX Error: %u skb[%p], map[0x%08X].\n",
++			entry, skb, mapping);
++		}
++	}
++}
++
++int ambeth_napi(struct napi_struct *napi, int budget)
++{
++	int rx_budget = budget;
++	struct ambeth_info *lp;
++	u32 entry;
++	u32 status;
++	unsigned long flags;
++	unsigned int dirty_diff;
++	short pkt_len;
++
++	lp = container_of(napi, struct ambeth_info, napi);
++	dev_vdbg(&lp->ndev->dev, "cur_rx[%u], dirty_rx[%u]\n",
++		lp->rx.cur_rx, lp->rx.dirty_rx);
++
++	if (unlikely(!netif_carrier_ok(lp->ndev)))
++		goto ambeth_poll_complete;
++
++	while (rx_budget > 0) {
++		entry = lp->rx.cur_rx % lp->rx_count;
++		status = lp->rx.desc_rx[entry].status;
++		if (status & ETH_RDES0_OWN)
++			break;
++
++		pkt_len = ETH_RDES0_FL(status) - 4;
++		if (unlikely(pkt_len > AMBETH_RX_COPYBREAK)) {
++			dev_err(&lp->ndev->dev, "ambarella eth: jumbo frame[size:%d] received drop\n",
++				pkt_len);
++			ambhw_dma_rx_stop(lp);
++			ambeth_check_rdes0_status(lp, status, entry);
++			lp->rx.cur_rx++;
++			break;
++		}
++
++		if (unlikely((status & (ETH_RDES0_FS | ETH_RDES0_LS)) !=
++			(ETH_RDES0_FS | ETH_RDES0_LS))) {
++			break;
++		}
++		if (likely((status & ETH_RDES0_ES) != ETH_RDES0_ES)) {
++			ambeth_napi_rx(lp, status, entry);
++		} else {
++			ambhw_dma_rx_stop(lp);
++			ambeth_check_rdes0_status(lp, status, entry);
++			rx_budget += lp->rx_count;
++			lp->rx.cur_rx++;
++		}
++		rx_budget--;
++
++		dirty_diff = (lp->rx.cur_rx - lp->rx.dirty_rx);
++		if (dirty_diff > (lp->rx_count / 4)) {
++			ambeth_rx_rngmng_refill(lp);
++		}
++	}
++
++ambeth_poll_complete:
++	if (rx_budget > 0) {
++		ambeth_rx_rngmng_refill(lp);
++		spin_lock_irqsave(&lp->lock, flags);
++		napi_complete(&lp->napi);
++		amba_setbitsl(lp->regbase + ETH_DMA_INTEN_OFFSET,
++			AMBETH_RXDMA_INTEN);
++		ambhw_dma_rx_start(lp);
++		spin_unlock_irqrestore(&lp->lock, flags);
++	}
++
++	dev_vdbg(&lp->ndev->dev, "cur_rx[%u], dirty_rx[%u], rx_budget[%u]\n",
++		lp->rx.cur_rx, lp->rx.dirty_rx, rx_budget);
++	return (budget - rx_budget);
++}
++
++static inline u32 ambhw_hashtable_crc(unsigned char *mac)
++{
++	unsigned char tmpbuf[ETH_ALEN];
++	int i;
++	u32 crc;
++
++	for (i = 0; i < ETH_ALEN; i++)
++		tmpbuf[i] = bitrev8(mac[i]);
++	crc = crc32_be(~0, tmpbuf, ETH_ALEN);
++
++	return (crc ^ ~0);
++}
++
++static inline void ambhw_hashtable_get(struct net_device *ndev, u32 *hat)
++{
++	struct netdev_hw_addr *ha;
++	unsigned int bitnr;
++#if 0
++	unsigned char test1[] = {0x1F,0x52,0x41,0x9C,0xB6,0xAF};
++	unsigned char test2[] = {0xA0,0x0A,0x98,0x00,0x00,0x45};
++	dev_info(&ndev->dev,
++		"Test1: 0x%08X.\n", ambhw_hashtable_crc(test1));
++	dev_info(&ndev->dev,
++		"Test2: 0x%08X.\n", ambhw_hashtable_crc(test2));
++#endif
++
++	hat[0] = hat[1] = 0;
++	netdev_for_each_mc_addr(ha, ndev) {
++		if (!(ha->addr[0] & 1))
++			continue;
++		bitnr = ambhw_hashtable_crc(ha->addr);
++		bitnr >>= 26;
++		bitnr &= 0x3F;
++		hat[bitnr >> 5] |= 1 << (bitnr & 31);
++	}
++}
++
++static void ambeth_set_multicast_list(struct net_device *ndev)
++{
++	struct ambeth_info *lp;
++	unsigned int mac_filter;
++	u32 hat[2];
++	unsigned long flags;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++	spin_lock_irqsave(&lp->lock, flags);
++
++	mac_filter = amba_readl(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET);
++	hat[0] = 0;
++	hat[1] = 0;
++
++	if (ndev->flags & IFF_PROMISC) {
++		mac_filter |= ETH_MAC_FRAME_FILTER_PR;
++	} else if (ndev->flags & (~IFF_PROMISC)) {
++		mac_filter &= ~ETH_MAC_FRAME_FILTER_PR;
++	}
++
++	if (ndev->flags & IFF_ALLMULTI) {
++		hat[0] = 0xFFFFFFFF;
++		hat[1] = 0xFFFFFFFF;
++		mac_filter |= ETH_MAC_FRAME_FILTER_PM;
++	} else if (!netdev_mc_empty(ndev)) {
++		ambhw_hashtable_get(ndev, hat);
++		mac_filter &= ~ETH_MAC_FRAME_FILTER_PM;
++		mac_filter |= ETH_MAC_FRAME_FILTER_HMC;
++	} else if (ndev->flags & (~IFF_ALLMULTI)) {
++		mac_filter &= ~ETH_MAC_FRAME_FILTER_PM;
++		mac_filter |= ETH_MAC_FRAME_FILTER_HMC;
++	}
++
++	if (netif_msg_hw(lp)) {
++		dev_info(&lp->ndev->dev, "MC Info: flags 0x%x.\n", ndev->flags);
++		dev_info(&lp->ndev->dev, "MC Info: mc_count 0x%x.\n",
++			netdev_mc_count(ndev));
++		dev_info(&lp->ndev->dev, "MC Info: mac_filter 0x%x.\n",
++			mac_filter);
++		dev_info(&lp->ndev->dev, "MC Info: hat[0x%x:0x%x].\n",
++			hat[1], hat[0]);
++	}
++
++	amba_writel(lp->regbase + ETH_MAC_HASH_HI_OFFSET, hat[1]);
++	amba_writel(lp->regbase + ETH_MAC_HASH_LO_OFFSET, hat[0]);
++	amba_writel(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET, mac_filter);
++
++	spin_unlock_irqrestore(&lp->lock, flags);
++}
++
++static int ambeth_set_mac_address(struct net_device *ndev, void *addr)
++{
++	struct ambeth_info *lp = (struct ambeth_info *)netdev_priv(ndev);
++	struct sockaddr *saddr = addr;
++	unsigned long flags;
++
++	if (!is_valid_ether_addr(saddr->sa_data))
++		return -EADDRNOTAVAIL;
++
++	spin_lock_irqsave(&lp->lock, flags);
++
++	if (netif_running(ndev)) {
++		spin_unlock_irqrestore(&lp->lock, flags);
++		return -EBUSY;
++	}
++
++	dev_dbg(&lp->ndev->dev, "MAC address[%pM].\n", saddr->sa_data);
++
++	memcpy(ndev->dev_addr, saddr->sa_data, ndev->addr_len);
++	ambhw_set_hwaddr(lp, ndev->dev_addr);
++	ambhw_get_hwaddr(lp, ndev->dev_addr);
++
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	return 0;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void ambeth_poll_controller(struct net_device *ndev)
++{
++	ambeth_interrupt(ndev->irq, ndev);
++}
++#endif
++
++static int ambeth_ioctl(struct net_device *ndev, struct ifreq *ifr, int ecmd)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++
++	if (!netif_running(ndev))
++		return -EINVAL;
++
++	if (!lp->phydev)
++		return -ENODEV;
++
++	return phy_mii_ioctl(lp->phydev, ifr, ecmd);
++}
++
++static const struct net_device_ops ambeth_netdev_ops = {
++	.ndo_open		= ambeth_open,
++	.ndo_stop		= ambeth_stop,
++	.ndo_start_xmit		= ambeth_hard_start_xmit,
++	.ndo_set_rx_mode	= ambeth_set_multicast_list,
++	.ndo_set_mac_address 	= ambeth_set_mac_address,
++	.ndo_validate_addr	= eth_validate_addr,
++	.ndo_do_ioctl		= ambeth_ioctl,
++	.ndo_change_mtu		= eth_change_mtu,
++	.ndo_tx_timeout		= ambeth_timeout,
++	.ndo_get_stats		= ambeth_get_stats,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	.ndo_poll_controller	= ambeth_poll_controller,
++#endif
++};
++
++/* ==========================================================================*/
++static int ambeth_get_settings(struct net_device *ndev,
++	struct ethtool_cmd *ecmd)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	int ret_val = 0;
++
++	if (!netif_running(ndev))
++		return -EINVAL;
++
++	if (lp->phy_enabled) {
++		ret_val = phy_ethtool_gset(lp->phydev, ecmd);
++	} else {
++		ret_val = -EINVAL;
++		if (lp->oldlink == PHY_RUNNING) {
++			ethtool_cmd_speed_set(ecmd, lp->oldspeed);
++			ecmd->duplex = lp->oldduplex;
++			ecmd->port = PORT_MII;
++			ecmd->phy_address = 0xFF;
++			ecmd->transceiver = XCVR_EXTERNAL;
++			ecmd->autoneg = AUTONEG_DISABLE;
++			ecmd->supported = SUPPORTED_MII;
++			switch (lp->oldspeed) {
++			case SPEED_1000:
++				if (lp->oldduplex == DUPLEX_FULL) {
++					ecmd->supported |=
++						SUPPORTED_1000baseT_Full;
++				} else {
++					ecmd->supported |=
++						SUPPORTED_1000baseT_Half;
++				}
++				ret_val = 0;
++				break;
++			case SPEED_100:
++				if (lp->oldduplex == DUPLEX_FULL) {
++					ecmd->supported |=
++						SUPPORTED_100baseT_Full;
++				} else {
++					ecmd->supported |=
++						SUPPORTED_100baseT_Half;
++				}
++				ret_val = 0;
++				break;
++			case SPEED_10:
++				if (lp->oldduplex == DUPLEX_FULL) {
++					ecmd->supported |=
++						SUPPORTED_10baseT_Full;
++				} else {
++					ecmd->supported |=
++						SUPPORTED_10baseT_Half;
++				}
++				ret_val = 0;
++				break;
++			default:
++				break;
++			}
++			ecmd->advertising = ecmd->supported;
++		}
++	}
++
++	return ret_val;
++}
++
++static int ambeth_set_settings(struct net_device *ndev,
++	struct ethtool_cmd *ecmd)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++
++	if (!netif_running(ndev) || !lp->phy_enabled)
++		return -EINVAL;
++
++	return phy_ethtool_sset(lp->phydev, ecmd);
++}
++
++static int ambeth_get_dump_flag(struct net_device *ndev,
++	struct ethtool_dump *ed)
++{
++	ed->len = (AMBETH_PHY_REG_SIZE * sizeof(u16));
++	ed->flag = 0;
++	pr_debug("%s: cmd[0x%08X], version[0x%08X], "
++		"flag[0x%08X], len[0x%08X]\n",
++		__func__, ed->cmd, ed->version,
++		ed->flag, ed->len);
++
++	return 0;
++}
++
++static int ambeth_get_dump_data(struct net_device *ndev,
++	struct ethtool_dump *ed, void *pdata)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	int i;
++	u16 *regbuf;
++
++	pr_debug("%s: cmd[0x%08X], version[0x%08X], "
++		"flag[0x%08X], len[0x%08X]\n",
++		__func__, ed->cmd, ed->version,
++		ed->flag, ed->len);
++
++	if (!lp->phy_enabled) {
++		return -EINVAL;
++	}
++	regbuf = (u16 *)pdata;
++	for (i = 0; i < (ed->len / 2); i++) {
++		regbuf[i] = mdiobus_read(lp->phydev->bus,
++			lp->phydev->addr, i);
++	}
++
++	return 0;
++}
++
++static int ambeth_set_dump(struct net_device *ndev, struct ethtool_dump *ed)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	u16 dbg_address;
++	u16 dbg_value;
++
++	pr_debug("%s: cmd[0x%08X], version[0x%08X], "
++		"flag[0x%08X], len[0x%08X]\n",
++		__func__, ed->cmd, ed->version,
++		ed->flag, ed->len);
++
++	if (!lp->phy_enabled) {
++		return -EINVAL;
++	}
++	dbg_address = ((ed->flag & 0xFFFF0000) >> 16);
++	dbg_value = (ed->flag & 0x0000FFFF);
++	mdiobus_write(lp->phydev->bus, lp->phydev->addr,
++		dbg_address, dbg_value);
++
++	return 0;
++}
++
++static u32 ambeth_get_msglevel(struct net_device *ndev)
++{
++	struct ambeth_info *lp;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++
++	return lp->msg_enable;
++}
++
++static void ambeth_set_msglevel(struct net_device *ndev, u32 value)
++{
++	struct ambeth_info *lp;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++
++	lp->msg_enable = value;
++}
++
++static void ambeth_get_pauseparam(struct net_device *ndev,
++				  struct ethtool_pauseparam *pause)
++{
++	struct ambeth_info *lp;
++	u32 flow_ctr;
++
++	lp = (struct ambeth_info *)netdev_priv(ndev);
++	flow_ctr = lp->flow_ctr;
++
++	pause->autoneg = (flow_ctr & AMBARELLA_ETH_FC_AUTONEG) ?
++				AUTONEG_ENABLE : AUTONEG_DISABLE;
++
++	pause->rx_pause = (flow_ctr & AMBARELLA_ETH_FC_RX) ? 1 : 0;
++	pause->tx_pause = (flow_ctr & AMBARELLA_ETH_FC_TX) ? 1 : 0;
++}
++
++static int ambeth_set_pauseparam(struct net_device *ndev,
++				 struct ethtool_pauseparam *pause)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	u32 flow_ctr;
++	int ret_val = 0;
++
++	/*
++	 * Symmeteric pause can respond to recieved pause frames, and
++	 * send pause frames to the link partner.
++	 *
++	 * Asymmetric pause can send pause frames, but can't respond to
++	 * pause frames from the link partner.
++	 *
++	 * Autoneg only advertises and reports the 'cap (or will)' of
++	 * the link partner. The final resolution still has to be done in
++	 * MAC / Driver.
++	 *
++	 * Since our MAC can support both directions independently, we
++	 * advertise our 'cap' to the link partner based on the
++	 * pauseparam specified by the user (ethtool). And take the
++	 * 'cap' of the link partner reported into consideration for
++	 * makeing the final resolution.
++	 */
++
++	flow_ctr = lp->flow_ctr;
++
++	if (pause->autoneg)
++		flow_ctr |= AMBARELLA_ETH_FC_AUTONEG;
++	else
++		flow_ctr &= ~AMBARELLA_ETH_FC_AUTONEG;
++
++	if (pause->rx_pause)
++		flow_ctr |= AMBARELLA_ETH_FC_RX;
++	else
++		flow_ctr &= ~AMBARELLA_ETH_FC_RX;
++
++	if (pause->tx_pause)
++		flow_ctr |= AMBARELLA_ETH_FC_TX;
++	else
++		flow_ctr &= ~AMBARELLA_ETH_FC_TX;
++
++	lp->flow_ctr = flow_ctr;
++	if(lp->flow_ctr & (AMBARELLA_ETH_FC_TX | AMBARELLA_ETH_FC_RX))
++		lp->phy_supported |= SUPPORTED_Pause;
++	else
++		lp->phy_supported &= ~SUPPORTED_Pause;
++
++
++	ambeth_fc_config(lp);
++
++	if (pause->autoneg && lp->phydev->autoneg) {
++
++		ret_val = phy_start_aneg(lp->phydev);
++		if (ret_val)
++			goto done;
++	}
++	else {
++		ambeth_fc_resolve(lp);
++	}
++done:
++	return ret_val;
++}
++
++static int ambeth_get_eee(struct net_device *ndev, struct ethtool_eee *e)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++
++	/*now our chip don't support EEE*/
++	e->eee_enabled = false;
++	e->eee_active = false;
++	e->tx_lpi_enabled = false;
++	e->tx_lpi_timer = 0;
++
++	return phy_ethtool_get_eee(lp->phydev, e);
++}
++
++static int ambeth_set_eee(struct net_device *ndev, struct ethtool_eee *e)
++{
++	struct ambeth_info *lp = netdev_priv(ndev);
++	int ret = 0;
++
++	if(e->eee_enabled || e->tx_lpi_enabled) {
++		dev_err(&lp->ndev->dev, "eth don't support EEE.\n");
++		return -EOPNOTSUPP;
++	}
++
++	ret = phy_init_eee(lp->phydev, 0);
++	if (ret) {
++		dev_err(&lp->ndev->dev, "phy don't support EEE.\n");
++		return ret;
++	}
++
++	return phy_ethtool_set_eee(lp->phydev, e);
++}
++
++static const struct ethtool_ops ambeth_ethtool_ops = {
++	.get_settings		= ambeth_get_settings,
++	.set_settings		= ambeth_set_settings,
++	.get_link		= ethtool_op_get_link,
++	.get_dump_flag		= ambeth_get_dump_flag,
++	.get_dump_data		= ambeth_get_dump_data,
++	.set_dump		= ambeth_set_dump,
++	.get_msglevel		= ambeth_get_msglevel,
++	.set_msglevel		= ambeth_set_msglevel,
++	.get_pauseparam		= ambeth_get_pauseparam,
++	.set_pauseparam		= ambeth_set_pauseparam,
++	.get_eee		= ambeth_get_eee,
++	.set_eee		= ambeth_set_eee,
++};
++
++/* ==========================================================================*/
++static int ambeth_of_parse(struct device_node *np, struct ambeth_info *lp)
++{
++	struct device_node *phy_np;
++	enum of_gpio_flags flags;
++	int gmii, ret_val, clk_src, clk_direction, clk_pl;
++
++	ret_val = of_property_read_u32(np, "amb,fixed-speed", &lp->fixed_speed);
++	if (ret_val < 0)
++		lp->fixed_speed = SPEED_UNKNOWN;
++
++	gmii = !!of_find_property(np, "amb,support-gmii", NULL);
++	if (gmii) {
++		lp->phy_supported = (	SUPPORTED_10baseT_Half | \
++					SUPPORTED_10baseT_Full | \
++					SUPPORTED_100baseT_Half | \
++					SUPPORTED_100baseT_Full | \
++					SUPPORTED_1000baseT_Half | \
++					SUPPORTED_1000baseT_Full | \
++					SUPPORTED_Autoneg | \
++					SUPPORTED_MII);
++	} else {
++		lp->phy_supported = (	SUPPORTED_10baseT_Half | \
++					SUPPORTED_10baseT_Full | \
++					SUPPORTED_100baseT_Half | \
++					SUPPORTED_100baseT_Full | \
++					SUPPORTED_Autoneg | \
++					SUPPORTED_MII);
++	}
++
++	/*enable flow control*/
++	lp->phy_supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
++
++	ret_val = of_property_read_u32(np, "amb,tx-ring-size", &lp->tx_count);
++	if (ret_val < 0 || lp->tx_count < AMBETH_TX_RNG_MIN)
++		lp->tx_count = AMBETH_TX_RNG_MIN;
++
++	ret_val = of_property_read_u32(np, "amb,rx-ring-size", &lp->rx_count);
++	if (ret_val < 0 || lp->rx_count < AMBETH_RX_RNG_MIN)
++		lp->rx_count = AMBETH_RX_RNG_MIN;
++
++	lp->tx_irq_low = ((lp->tx_count * 1) / 4);
++	lp->tx_irq_high = ((lp->tx_count * 3) / 4);
++
++	lp->ipc_tx = !!of_find_property(np, "amb,ipc-tx", NULL);
++	lp->ipc_rx = !!of_find_property(np, "amb,ipc-rx", NULL);
++	lp->dump_tx = !!of_find_property(np, "amb,dump-tx", NULL);
++	lp->dump_rx = !!of_find_property(np, "amb,dump-rx", NULL);
++	lp->dump_rx_free = !!of_find_property(np, "amb,dump-rx-free", NULL);
++	lp->dump_rx_all = !!of_find_property(np, "amb,dump-rx-all", NULL);
++	lp->mdio_gpio = !!of_find_property(np, "amb,mdio-gpio", NULL);
++
++	for_each_child_of_node(np, phy_np) {
++		if (!phy_np->name || of_node_cmp(phy_np->name, "phy"))
++			continue;
++
++		lp->pwr_gpio = of_get_named_gpio_flags(phy_np, "pwr-gpios", 0, &flags);
++		lp->pwr_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++		lp->rst_gpio = of_get_named_gpio_flags(phy_np, "rst-gpios", 0, &flags);
++		lp->rst_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++		ret_val = of_property_read_u32(phy_np, "amb,clk-src", &clk_src);
++		if (ret_val == 0 && clk_src == 0) {
++			/*clk_src == 0 represent the clk is external*/
++			amba_writel(ENET_CLK_SRC_SEL_REG, 0x00);
++		} else if(ret_val == 0 && clk_src == 1) {
++			/*clk_src == 1 and default represent the clk is internal*/
++			amba_writel(ENET_CLK_SRC_SEL_REG, 0x01);
++		} else {
++			/*default value for clk source*/
++		}
++
++		ret_val = of_property_read_u32(phy_np, "amb,clk-invert", &clk_pl);
++		if(ret_val == 0 && clk_pl == 1) {
++			amba_setbitsl(AHB_SCRATCHPAD_REG(0xc), 0x80000000);
++		} else if(ret_val == 0 && clk_pl == 0) {
++			amba_clrbitsl(AHB_SCRATCHPAD_REG(0xc), 0x80000000);
++		}
++
++		ret_val = of_property_read_u32(phy_np, "amb,clk-dir", &clk_direction);
++		if(ret_val == 0 && clk_direction == 1) {
++			/*set direction of xx_enet_clk_rx as output from ambarella chip*/
++			lp->clk_direction = 1;
++			ret_val = amba_readl(AHB_MISC_EN_REG);
++			ret_val |= (1 << 5);
++			amba_writel(AHB_MISC_EN_REG, ret_val);
++		} else if(ret_val == 0 && clk_direction == 0) {
++			/*set direction of xx_enet_clk_rx as output from external phy*/
++			lp->clk_direction = 0;
++			ret_val = amba_readl(AHB_MISC_EN_REG);
++			ret_val &= ~(1 << 5);
++			amba_writel(AHB_MISC_EN_REG, ret_val);
++		} else
++			lp->clk_direction = -1;
++	}
++
++	return 0;
++}
++
++static int ambeth_drv_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node, *mdio_np = NULL;
++	struct net_device *ndev;
++	struct ambeth_info *lp;
++	struct resource *res;
++	const char *macaddr;
++	int ret_val = 0;
++
++	if (!(ambarella_get_poc() & SYS_CONFIG_ETH_ENABLE)) {
++		dev_err(&pdev->dev, "Not enabled, check HW config!\n");
++		return -EPERM;
++	}
++
++	ndev = alloc_etherdev(sizeof(struct ambeth_info));
++	if (ndev == NULL) {
++		dev_err(&pdev->dev, "alloc_etherdev fail.\n");
++		return -ENOMEM;
++	}
++	lp = netdev_priv(ndev);
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "No mem resource for fio_reg!\n");
++		ret_val = -ENXIO;
++		goto ambeth_drv_probe_free_netdev;
++	}
++
++	lp->regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (!lp->regbase) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		ret_val = -ENOMEM;
++		goto ambeth_drv_probe_free_netdev;
++	}
++
++	ndev->irq = platform_get_irq(pdev, 0);
++	if (ndev->irq < 0) {
++		dev_err(&pdev->dev, "no irq for ethernet!\n");
++		ret_val = -ENODEV;
++		goto ambeth_drv_probe_free_netdev;
++	}
++
++	SET_NETDEV_DEV(ndev, &pdev->dev);
++	ndev->dev.dma_mask = pdev->dev.dma_mask;
++	ndev->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
++
++	spin_lock_init(&lp->lock);
++	lp->ndev = ndev;
++	lp->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV);
++
++	ambeth_of_parse(np, lp);
++
++	if (lp->ipc_tx)
++		ndev->features |= NETIF_F_HW_CSUM;
++
++	/* request gpio for PHY power control */
++	if (gpio_is_valid(lp->pwr_gpio)) {
++		ret_val = devm_gpio_request(&pdev->dev,
++			lp->pwr_gpio, "phy power");
++		if (ret_val < 0) {
++			dev_err(&pdev->dev, "Failed to request pwr-gpios!\n");
++			goto ambeth_drv_probe_free_netdev;
++		}
++		gpio_direction_output(lp->pwr_gpio, lp->pwr_gpio_active);
++	}
++
++	/* request gpio for PHY reset control */
++	if (gpio_is_valid(lp->rst_gpio)) {
++		ret_val = devm_gpio_request(&pdev->dev,
++			lp->rst_gpio, "phy reset");
++		if (ret_val < 0) {
++			dev_err(&pdev->dev, "Failed to request rst-gpios!\n");
++			goto ambeth_drv_probe_free_netdev;
++		}
++		gpio_direction_output(lp->rst_gpio, !lp->rst_gpio_active);
++	}
++
++	if(lp->mdio_gpio) {
++		mdio_np = of_find_compatible_node(NULL, NULL, "virtual,mdio-gpio");
++
++		if(mdio_np == NULL) {
++			dev_err(&pdev->dev, "Failed to get mdio_gpio device node\n");
++			goto ambeth_drv_probe_free_netdev;
++		}
++
++		lp->phydev = of_phy_find_device(mdio_np->child);
++
++		if(!lp->phydev) {
++			dev_err(&pdev->dev, "Failed to get phydev from mdio_gpio device node\n");
++			goto ambeth_drv_probe_free_netdev;
++		}
++
++		lp->new_bus = *lp->phydev->bus;
++	} else {
++		lp->new_bus.name = "Ambarella MII Bus",
++		lp->new_bus.read = &ambhw_mdio_read,
++		lp->new_bus.write = &ambhw_mdio_write,
++		lp->new_bus.reset = &ambhw_mdio_reset,
++		snprintf(lp->new_bus.id, MII_BUS_ID_SIZE, "%s", pdev->name);
++		lp->new_bus.priv = lp;
++		lp->new_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
++		if (lp->new_bus.irq == NULL) {
++			dev_err(&pdev->dev, "alloc new_bus.irq fail.\n");
++			ret_val = -ENOMEM;
++			goto ambeth_drv_probe_free_netdev;
++		}
++
++		lp->new_bus.parent = &pdev->dev;
++		lp->new_bus.state = MDIOBUS_ALLOCATED;
++
++		ret_val = of_mdiobus_register(&lp->new_bus, pdev->dev.of_node);
++		if (ret_val < 0) {
++			dev_err(&pdev->dev, "mdiobus_register fail%d.\n", ret_val);
++			goto ambeth_drv_probe_kfree_mdiobus;
++		}
++
++		lp->phydev = phy_find_first(&lp->new_bus);
++		if (lp->phydev == NULL) {
++			dev_err(&pdev->dev, "No PHY device.\n");
++			ret_val = -ENODEV;
++			goto ambeth_drv_probe_kfree_mdiobus;
++		}
++	}
++
++	if (netif_msg_drv(lp)) {
++		dev_info(&pdev->dev, "Ethernet PHY[%d]: 0x%08x!\n",
++				lp->phydev->addr, lp->phydev->phy_id);
++	}
++
++	ether_setup(ndev);
++	ndev->netdev_ops = &ambeth_netdev_ops;
++	ndev->watchdog_timeo = AMBETH_TX_WATCHDOG;
++	netif_napi_add(ndev, &lp->napi, ambeth_napi, AMBETH_NAPI_WEIGHT);
++
++	macaddr = of_get_mac_address(pdev->dev.of_node);
++	if (macaddr)
++		memcpy(ndev->dev_addr, macaddr, ETH_ALEN);
++
++	if (!is_valid_ether_addr(ndev->dev_addr))
++		eth_hw_addr_random(ndev);
++
++	ambhw_disable(lp);
++
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio))
++		gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
++
++	SET_ETHTOOL_OPS(ndev, &ambeth_ethtool_ops);
++	ret_val = register_netdev(ndev);
++	if (ret_val) {
++		dev_err(&pdev->dev, " register_netdev fail%d.\n", ret_val);
++		goto ambeth_drv_probe_netif_napi_del;
++	}
++
++	platform_set_drvdata(pdev, ndev);
++	dev_notice(&pdev->dev, "MAC Address[%pM].\n", ndev->dev_addr);
++
++	return 0;
++
++ambeth_drv_probe_netif_napi_del:
++	netif_napi_del(&lp->napi);
++	mdiobus_unregister(&lp->new_bus);
++
++ambeth_drv_probe_kfree_mdiobus:
++	kfree(lp->new_bus.irq);
++
++ambeth_drv_probe_free_netdev:
++	free_netdev(ndev);
++	return ret_val;
++}
++
++static int ambeth_drv_remove(struct platform_device *pdev)
++{
++	struct net_device *ndev = platform_get_drvdata(pdev);
++	struct ambeth_info *lp = netdev_priv(ndev);
++
++	unregister_netdev(ndev);
++	netif_napi_del(&lp->napi);
++	mdiobus_unregister(&lp->new_bus);
++	kfree(lp->new_bus.irq);
++	platform_set_drvdata(pdev, NULL);
++	free_netdev(ndev);
++	dev_notice(&pdev->dev, "Removed.\n");
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int ambeth_drv_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct net_device *ndev = platform_get_drvdata(pdev);
++	struct ambeth_info *lp = netdev_priv(ndev);
++	int ret_val = 0;
++	unsigned long flags;
++
++	if (!netif_running(ndev))
++		goto ambeth_drv_suspend_exit;
++
++	napi_disable(&lp->napi);
++	netif_device_detach(ndev);
++	disable_irq(ndev->irq);
++
++	ambeth_phy_stop(lp);
++
++	spin_lock_irqsave(&lp->lock, flags);
++	ambhw_disable(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio))
++		gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
++
++ambeth_drv_suspend_exit:
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++		__func__, ret_val, state.event);
++
++	return ret_val;
++}
++
++static int ambeth_drv_resume(struct platform_device *pdev)
++{
++	struct net_device *ndev = platform_get_drvdata(pdev);
++	struct ambeth_info *lp = netdev_priv(ndev);
++	int ret_val = 0;
++	unsigned long flags;
++
++	if (!netif_running(ndev))
++		goto ambeth_drv_resume_exit;
++
++	if(lp->clk_direction == 1) {
++		ret_val = amba_readl(AHB_MISC_EN_REG);
++		ret_val |= (1 << 5);
++		amba_writel(AHB_MISC_EN_REG, ret_val);
++	} else if(lp->clk_direction == 0) {
++		ret_val = amba_readl(AHB_MISC_EN_REG);
++		ret_val &= ~(1 << 5);
++		amba_writel(AHB_MISC_EN_REG, ret_val);
++	}
++
++	if (gpio_is_valid(lp->pwr_gpio))
++		gpio_set_value_cansleep(lp->pwr_gpio, lp->pwr_gpio_active);
++	if (gpio_is_valid(lp->rst_gpio)) {
++		gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
++		msleep(10);
++		gpio_set_value_cansleep(lp->rst_gpio, !lp->rst_gpio_active);
++	}
++
++	spin_lock_irqsave(&lp->lock, flags);
++	ret_val = ambhw_enable(lp);
++	ambhw_set_link_mode_speed(lp);
++	ambeth_rx_rngmng_init(lp);
++	ambeth_tx_rngmng_init(lp);
++	ambhw_set_dma_desc(lp);
++	ambhw_dma_rx_start(lp);
++	ambhw_dma_tx_start(lp);
++	ambhw_dma_int_enable(lp);
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	if (ret_val) {
++		dev_err(&pdev->dev, "ambhw_enable.\n");
++	} else {
++		ambeth_set_multicast_list(ndev);
++		netif_carrier_off(ndev);
++		ret_val = ambeth_phy_start(lp);
++		enable_irq(ndev->irq);
++		netif_device_attach(ndev);
++		napi_enable(&lp->napi);
++	}
++ambeth_drv_resume_exit:
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, ret_val);
++	return ret_val;
++}
++#endif
++
++static const struct of_device_id ambarella_eth_dt_ids[] = {
++	{ .compatible = "ambarella,eth" },
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ambarella_eth_dt_ids);
++
++static struct platform_driver ambeth_driver = {
++	.probe		= ambeth_drv_probe,
++	.remove		= ambeth_drv_remove,
++#ifdef CONFIG_PM
++	.suspend        = ambeth_drv_suspend,
++	.resume		= ambeth_drv_resume,
++#endif
++	.driver = {
++		.name	= "ambarella-eth",
++		.owner	= THIS_MODULE,
++		.of_match_table	= ambarella_eth_dt_ids,
++	},
++};
++
++module_platform_driver(ambeth_driver);
++
++MODULE_DESCRIPTION("Ambarella Media Processor Ethernet Driver");
++MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 1e11f2bf..b29a0f6b 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -106,6 +106,13 @@ config MICREL_PHY
+ 	---help---
+ 	  Supports the KSZ9021, VSC8201, KS8001 PHYs.
+ 
++config MICREL_PHY_KSZ80X1R
++	tristate "Driver for Micrel PHYs KSZ80X1R"
++	depends on PLAT_AMBARELLA=y
++	depends on MICREL_PHY=n
++	---help---
++	  Supports the KSZ80X1R PHYs.
++
+ config FIXED_PHY
+ 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+ 	depends on PHYLIB=y
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index 9645e389..04c9ddc7 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -23,6 +23,7 @@ obj-$(CONFIG_NATIONAL_PHY)	+= national.o
+ obj-$(CONFIG_DP83640_PHY)	+= dp83640.o
+ obj-$(CONFIG_STE10XP)		+= ste10Xp.o
+ obj-$(CONFIG_MICREL_PHY)	+= micrel.o
++obj-$(CONFIG_MICREL_PHY_KSZ80X1R) += ksz80x1r.o
+ obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
+ obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o
+ obj-$(CONFIG_AT803X_PHY)	+= at803x.o
+diff --git a/drivers/net/phy/ksz80x1r.c b/drivers/net/phy/ksz80x1r.c
+new file mode 100644
+index 00000000..64372e8a
+--- /dev/null
++++ b/drivers/net/phy/ksz80x1r.c
+@@ -0,0 +1,150 @@
++/*
++ * drivers/net/phy/ksz80x1r.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2014, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/phy.h>
++#include <linux/micrel_phy.h>
++
++/* ==========================================================================*/
++#define MII_KSZ80X1R_INTCS			0x1B
++#define KSZ80X1R_INTCS_JABBER			(1 << 15)
++#define KSZ80X1R_INTCS_RECEIVE_ERR		(1 << 14)
++#define KSZ80X1R_INTCS_PAGE_RECEIVE		(1 << 13)
++#define KSZ80X1R_INTCS_PARELLEL			(1 << 12)
++#define KSZ80X1R_INTCS_LINK_PARTNER_ACK		(1 << 11)
++#define KSZ80X1R_INTCS_LINK_DOWN		(1 << 10)
++#define KSZ80X1R_INTCS_REMOTE_FAULT		(1 << 9)
++#define KSZ80X1R_INTCS_LINK_UP			(1 << 8)
++#define KSZ80X1R_INTCS_ALL			(KSZ80X1R_INTCS_LINK_UP |\
++						KSZ80X1R_INTCS_LINK_DOWN)
++
++#define MII_KSZ80X1R_CTRL			0x1F
++#define KSZ80X1R_CTRL_INT_ACTIVE_HIGH		(1 << 9)
++#define KSZ80X1R_RMII_50MHZ_CLK			(1 << 7)
++
++/* ==========================================================================*/
++MODULE_DESCRIPTION("Micrel KSZ8081R");
++MODULE_AUTHOR("Anthony Ginger <hfjiang@ambarella.com>");
++MODULE_LICENSE("GPL");
++
++/* ==========================================================================*/
++static int ksz80x1r_config_init(struct phy_device *phydev)
++{
++	int regval;
++
++	pr_debug("Set KSZ80X1R 50MHz Clock Mode...");
++	regval = phy_read(phydev, MII_KSZ80X1R_CTRL);
++	regval |= KSZ80X1R_RMII_50MHZ_CLK;
++	return phy_write(phydev, MII_KSZ80X1R_CTRL, regval);
++}
++
++void ksz80x1r_prevent_loss(struct phy_device *phydev) {
++	phy_write(phydev, 0x0d, 0x001c);
++	phy_write(phydev, 0x0e, 0x0008);
++	phy_write(phydev, 0x0d, 0x401c);
++	phy_write(phydev, 0x0e, 0x0067);
++	phy_write(phydev, 0x0d, 0x001c);
++	phy_write(phydev, 0x0e, 0x0009);
++	phy_write(phydev, 0x0d, 0x401c);
++	phy_write(phydev, 0x0e, 0xffff);
++	phy_write(phydev, 0x0d, 0x001c);
++	phy_write(phydev, 0x0e, 0x000a);
++	phy_write(phydev, 0x0d, 0x401c);
++	phy_write(phydev, 0x0e, 0xffff);
++}
++
++int ksz80x1r_config_aneg(struct phy_device *phydev)
++{
++	int result;
++
++	result = genphy_config_aneg(phydev);
++	if(result > 0)
++		ksz80x1r_prevent_loss(phydev);
++
++	return result;
++}
++
++static int ksz80x1r_ack_interrupt(struct phy_device *phydev)
++{
++	int rc;
++
++	rc = phy_read(phydev, MII_KSZ80X1R_INTCS);
++
++	return (rc < 0) ? rc : 0;
++}
++
++static int ksz80x1r_set_interrupt(struct phy_device *phydev)
++{
++	int temp;
++	temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ?
++		KSZ80X1R_INTCS_ALL : 0;
++	return phy_write(phydev, MII_KSZ80X1R_INTCS, temp);
++}
++
++static int ksz80x1r_config_intr(struct phy_device *phydev)
++{
++	int temp, rc;
++
++	/* set the interrupt pin active low */
++	temp = phy_read(phydev, MII_KSZ80X1R_CTRL);
++	temp &= ~KSZ80X1R_CTRL_INT_ACTIVE_HIGH;
++	phy_write(phydev, MII_KSZ80X1R_CTRL, temp);
++	rc = ksz80x1r_set_interrupt(phydev);
++	return rc < 0 ? rc : 0;
++}
++
++static struct phy_driver ksz80x1r_driver = {
++	.phy_id		= PHY_ID_KSZ8081,
++	.name		= "Micrel KSZ8081 or KSZ8091",
++	.phy_id_mask	= 0x00fffff0,
++	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
++	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
++	.config_init	= ksz80x1r_config_init,
++	.config_aneg	= ksz80x1r_config_aneg,
++	.read_status	= genphy_read_status,
++	.ack_interrupt	= ksz80x1r_ack_interrupt,
++	.config_intr	= ksz80x1r_config_intr,
++	.driver		= { .owner = THIS_MODULE,},
++};
++
++static int __init ksz80x1r_init(void)
++{
++	return phy_driver_register(&ksz80x1r_driver);
++}
++
++static void __exit ksz80x1r_exit(void)
++{
++	phy_driver_unregister(&ksz80x1r_driver);
++}
++
++/* ==========================================================================*/
++module_init(ksz80x1r_init);
++module_exit(ksz80x1r_exit);
++
++static struct mdio_device_id __maybe_unused ksz80x1r_tbl[] = {
++	{ PHY_ID_KSZ8081, 0x0000fff0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(mdio, ksz80x1r_tbl);
++
+diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
+index a47f9236..a64ad54b 100644
+--- a/drivers/net/phy/mdio-gpio.c
++++ b/drivers/net/phy/mdio-gpio.c
+@@ -30,16 +30,32 @@
+ 
+ #include <linux/of_gpio.h>
+ #include <linux/of_mdio.h>
++#include <linux/delay.h>
+ 
+ struct mdio_gpio_info {
+ 	struct mdiobb_ctrl ctrl;
+-	int mdc, mdio;
++	int mdc, mdio, rst;
++	int rst_active_low;
+ };
+ 
++static int mdio_gpio_reset(struct mii_bus *bus)
++{
++	struct mdiobb_ctrl *bb_ctrl = bus->priv;
++	struct mdio_gpio_info *mdio_info = container_of(bb_ctrl, struct mdio_gpio_info, ctrl);
++
++	gpio_direction_output(mdio_info->rst, mdio_info->rst_active_low);
++	msleep(50);
++	gpio_direction_output(mdio_info->rst, !mdio_info->rst_active_low);
++	msleep(50);
++
++	return 0;
++}
++
+ static void *mdio_gpio_of_get_data(struct platform_device *pdev)
+ {
+ 	struct device_node *np = pdev->dev.of_node;
+ 	struct mdio_gpio_platform_data *pdata;
++	enum of_gpio_flags flags;
+ 	int ret;
+ 
+ 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+@@ -57,6 +73,18 @@ static void *mdio_gpio_of_get_data(struct platform_device *pdev)
+ 		return NULL;
+ 	pdata->mdio = ret;
+ 
++	pdata->rst = of_get_named_gpio_flags(np->child, "rst-gpios", 0, &flags);
++	if (gpio_is_valid(pdata->rst)) {
++		ret = devm_gpio_request(&pdev->dev,
++				pdata->rst, "phy reset");
++		if(ret < 0)
++			dev_err(&pdev->dev, "Failed to request rst-gpios!\n");
++		else {
++			pdata->rst_active_low = flags & OF_GPIO_ACTIVE_LOW;
++			pdata->reset = mdio_gpio_reset;
++		}
++	}
++
+ 	return pdata;
+ }
+ 
+@@ -119,6 +147,8 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
+ 	bitbang->ctrl.reset = pdata->reset;
+ 	bitbang->mdc = pdata->mdc;
+ 	bitbang->mdio = pdata->mdio;
++	bitbang->rst = pdata->rst;
++	bitbang->rst_active_low = pdata->rst_active_low;
+ 
+ 	new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+ 	if (!new_bus)
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 299d3555..48f8d581 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -588,7 +588,7 @@ int phy_start_interrupts(struct phy_device *phydev)
+ 
+ 	atomic_set(&phydev->irq_disable, 0);
+ 	if (request_irq(phydev->irq, phy_interrupt,
+-				IRQF_SHARED,
++				IRQF_SHARED | phydev->irq_flags,
+ 				"phy_interrupt",
+ 				phydev) < 0) {
+ 		pr_warn("%s: Can't get IRQ %d (PHY)\n",
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 3657b4a2..2b764d61 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -917,6 +917,9 @@ static int genphy_config_init(struct phy_device *phydev)
+ 	int val;
+ 	u32 features;
+ 
++	/* Make sure PHY is ON */
++	genphy_resume(phydev);
++
+ 	/* For now, I'll claim that the generic driver supports
+ 	 * all possible port types */
+ 	features = (SUPPORTED_TP | SUPPORTED_MII
+@@ -958,6 +961,7 @@ static int genphy_config_init(struct phy_device *phydev)
+ 
+ 	return 0;
+ }
++
+ int genphy_suspend(struct phy_device *phydev)
+ {
+ 	int value;
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 8f669243..ff7a6f6f 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -221,6 +221,12 @@ config PINCTRL_S3C64XX
+ 	depends on ARCH_S3C64XX
+ 	select PINCTRL_SAMSUNG
+ 
++config PINCTRL_AMB
++	bool
++	depends on PLAT_AMBARELLA
++	select PINMUX
++	select PINCONF
++
+ source "drivers/pinctrl/mvebu/Kconfig"
+ source "drivers/pinctrl/sh-pfc/Kconfig"
+ source "drivers/pinctrl/spear/Kconfig"
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index 9bdaeb87..cbbe9aaf 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -45,9 +45,11 @@ obj-$(CONFIG_PINCTRL_EXYNOS5440)	+= pinctrl-exynos5440.o
+ obj-$(CONFIG_PINCTRL_S3C64XX)	+= pinctrl-s3c64xx.o
+ obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o
+ obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o
++obj-$(CONFIG_PINCTRL_AMB)	+= pinctrl-ambarella.o
+ 
+ obj-$(CONFIG_PLAT_ORION)        += mvebu/
+ obj-$(CONFIG_ARCH_SHMOBILE)	+= sh-pfc/
+ obj-$(CONFIG_SUPERH)		+= sh-pfc/
+ obj-$(CONFIG_PLAT_SPEAR)	+= spear/
+ obj-$(CONFIG_ARCH_VT8500)	+= vt8500/
++
+diff --git a/drivers/pinctrl/pinctrl-ambarella.c b/drivers/pinctrl/pinctrl-ambarella.c
+new file mode 100644
+index 00000000..28c33a88
+--- /dev/null
++++ b/drivers/pinctrl/pinctrl-ambarella.c
+@@ -0,0 +1,856 @@
++/*
++ * drivers/pinctrl/ambarella/pinctrl-amb.c
++ *
++ * History:
++ *	2013/12/18 - [Cao Rongrong] created file
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/syscore_ops.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/pinconf.h>
++#include <plat/rct.h>
++#include <plat/pinctrl.h>
++#include "core.h"
++
++#define PIN_NAME_LENGTH		8
++#define SUFFIX_LENGTH		4
++
++#define MUXIDS_TO_PINID(m)	((m) & 0xfff)
++#define MUXIDS_TO_ALT(m)	(((m) >> 12) & 0xf)
++
++#define CONFIDS_TO_PINID(c)	((c) & 0xfff)
++#define CONFIDS_TO_CONF(c)	(((c) >> 16) & 0xffff)
++
++/*
++ * bit1~0: 00: pull down, 01: pull up, 1x: clear pull up/down
++ * bit2:   reserved
++ * bit3:   1: config pull up/down, 0: leave pull up/down as default value
++ * bit5~4: drive strength value
++ * bit6:   reserved
++ * bit7:   1: config drive strength, 0: leave drive strength as default value
++ */
++#define CONF_TO_PULL_VAL(c)	(((c) >> 0) & 0x1)
++#define CONF_TO_PULL_CLR(c)	(((c) >> 1) & 0x1)
++#define CFG_PULL_PRESENT(c)	(((c) >> 3) & 0x1)
++#define CONF_TO_DS_VAL(c)	(((c) >> 4) & 0x3)
++#define CFG_DS_PRESENT(c)	(((c) >> 7) & 0x1)
++
++struct ambpin_group {
++	const char		*name;
++	unsigned int		*pins;
++	unsigned		num_pins;
++	u8			*alt;
++	unsigned int		*conf_pins;
++	unsigned		num_conf_pins;
++	unsigned long		*conf;
++};
++
++struct ambpin_function {
++	const char		*name;
++	const char		**groups;
++	unsigned		num_groups;
++	unsigned long		function;
++};
++
++struct amb_pinctrl_soc_data {
++	struct device			*dev;
++	struct pinctrl_dev		*pctl;
++	void __iomem			*regbase[GPIO_INSTANCES];
++	void __iomem			*iomux_base;
++	unsigned long			used[BITS_TO_LONGS(AMBGPIO_SIZE)];
++
++	struct ambpin_function		*functions;
++	unsigned int			nr_functions;
++	struct ambpin_group		*groups;
++	unsigned int			nr_groups;
++};
++
++void __iomem *amb_iomux_base = NULL;
++
++/* check if the selector is a valid pin group selector */
++static int amb_get_group_count(struct pinctrl_dev *pctldev)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	return soc->nr_groups;
++}
++
++/* return the name of the group selected by the group selector */
++static const char *amb_get_group_name(struct pinctrl_dev *pctldev,
++						unsigned selector)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	return soc->groups[selector].name;
++}
++
++/* return the pin numbers associated with the specified group */
++static int amb_get_group_pins(struct pinctrl_dev *pctldev,
++		unsigned selector, const unsigned **pins, unsigned *num_pins)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	*pins = soc->groups[selector].pins;
++	*num_pins = soc->groups[selector].num_pins;
++	return 0;
++}
++
++static void amb_pin_dbg_show(struct pinctrl_dev *pctldev,
++			struct seq_file *s, unsigned pin)
++{
++	struct pin_desc *desc;
++
++	seq_printf(s, " %s", dev_name(pctldev->dev));
++
++	desc = pin_desc_get(pctldev, pin);
++	if (desc) {
++		seq_printf(s, " owner: %s%s%s%s",
++			desc->mux_owner ? desc->mux_owner : "",
++			desc->mux_owner && desc->gpio_owner ? " " : "",
++			desc->gpio_owner ? desc->gpio_owner : "",
++			!desc->mux_owner && !desc->gpio_owner ? "NULL" : "");
++	} else {
++		seq_printf(s, " not registered");
++	}
++}
++
++static int amb_dt_node_to_map(struct pinctrl_dev *pctldev,
++			struct device_node *np,
++			struct pinctrl_map **map, unsigned *num_maps)
++{
++	struct amb_pinctrl_soc_data *soc = pinctrl_dev_get_drvdata(pctldev);
++	struct ambpin_group *grp = NULL;
++	struct pinctrl_map *new_map;
++	char *grp_name = NULL;
++	int length = strlen(np->name) + SUFFIX_LENGTH;
++	u32 i, reg, new_num;
++
++	if (of_property_read_u32(np, "reg", &reg))
++		return -EINVAL;
++
++	/* Compose group name */
++	grp_name = devm_kzalloc(soc->dev, length, GFP_KERNEL);
++	if (!grp_name)
++		return -ENOMEM;
++
++	snprintf(grp_name, length, "%s.%d", np->name, reg);
++
++	/* find the group of this node by name */
++	for (i = 0; i < soc->nr_groups; i++) {
++		if (!strcmp(soc->groups[i].name, grp_name)) {
++			grp = &soc->groups[i];
++			break;
++		}
++	}
++	if (grp == NULL){
++		dev_err(soc->dev, "unable to find group for node %s\n", np->name);
++		return -EINVAL;
++	}
++
++	new_num = !!grp->num_pins + grp->num_conf_pins;
++	new_map = devm_kzalloc(soc->dev,
++				sizeof(struct pinctrl_map) * new_num, GFP_KERNEL);
++	if (!new_map)
++		return -ENOMEM;
++
++	*map = new_map;
++	*num_maps = new_num;
++
++	/* create mux map */
++	if (grp->num_pins) {
++		new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
++		new_map[0].data.mux.group = grp_name;
++		new_map[0].data.mux.function = np->name;
++		new_map++;
++	}
++
++	/* create config map */
++	for (i = 0; i < grp->num_conf_pins; i++) {
++		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
++		new_map[i].data.configs.group_or_pin =
++				pin_get_name(pctldev, grp->conf_pins[i]);
++		new_map[i].data.configs.configs = &grp->conf[i];
++		new_map[i].data.configs.num_configs = 1;
++	}
++
++	return 0;
++}
++
++static void amb_dt_free_map(struct pinctrl_dev *pctldev,
++			struct pinctrl_map *map, unsigned num_maps)
++{
++}
++
++/* list of pinctrl callbacks for the pinctrl core */
++static const struct pinctrl_ops amb_pctrl_ops = {
++	.get_groups_count	= amb_get_group_count,
++	.get_group_name		= amb_get_group_name,
++	.get_group_pins		= amb_get_group_pins,
++	.pin_dbg_show		= amb_pin_dbg_show,
++	.dt_node_to_map		= amb_dt_node_to_map,
++	.dt_free_map		= amb_dt_free_map,
++};
++
++/* check if the selector is a valid pin function selector */
++static int amb_pinmux_request(struct pinctrl_dev *pctldev, unsigned pin)
++{
++	struct amb_pinctrl_soc_data *soc;
++	int rval = 0;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++
++	if (test_and_set_bit(pin, soc->used))
++		rval = -EBUSY;
++
++	return rval;
++}
++
++/* check if the selector is a valid pin function selector */
++static int amb_pinmux_free(struct pinctrl_dev *pctldev, unsigned pin)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	clear_bit(pin, soc->used);
++
++	return 0;
++}
++
++/* check if the selector is a valid pin function selector */
++static int amb_pinmux_get_fcount(struct pinctrl_dev *pctldev)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	return soc->nr_functions;
++}
++
++/* return the name of the pin function specified */
++static const char *amb_pinmux_get_fname(struct pinctrl_dev *pctldev,
++			unsigned selector)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	return soc->functions[selector].name;
++}
++
++/* return the groups associated for the specified function selector */
++static int amb_pinmux_get_groups(struct pinctrl_dev *pctldev,
++			unsigned selector, const char * const **groups,
++			unsigned * const num_groups)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	*groups = soc->functions[selector].groups;
++	*num_groups = soc->functions[selector].num_groups;
++	return 0;
++}
++
++static void amb_pinmux_set_altfunc(struct amb_pinctrl_soc_data *soc,
++			u32 bank, u32 offset, enum amb_pin_altfunc altfunc)
++{
++	void __iomem *regbase = soc->regbase[bank];
++	void __iomem *iomux_reg;
++	u32 i, data;
++
++	if (altfunc == AMB_ALTFUNC_GPIO) {
++		amba_clrbitsl(regbase + GPIO_AFSEL_OFFSET, 0x1 << offset);
++		amba_clrbitsl(regbase + GPIO_DIR_OFFSET, 0x1 << offset);
++	} else {
++		amba_setbitsl(regbase + GPIO_AFSEL_OFFSET, 0x1 << offset);
++		amba_clrbitsl(regbase + GPIO_MASK_OFFSET, 0x1 << offset);
++	}
++
++	if (soc->iomux_base) {
++		for (i = 0; i < 3; i++) {
++			iomux_reg = soc->iomux_base + IOMUX_REG_OFFSET(bank, i);
++			data = amba_readl(iomux_reg);
++			data &= (~(0x1 << offset));
++			data |= (((altfunc >> i) & 0x1) << offset);
++			amba_writel(iomux_reg, data);
++		}
++		iomux_reg = soc->iomux_base + IOMUX_CTRL_SET_OFFSET;
++		amba_writel(iomux_reg, 0x1);
++		amba_writel(iomux_reg, 0x0);
++	}
++}
++
++/* enable a specified pinmux by writing to registers */
++static int amb_pinmux_enable(struct pinctrl_dev *pctldev,
++			unsigned selector, unsigned group)
++{
++	struct amb_pinctrl_soc_data *soc;
++	const struct ambpin_group *grp;
++	u32 i, bank, offset;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	grp = &soc->groups[group];
++
++	for (i = 0; i < grp->num_pins; i++) {
++		bank = PINID_TO_BANK(grp->pins[i]);
++		offset = PINID_TO_OFFSET(grp->pins[i]);
++		amb_pinmux_set_altfunc(soc, bank, offset,  grp->alt[i]);
++	}
++
++	return 0;
++}
++
++/* disable a specified pinmux by writing to registers */
++static void amb_pinmux_disable(struct pinctrl_dev *pctldev,
++			unsigned selector, unsigned group)
++{
++	struct amb_pinctrl_soc_data *soc;
++	const struct ambpin_group *grp;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	grp = &soc->groups[group];
++
++	/* FIXME: poke out the mux, set the pin to some default state? */
++	dev_dbg(soc->dev,
++		"disable group %s, %u pins\n", grp->name, grp->num_pins);
++}
++
++static int amb_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
++			struct pinctrl_gpio_range *range, unsigned pin)
++{
++	struct amb_pinctrl_soc_data *soc;
++	u32 bank, offset;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++
++	if (!range || !range->gc) {
++		dev_err(soc->dev, "invalid range: %p\n", range);
++		return -EINVAL;
++	}
++
++	if (test_and_set_bit(pin, soc->used))
++		return -EBUSY;
++
++	bank = PINID_TO_BANK(pin);
++	offset = PINID_TO_OFFSET(pin);
++	amb_pinmux_set_altfunc(soc, bank, offset, AMB_ALTFUNC_GPIO);
++
++	return 0;
++}
++
++static void amb_pinmux_gpio_disable_free(struct pinctrl_dev *pctldev,
++			struct pinctrl_gpio_range *range,
++			unsigned pin)
++{
++	struct amb_pinctrl_soc_data *soc;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	dev_dbg(soc->dev, "disable pin %u as GPIO\n", pin);
++	/* Set the pin to some default state, GPIO is usually default */
++
++	clear_bit(pin, soc->used);
++}
++
++/*
++ * The calls to gpio_direction_output() and gpio_direction_input()
++ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
++ * function called from the gpiolib interface).
++ */
++static int amb_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
++			struct pinctrl_gpio_range *range,
++			unsigned pin, bool input)
++{
++	struct amb_pinctrl_soc_data *soc;
++	void __iomem *regbase;
++	u32 bank, offset, mask;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++
++	bank = PINID_TO_BANK(pin);
++	offset = PINID_TO_OFFSET(pin);
++	regbase = soc->regbase[bank];
++	mask = (0x1 << offset);
++
++	amba_clrbitsl(regbase + GPIO_AFSEL_OFFSET, mask);
++	if (input)
++		amba_clrbitsl(regbase + GPIO_DIR_OFFSET, mask);
++	else
++		amba_setbitsl(regbase + GPIO_DIR_OFFSET, mask);
++
++	return 0;
++}
++
++/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
++static const struct pinmux_ops amb_pinmux_ops = {
++	.request		= amb_pinmux_request,
++	.free			= amb_pinmux_free,
++	.get_functions_count	= amb_pinmux_get_fcount,
++	.get_function_name	= amb_pinmux_get_fname,
++	.get_function_groups	= amb_pinmux_get_groups,
++	.enable			= amb_pinmux_enable,
++	.disable		= amb_pinmux_disable,
++	.gpio_request_enable	= amb_pinmux_gpio_request_enable,
++	.gpio_disable_free	= amb_pinmux_gpio_disable_free,
++	.gpio_set_direction	= amb_pinmux_gpio_set_direction,
++};
++
++/* set the pin config settings for a specified pin */
++static int amb_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
++			unsigned long config)
++{
++	struct amb_pinctrl_soc_data *soc;
++	u32 bank, offset, reg, val;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	bank = PINID_TO_BANK(pin);
++	offset = PINID_TO_OFFSET(pin);
++
++	if (CFG_PULL_PRESENT(config)) {
++		reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(bank));
++		amba_clrbitsl(reg, 1 << offset);
++		amba_setbitsl(reg, CONF_TO_PULL_VAL(config) << offset);
++
++		reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(bank));
++		if (CONF_TO_PULL_CLR(config))
++			amba_clrbitsl(reg, 1 << offset);
++		else
++			amba_setbitsl(reg, 1 << offset);
++	}
++
++	if (CFG_DS_PRESENT(config)) {
++		amba_clrbitsl(RCT_REG(GPIO_DS0_OFFSET(bank)), 1 << offset);
++		amba_clrbitsl(RCT_REG(GPIO_DS1_OFFSET(bank)), 1 << offset);
++		/* set bit1 of DS value to DS0 reg, and set bit0 of DS value to DS1 reg,
++		 * because bit[1:0] = 00 is 2mA, 10 is 4mA, 01 is 8mA, 11 is 12mA */
++		val = (CONF_TO_DS_VAL(config) >> 1) & 0x1;
++		amba_setbitsl(RCT_REG(GPIO_DS0_OFFSET(bank)), val << offset);
++		val = CONF_TO_DS_VAL(config) & 0x1;
++		amba_setbitsl(RCT_REG(GPIO_DS1_OFFSET(bank)), val << offset);
++	}
++
++	return 0;
++}
++
++/* get the pin config settings for a specified pin */
++static int amb_pinconf_get(struct pinctrl_dev *pctldev,
++			unsigned int pin, unsigned long *config)
++{
++	dev_WARN_ONCE(pctldev->dev, true, "NOT Implemented.\n");
++	return -ENOTSUPP;
++}
++
++static void amb_pinconf_dbg_show(struct pinctrl_dev *pctldev,
++			struct seq_file *s, unsigned pin)
++{
++	struct amb_pinctrl_soc_data *soc;
++	u32 bank, offset, reg;
++	u32 pull_en, pull_dir, drv_strength;
++
++	soc = pinctrl_dev_get_drvdata(pctldev);
++	bank = PINID_TO_BANK(pin);
++	offset = PINID_TO_OFFSET(pin);
++
++	reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(bank));
++	pull_en = (amba_readl(reg) >> offset) & 0x1;
++
++	reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(bank));
++	pull_dir = (amba_readl(reg) >> offset) & 0x1;
++
++	seq_printf(s, " pull: %s, ", pull_en ? pull_dir ? "up" : "down" : "disable");
++
++	reg = RCT_REG(GPIO_DS0_OFFSET(bank));
++	drv_strength = ((amba_readl(reg) >> offset) & 0x1) << 1;
++	reg = RCT_REG(GPIO_DS1_OFFSET(bank));
++	drv_strength |= (amba_readl(reg) >> offset) & 0x1;
++
++	seq_printf(s, "drive-strength: %s",
++		drv_strength == 3 ? "12mA" : drv_strength == 2 ? "8mA" :
++		drv_strength == 1 ? "4mA" : "2mA");
++}
++
++/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
++static const struct pinconf_ops amb_pinconf_ops = {
++	.pin_config_get		= amb_pinconf_get,
++	.pin_config_set		= amb_pinconf_set,
++	.pin_config_dbg_show	= amb_pinconf_dbg_show,
++};
++
++static struct pinctrl_desc amb_pinctrl_desc = {
++	.pctlops = &amb_pctrl_ops,
++	.pmxops = &amb_pinmux_ops,
++	.confops = &amb_pinconf_ops,
++	.owner = THIS_MODULE,
++};
++
++static int amb_pinctrl_parse_group(struct amb_pinctrl_soc_data *soc,
++			struct device_node *np, int idx, const char **out_name)
++{
++	struct ambpin_group *grp = &soc->groups[idx];
++	struct property *prop;
++	const char *prop_name;
++	char *grp_name;
++	int length = strlen(np->name) + SUFFIX_LENGTH;
++	u32 reg, i;
++
++	grp_name = devm_kzalloc(soc->dev, length, GFP_KERNEL);
++	if (!grp_name)
++		return -ENOMEM;
++
++	if (of_property_read_u32(np, "reg", &reg))
++		return -EINVAL;
++
++	snprintf(grp_name, length, "%s.%d", np->name, reg);
++
++	grp->name = grp_name;
++
++	prop_name = "amb,pinmux-ids";
++	prop = of_find_property(np, prop_name, &length);
++	if (prop) {
++		grp->num_pins = length / sizeof(u32);
++
++		grp->pins = devm_kzalloc(soc->dev,
++					grp->num_pins * sizeof(u32), GFP_KERNEL);
++		if (!grp->pins)
++			return -ENOMEM;
++
++		grp->alt = devm_kzalloc(soc->dev,
++					grp->num_pins * sizeof(u8), GFP_KERNEL);
++		if (!grp->alt)
++			return -ENOMEM;
++
++		of_property_read_u32_array(np, prop_name, grp->pins, grp->num_pins);
++
++		for (i = 0; i < grp->num_pins; i++) {
++			grp->alt[i] = MUXIDS_TO_ALT(grp->pins[i]);
++			grp->pins[i] = MUXIDS_TO_PINID(grp->pins[i]);
++		}
++	}
++
++	/* parse pinconf */
++	prop_name = "amb,pinconf-ids";
++	prop = of_find_property(np, prop_name, &length);
++	if (prop) {
++		grp->num_conf_pins = length / sizeof(u32);
++
++		grp->conf_pins = devm_kzalloc(soc->dev,
++					grp->num_conf_pins * sizeof(u32), GFP_KERNEL);
++		if (!grp->conf_pins)
++			return -ENOMEM;
++
++		grp->conf = devm_kzalloc(soc->dev,
++				grp->num_conf_pins * sizeof(unsigned long), GFP_KERNEL);
++		if (!grp->conf)
++			return -ENOMEM;
++
++		of_property_read_u32_array(np, prop_name, grp->conf_pins, grp->num_conf_pins);
++
++		for (i = 0; i < grp->num_conf_pins; i++) {
++			grp->conf[i] = CONFIDS_TO_CONF(grp->conf_pins[i]);
++			grp->conf_pins[i] = CONFIDS_TO_PINID(grp->conf_pins[i]);
++		}
++	}
++
++	if (out_name)
++		*out_name = grp->name;
++
++	return 0;
++}
++
++static int amb_pinctrl_parse_dt(struct amb_pinctrl_soc_data *soc)
++{
++	struct device_node *np = soc->dev->of_node;
++	struct device_node *child;
++	struct ambpin_function *f;
++	const char *gpio_compat = "ambarella,gpio";
++	const char *fn;
++	int i = 0, idxf = 0, idxg = 0;
++	int ret;
++
++	child = of_get_next_child(np, NULL);
++	if (!child) {
++		dev_err(soc->dev, "no group is defined\n");
++		return -ENOENT;
++	}
++
++	/* Count total functions and groups */
++	fn = "";
++	for_each_child_of_node(np, child) {
++		if (of_device_is_compatible(child, gpio_compat))
++			continue;
++		soc->nr_groups++;
++		if (strcmp(fn, child->name)) {
++			fn = child->name;
++			soc->nr_functions++;
++		}
++	}
++
++	soc->functions = devm_kzalloc(soc->dev, soc->nr_functions *
++				sizeof(struct ambpin_function), GFP_KERNEL);
++	if (!soc->functions)
++		return -ENOMEM;
++
++	soc->groups = devm_kzalloc(soc->dev, soc->nr_groups *
++				sizeof(struct ambpin_group), GFP_KERNEL);
++	if (!soc->groups)
++		return -ENOMEM;
++
++	/* Count groups for each function */
++	fn = "";
++	f = &soc->functions[idxf];
++	for_each_child_of_node(np, child) {
++		if (of_device_is_compatible(child, gpio_compat))
++			continue;
++		if (strcmp(fn, child->name)) {
++			f = &soc->functions[idxf++];
++			f->name = fn = child->name;
++		}
++		f->num_groups++;
++	};
++
++	/* Get groups for each function */
++	fn = "";
++	idxf = 0;
++	for_each_child_of_node(np, child) {
++		if (of_device_is_compatible(child, gpio_compat))
++			continue;
++
++		if (strcmp(fn, child->name)) {
++			f = &soc->functions[idxf++];
++			f->groups = devm_kzalloc(soc->dev,
++					f->num_groups * sizeof(*f->groups),
++					GFP_KERNEL);
++			if (!f->groups)
++				return -ENOMEM;
++			fn = child->name;
++			i = 0;
++		}
++
++		ret = amb_pinctrl_parse_group(soc, child,
++					idxg++, &f->groups[i++]);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++/* register the pinctrl interface with the pinctrl subsystem */
++static int amb_pinctrl_register(struct amb_pinctrl_soc_data *soc)
++{
++	struct pinctrl_pin_desc *pindesc;
++	char *pin_names;
++	int pin, rval;
++
++	/* dynamically populate the pin number and pin name for pindesc */
++	pindesc = devm_kzalloc(soc->dev,
++			sizeof(*pindesc) * AMBGPIO_SIZE, GFP_KERNEL);
++	if (!pindesc) {
++		dev_err(soc->dev, "No memory for pin desc\n");
++		return -ENOMEM;
++	}
++
++	pin_names = devm_kzalloc(soc->dev,
++			PIN_NAME_LENGTH * AMBGPIO_SIZE, GFP_KERNEL);
++	if (!pin_names) {
++		dev_err(soc->dev, "No memory for pin names\n");
++		return -ENOMEM;
++	}
++
++	for (pin = 0; pin < AMBGPIO_SIZE; pin++) {
++		pindesc[pin].number = pin;
++		sprintf(pin_names, "io%d", pin);
++		pindesc[pin].name = pin_names;
++		pin_names += PIN_NAME_LENGTH;
++	}
++
++	amb_pinctrl_desc.name = dev_name(soc->dev);
++	amb_pinctrl_desc.pins = pindesc;
++	amb_pinctrl_desc.npins = AMBGPIO_SIZE;
++
++	rval = amb_pinctrl_parse_dt(soc);
++	if (rval)
++		return rval;
++
++	soc->pctl = pinctrl_register(&amb_pinctrl_desc, soc->dev, soc);
++	if (!soc->pctl) {
++		dev_err(soc->dev, "could not register pinctrl driver\n");
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int amb_pinctrl_probe(struct platform_device *pdev)
++{
++	struct amb_pinctrl_soc_data *soc;
++	struct resource *res;
++	int i, rval;
++
++	soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
++	if (!soc) {
++		dev_err(&pdev->dev, "failed to allocate memory for private data\n");
++		return -ENOMEM;
++	}
++	soc->dev = &pdev->dev;
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
++		if (res == NULL) {
++			dev_err(&pdev->dev, "no mem resource for gpio[%d]!\n", i);
++			return -ENXIO;
++		}
++
++		soc->regbase[i] = devm_ioremap(&pdev->dev,
++						res->start, resource_size(res));
++		if (soc->regbase[i] == 0) {
++			dev_err(&pdev->dev, "devm_ioremap() failed\n");
++			return -ENOMEM;
++		}
++	}
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iomux");
++	if (res != NULL) {
++		soc->iomux_base = devm_ioremap(&pdev->dev,
++						res->start, resource_size(res));
++		if (soc->iomux_base == 0) {
++			dev_err(&pdev->dev, "devm_ioremap() failed\n");
++			return -ENOMEM;
++		}
++
++		amb_iomux_base = soc->iomux_base;
++	}
++
++	rval = amb_pinctrl_register(soc);
++	if (rval)
++		return rval;
++
++	platform_set_drvdata(pdev, soc);
++	dev_info(&pdev->dev, "Ambarella pinctrl driver registered\n");
++
++	return 0;
++}
++
++#if defined(CONFIG_PM)
++
++static u32 amb_iomux_pm_reg[GPIO_INSTANCES][3];
++static u32 amb_pull_pm_reg[2][GPIO_INSTANCES];
++static u32 amb_ds_pm_reg[GPIO_INSTANCES][2];
++
++static int amb_pinctrl_suspend(void)
++{
++	u32 i, j, reg;
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(i));
++		amb_pull_pm_reg[0][i] = amba_readl(reg);
++		reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(i));
++		amb_pull_pm_reg[1][i] = amba_readl(reg);
++	}
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		amb_ds_pm_reg[i][0] = amba_readl(RCT_REG(GPIO_DS0_OFFSET(i)));
++		amb_ds_pm_reg[i][1] = amba_readl(RCT_REG(GPIO_DS1_OFFSET(i)));
++	}
++
++	if (amb_iomux_base == NULL)
++		return 0;
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		for (j = 0; j < 3; j++) {
++			reg = (u32)amb_iomux_base + IOMUX_REG_OFFSET(i, j);
++			amb_iomux_pm_reg[i][j] = amba_readl(reg);
++		}
++	}
++
++	return 0;
++}
++
++static void amb_pinctrl_resume(void)
++{
++	u32 i, j, reg;
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(i));
++		amba_writel(reg, amb_pull_pm_reg[0][i]);
++		reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(i));
++		amba_writel(reg, amb_pull_pm_reg[1][i]);
++	}
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		amba_writel(RCT_REG(GPIO_DS0_OFFSET(i)), amb_ds_pm_reg[i][0]);
++		amba_writel(RCT_REG(GPIO_DS1_OFFSET(i)), amb_ds_pm_reg[i][1]);
++	}
++
++	if (amb_iomux_base == NULL)
++		return;
++
++	for (i = 0; i < GPIO_INSTANCES; i++) {
++		for (j = 0; j < 3; j++) {
++			reg = (u32)amb_iomux_base + IOMUX_REG_OFFSET(i, j);
++			amba_writel(reg, amb_iomux_pm_reg[i][j]);
++		}
++	}
++
++	amba_writel(amb_iomux_base + IOMUX_CTRL_SET_OFFSET, 0x1);
++	amba_writel(amb_iomux_base + IOMUX_CTRL_SET_OFFSET, 0x0);
++}
++
++static struct syscore_ops amb_pinctrl_syscore_ops = {
++	.suspend	= amb_pinctrl_suspend,
++	.resume		= amb_pinctrl_resume,
++};
++
++#endif /* CONFIG_PM */
++
++static const struct of_device_id amb_pinctrl_dt_match[] = {
++	{ .compatible = "ambarella,pinctrl" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, amb_pinctrl_dt_match);
++
++static struct platform_driver amb_pinctrl_driver = {
++	.probe	= amb_pinctrl_probe,
++	.driver	= {
++		.name	= "ambarella-pinctrl",
++		.owner	= THIS_MODULE,
++		.of_match_table = of_match_ptr(amb_pinctrl_dt_match),
++	},
++};
++
++static int __init amb_pinctrl_drv_register(void)
++{
++#ifdef CONFIG_PM
++	register_syscore_ops(&amb_pinctrl_syscore_ops);
++#endif
++	return platform_driver_register(&amb_pinctrl_driver);
++}
++postcore_initcall(amb_pinctrl_drv_register);
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella SoC pinctrl driver");
++MODULE_LICENSE("GPL v2");
++
++
+diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
+index 3ccadf63..7b1ec8b0 100644
+--- a/drivers/power/wm831x_power.c
++++ b/drivers/power/wm831x_power.c
+@@ -18,6 +18,7 @@
+ #include <linux/mfd/wm831x/auxadc.h>
+ #include <linux/mfd/wm831x/pmu.h>
+ #include <linux/mfd/wm831x/pdata.h>
++#include <linux/mfd/wm831x/irq.h>
+ 
+ struct wm831x_power {
+ 	struct wm831x *wm831x;
+@@ -649,8 +650,66 @@ static int wm831x_power_remove(struct platform_device *pdev)
+ 	power_supply_unregister(&wm831x_power->wall);
+ 	power_supply_unregister(&wm831x_power->usb);
+ 	kfree(wm831x_power);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int wm831x_power_suppend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	int irq, i;
++
++	for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
++		irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
++		disable_irq(irq);
++	}
++
++	irq = platform_get_irq_byname(pdev, "PWR SRC");
++	disable_irq(irq);
++
++	irq = platform_get_irq_byname(pdev, "SYSLO");
++	disable_irq(irq);
++
++	return 0;
++}
++
++static int wm831x_power_resume(struct platform_device *pdev)
++{
++	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
++	struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
++	int irq, i;
++
++	for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
++		irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
++		enable_irq(irq);
++	}
++
++	irq = platform_get_irq_byname(pdev, "PWR SRC");
++	enable_irq(irq);
++
++	irq = platform_get_irq_byname(pdev, "SYSLO");
++	enable_irq(irq);
++
++	if (wm831x_pdata && wm831x_pdata->irq_cmos)
++		i = 0;
++	else
++		i = WM831X_IRQ_OD;
++
++	wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
++			WM831X_IRQ_OD, i);
++
++	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
++
++	for(i=0;i<ARRAY_SIZE(wm831x->irq_masks_cur);i++){
++		wm831x_reg_write(wm831x,
++				 WM831X_INTERRUPT_STATUS_1_MASK + i,
++				 wm831x->irq_masks_cache[i]);
++	}
++
+ 	return 0;
+ }
++#endif
+ 
+ static struct platform_driver wm831x_power_driver = {
+ 	.probe = wm831x_power_probe,
+@@ -658,6 +717,10 @@ static struct platform_driver wm831x_power_driver = {
+ 	.driver = {
+ 		.name = "wm831x-power",
+ 	},
++#ifdef CONFIG_PM
++	.suspend = wm831x_power_suppend,
++	.resume = wm831x_power_resume,
++#endif
+ };
+ 
+ module_platform_driver(wm831x_power_driver);
+diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
+index 115b6445..24a11249 100644
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -28,6 +28,15 @@ menuconfig PWM
+ 
+ if PWM
+ 
++config PWM_AMBARELLA
++	tristate "Ambarella PWM support"
++	depends on ARCH_AMBARELLA && OF
++	help
++	  Generic PWM framework driver for Ambarella chips.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called pwm-ambarella.
++
+ config PWM_AB8500
+ 	tristate "AB8500 PWM support"
+ 	depends on AB8500_CORE && ARCH_U8500
+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
+index 94ba21e2..db8a9978 100644
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -1,4 +1,5 @@
+ obj-$(CONFIG_PWM)		+= core.o
++obj-$(CONFIG_PWM_AMBARELLA)	+= pwm-ambarella.o
+ obj-$(CONFIG_PWM_AB8500)	+= pwm-ab8500.o
+ obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
+ obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
+diff --git a/drivers/pwm/pwm-ambarella.c b/drivers/pwm/pwm-ambarella.c
+new file mode 100644
+index 00000000..d5995bf3
+--- /dev/null
++++ b/drivers/pwm/pwm-ambarella.c
+@@ -0,0 +1,270 @@
++/*
++ * drivers/pwm/pwm-ambarella.c
++ *
++ * History:
++ *	2014/03/19 - [Cao Rongrong] Created
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/slab.h>
++#include <plat/pwm.h>
++
++#define PWM_DEFAULT_FREQUENCY		2200000
++
++struct ambarella_pwm_chip {
++	struct pwm_chip chip;
++	void __iomem *base;
++	void __iomem *base2; /* for the individual pwm controller if existed */
++	struct clk *clk;
++	enum pwm_polarity polarity[PWM_INSTANCES];
++};
++
++#define to_ambarella_pwm_chip(_chip) container_of(_chip, struct ambarella_pwm_chip, chip)
++
++static u32 ambpwm_enable_offset[] = {
++	PWM_B0_ENABLE_OFFSET,
++	PWM_B1_ENABLE_OFFSET,
++	PWM_C0_ENABLE_OFFSET,
++	PWM_C1_ENABLE_OFFSET,
++	PWM_ENABLE_OFFSET,
++};
++
++static u32 ambpwm_divider_offset[] = {
++	PWM_B0_ENABLE_OFFSET,
++	PWM_B1_ENABLE_OFFSET,
++	PWM_C0_ENABLE_OFFSET,
++	PWM_C1_ENABLE_OFFSET,
++	PWM_MODE_OFFSET,
++};
++
++static u32 ambpwm_data_offset[] = {
++	PWM_B0_DATA1_OFFSET,
++	PWM_B1_DATA1_OFFSET,
++	PWM_C0_DATA1_OFFSET,
++	PWM_C1_DATA1_OFFSET,
++	PWM_CONTROL_OFFSET,
++};
++
++static bool ambpwm_is_chief[] = {true, false, true, false, false};
++
++static int ambarella_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
++			int duty_ns, int period_ns)
++{
++	struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
++	void __iomem *base;
++	void __iomem *reg;
++	u32 tick_bits, clock, total, on, off, div;
++
++	/* we arrange the id of the individual pwm to the last one */
++	if (ambpwm->base2 && pwm->hwpwm == PWM_INSTANCES - 1) {
++		base = ambpwm->base2;
++		tick_bits = PWM_PWM_TICKS_MAX_BITS;
++	} else {
++		base = ambpwm->base;
++		tick_bits = PWM_ST_TICKS_MAX_BITS;
++	}
++
++	reg = base + ambpwm_enable_offset[pwm->hwpwm];
++	if (ambpwm_is_chief[pwm->hwpwm])
++		amba_setbitsl(reg, PWM_CLK_SRC_BIT);
++	else
++		amba_clrbitsl(reg, PWM_INV_EN_BIT);
++
++	clock = (clk_get_rate(clk_get(NULL, "gclk_pwm")) + 50000) / 100000;
++	total = (clock * period_ns + 5000) / 10000;
++	div = total >> tick_bits;
++	clock /= (div + 1);
++	reg = base + ambpwm_divider_offset[pwm->hwpwm];
++	amba_clrbitsl(reg, PWM_DIVIDER_MASK);
++	amba_setbitsl(reg, div << 1);
++
++	total = (clock * period_ns + 5000) / 10000;
++	on = (clock * duty_ns + 5000) / 10000;
++	off = total - on;
++	if (on == 0)
++		on = 1;
++	if (off == 0)
++		off = 1;
++
++	reg = base + ambpwm_data_offset[pwm->hwpwm];
++	if (ambpwm->polarity[pwm->hwpwm] == PWM_POLARITY_NORMAL)
++		amba_writel(reg, (on - 1) << tick_bits | (off - 1));
++	else
++		amba_writel(reg, (off - 1) << tick_bits | (on - 1));
++
++	return 0;
++}
++
++static int ambarella_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++	struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
++	void __iomem *reg;
++
++	/* we arrange the id of the individual pwm to the last one */
++	if (ambpwm->base2 && pwm->hwpwm == PWM_INSTANCES - 1)
++		reg = ambpwm->base2 + ambpwm_enable_offset[pwm->hwpwm];
++	else
++		reg = ambpwm->base + ambpwm_enable_offset[pwm->hwpwm];
++
++	amba_setbitsl(reg, PWM_PWM_EN_BIT);
++
++	return 0;
++}
++
++static void ambarella_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++	struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
++	void __iomem *reg;
++
++	/* we arrange the id of the individual pwm to the last one */
++	if (ambpwm->base2 && pwm->hwpwm == PWM_INSTANCES - 1)
++		reg = ambpwm->base2 + ambpwm_enable_offset[pwm->hwpwm];
++	else
++		reg = ambpwm->base + ambpwm_enable_offset[pwm->hwpwm];
++
++	amba_clrbitsl(reg, PWM_PWM_EN_BIT);
++}
++
++static int ambarella_pwm_set_polarity(struct pwm_chip *chip,
++			struct pwm_device *pwm,	enum pwm_polarity polarity)
++{
++	struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
++
++	ambpwm->polarity[pwm->hwpwm] = polarity;
++
++	return 0;
++}
++
++static const struct pwm_ops ambarella_pwm_ops = {
++	.config		= ambarella_pwm_config,
++	.enable		= ambarella_pwm_enable,
++	.disable	= ambarella_pwm_disable,
++	.set_polarity	= ambarella_pwm_set_polarity,
++	.owner		= THIS_MODULE,
++};
++
++static int ambarella_pwm_probe(struct platform_device *pdev)
++{
++	struct ambarella_pwm_chip *ambpwm;
++	struct resource *res;
++	int ret;
++
++	BUG_ON(ARRAY_SIZE(ambpwm_enable_offset) < PWM_INSTANCES);
++
++	ambpwm = devm_kzalloc(&pdev->dev, sizeof(*ambpwm), GFP_KERNEL);
++	if (!ambpwm)
++		return -ENOMEM;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (res == NULL)
++		return -ENXIO;
++
++	ambpwm->base = devm_ioremap(&pdev->dev,
++					res->start, resource_size(res));
++	if (IS_ERR(ambpwm->base))
++		return PTR_ERR(ambpwm->base);
++
++	ambpwm->base2 = NULL;
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++	if (res != NULL) {
++		ambpwm->base2 = devm_ioremap(&pdev->dev,
++					res->start, resource_size(res));
++		if (IS_ERR(ambpwm->base2))
++			return PTR_ERR(ambpwm->base);
++	}
++
++	ambpwm->clk = clk_get(NULL, "gclk_pwm");
++	if (IS_ERR(ambpwm->clk))
++		return PTR_ERR(ambpwm->clk);
++
++	clk_set_rate(clk_get(NULL, "gclk_pwm"), PWM_DEFAULT_FREQUENCY);
++
++	ambpwm->chip.dev = &pdev->dev;
++	ambpwm->chip.ops = &ambarella_pwm_ops;
++	ambpwm->chip.of_xlate = of_pwm_xlate_with_flags;
++	ambpwm->chip.of_pwm_n_cells = 3;
++	ambpwm->chip.base = -1;
++	ambpwm->chip.npwm = PWM_INSTANCES;
++
++	ret = pwmchip_add(&ambpwm->chip);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret);
++		return ret;
++	}
++
++	platform_set_drvdata(pdev, ambpwm);
++
++	return 0;
++}
++
++static int ambarella_pwm_remove(struct platform_device *pdev)
++{
++	struct ambarella_pwm_chip *ambpwm = platform_get_drvdata(pdev);
++
++	return pwmchip_remove(&ambpwm->chip);
++}
++
++#ifdef CONFIG_PM
++static int ambarella_pwm_suspend(struct platform_device *pdev,
++				 pm_message_t state)
++{
++	return 0;
++}
++
++static int ambarella_pwm_resume(struct platform_device *pdev)
++{
++	clk_set_rate(clk_get(NULL, "gclk_pwm"), PWM_DEFAULT_FREQUENCY);
++	return 0;
++}
++#endif
++
++static const struct of_device_id ambarella_pwm_dt_ids[] = {
++	{ .compatible = "ambarella,pwm", },
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ambarella_pwm_dt_ids);
++
++static struct platform_driver ambarella_pwm_driver = {
++	.driver = {
++		.name = "ambarella-pwm",
++		.of_match_table = of_match_ptr(ambarella_pwm_dt_ids),
++	},
++	.probe = ambarella_pwm_probe,
++	.remove = ambarella_pwm_remove,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_pwm_suspend,
++	.resume		= ambarella_pwm_resume,
++#endif
++};
++module_platform_driver(ambarella_pwm_driver);
++
++MODULE_ALIAS("platform:ambarella-pwm");
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella PWM Driver");
++MODULE_LICENSE("GPL v2");
++
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 70ccc201..1d7a283c 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -312,7 +312,49 @@ static ssize_t regulator_uV_show(struct device *dev,
+ 
+ 	return ret;
+ }
+-static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
++
++static ssize_t regulator_uV_store(struct device *dev,
++	struct device_attribute *attr,
++	const char *buf, size_t count)
++{
++	struct regulator_dev *rdev = dev_get_drvdata(dev);
++	ssize_t			status;
++	long		value;
++	int ret;
++	int min_uV, max_uV ;
++
++	mutex_lock(&rdev->mutex);
++	status = strict_strtol(buf, 0, &value);
++	if (status != 0)
++		goto out;
++
++	/* sanity check */
++	if (!rdev->desc->ops->set_voltage &&
++	    !rdev->desc->ops->set_voltage_sel)
++		goto out;
++
++	min_uV = max_uV = value;
++	/* constraints check */
++	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
++	if (ret < 0)
++		goto out;
++
++	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
++	if (ret < 0)
++		goto out;
++
++	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
++	if (ret < 0)
++		goto out;
++
++out:
++	mutex_unlock(&rdev->mutex);
++
++	return count;
++}
++
++
++static DEVICE_ATTR(microvolts, 0644, regulator_uV_show, regulator_uV_store);
+ 
+ static ssize_t regulator_uA_show(struct device *dev,
+ 				struct device_attribute *attr, char *buf)
+diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
+index 0af6898b..40964a3d 100644
+--- a/drivers/regulator/wm831x-dcdc.c
++++ b/drivers/regulator/wm831x-dcdc.c
+@@ -365,6 +365,16 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
+ 	return wm831x_dcdc_ilim[val];
+ }
+ 
++static int wm831x_buckv_set_suspend_enable(struct regulator_dev *rdev)
++{
++		return 0;
++}
++
++static int wm831x_buckv_set_suspend_disable(struct regulator_dev *rdev)
++{
++		return 0;
++}
++
+ static struct regulator_ops wm831x_buckv_ops = {
+ 	.set_voltage_sel = wm831x_buckv_set_voltage_sel,
+ 	.get_voltage_sel = wm831x_buckv_get_voltage_sel,
+@@ -381,6 +391,8 @@ static struct regulator_ops wm831x_buckv_ops = {
+ 	.get_mode = wm831x_dcdc_get_mode,
+ 	.set_mode = wm831x_dcdc_set_mode,
+ 	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
++	.set_suspend_enable = wm831x_buckv_set_suspend_enable,
++	.set_suspend_disable = wm831x_buckv_set_suspend_disable,
+ };
+ 
+ /*
+@@ -607,6 +619,16 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+ 	return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, sel);
+ }
+ 
++static int wm831x_buckp_set_suspend_enable(struct regulator_dev *rdev)
++{
++		return 0;
++}
++
++static int wm831x_buckp_set_suspend_disable(struct regulator_dev *rdev)
++{
++		return 0;
++}
++
+ static struct regulator_ops wm831x_buckp_ops = {
+ 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+ 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+@@ -621,6 +643,8 @@ static struct regulator_ops wm831x_buckp_ops = {
+ 	.get_mode = wm831x_dcdc_get_mode,
+ 	.set_mode = wm831x_dcdc_set_mode,
+ 	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
++	.set_suspend_enable = wm831x_buckp_set_suspend_enable,
++	.set_suspend_disable = wm831x_buckp_set_suspend_disable,
+ };
+ 
+ static int wm831x_buckp_probe(struct platform_device *pdev)
+diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
+index 1ec379a9..747daef0 100644
+--- a/drivers/regulator/wm831x-ldo.c
++++ b/drivers/regulator/wm831x-ldo.c
+@@ -228,6 +228,15 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
+ 	return REGULATOR_MODE_NORMAL;
+ }
+ 
++static int wm831x_gp_ldo_set_suspend_enable(struct regulator_dev *rdev)
++{
++	return 0;
++}
++
++static int wm831x_gp_ldo_set_suspend_disable(struct regulator_dev *rdev)
++{
++	return 0;
++}
+ 
+ static struct regulator_ops wm831x_gp_ldo_ops = {
+ 	.list_voltage = wm831x_gp_ldo_list_voltage,
+@@ -245,6 +254,8 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
+ 	.is_enabled = regulator_is_enabled_regmap,
+ 	.enable = regulator_enable_regmap,
+ 	.disable = regulator_disable_regmap,
++	.set_suspend_enable = wm831x_gp_ldo_set_suspend_enable,
++	.set_suspend_disable = wm831x_gp_ldo_set_suspend_disable,
+ };
+ 
+ static int wm831x_gp_ldo_probe(struct platform_device *pdev)
+@@ -487,6 +498,16 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
+ 		return regulator_mode_to_status(ret);
+ }
+ 
++static int wm831x_aldo_set_suspend_enable(struct regulator_dev *rdev)
++{
++	return 0;
++}
++
++static int wm831x_aldo_set_suspend_disable(struct regulator_dev *rdev)
++{
++	return 0;
++}
++
+ static struct regulator_ops wm831x_aldo_ops = {
+ 	.list_voltage = wm831x_aldo_list_voltage,
+ 	.map_voltage = wm831x_aldo_map_voltage,
+@@ -502,6 +523,8 @@ static struct regulator_ops wm831x_aldo_ops = {
+ 	.is_enabled = regulator_is_enabled_regmap,
+ 	.enable = regulator_enable_regmap,
+ 	.disable = regulator_disable_regmap,
++	.set_suspend_enable = wm831x_aldo_set_suspend_enable,
++	.set_suspend_disable = wm831x_aldo_set_suspend_disable,
+ };
+ 
+ static int wm831x_aldo_probe(struct platform_device *pdev)
+diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
+index d4d377c4..2c7a43a9 100644
+--- a/drivers/remoteproc/Kconfig
++++ b/drivers/remoteproc/Kconfig
+@@ -63,4 +63,5 @@ config DA8XX_REMOTEPROC
+ 	  It's safe to say n here if you're not interested in multimedia
+ 	  offloading.
+ 
++source "drivers/remoteproc/ambarella/Kconfig"
+ endmenu
+diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
+index ac2ff756..d6b8ce6a 100644
+--- a/drivers/remoteproc/Makefile
++++ b/drivers/remoteproc/Makefile
+@@ -7,6 +7,8 @@ remoteproc-y				:= remoteproc_core.o
+ remoteproc-y				+= remoteproc_debugfs.o
+ remoteproc-y				+= remoteproc_virtio.o
+ remoteproc-y				+= remoteproc_elf_loader.o
++remoteproc-y				+= remoteproc_dummy_loader.o
+ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
+ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
+ obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
++obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC)	+= ambarella/
+diff --git a/drivers/remoteproc/ambarella/Kconfig b/drivers/remoteproc/ambarella/Kconfig
+new file mode 100644
+index 00000000..87935c29
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/Kconfig
+@@ -0,0 +1,63 @@
++config RPROC_SUPPORT
++	bool
++	select REMOTEPROC
++        select RPMSG
++	default n
++
++config RPROC_CA9_A
++	tristate "Enable RPROC Host on CA9-A"
++	depends on MACH_HYACINTH_0
++	select RPROC_SUPPORT
++	help
++	  TBD:
++
++config RPROC_CA9_B
++	tristate "Enable RPROC Host on CA9-B"
++	depends on MACH_HYACINTH_1
++	select RPROC_SUPPORT
++	help
++	  TBD:
++
++config RPROC_S2
++    tristate "Enable RPROC Host on S2"
++    depends on MACH_GINKGO
++    select RPROC_SUPPORT
++    help
++      TBD:
++    default n
++
++config RPCLNT_SUPPORT
++	bool
++	select REMOTEPROC
++        select RPMSG
++	default n
++
++config RPCLNT_CA9_B
++	tristate "Enable RPROC Clnt on CA9-B"
++	depends on MACH_HYACINTH_1
++	select RPCLNT_SUPPORT
++	help
++	  TODO:
++
++config RPMSG_VRING_BASE
++	hex "Base address (Physical) used for the rpmsg & remoteproc"
++	depends on REMOTEPROC
++	default 0x5C000000 if MACH_HYACINTH_0 || MACH_HYACINTH_1
++	default 0x20000000 if MACH_GINKO
++
++config RPMSG_NUM_BUFS
++	int "Number of buffers for each RPMSG bus"
++	depends on REMOTEPROC
++	default 4096
++	help
++	  The buffers are partitioned into dedicated halves for TX
++	  and RX.
++
++config RPMSG_BUF_SIZE
++	int "Buffer size (in bytes) for each RPMSG message"
++	depends on REMOTEPROC
++	default 4096
++	help
++	  The first 16 bytes are used by the rpmsg header internally.
++	  So only N - 16 bytes is available for the message payload.
++
+diff --git a/drivers/remoteproc/ambarella/Makefile b/drivers/remoteproc/ambarella/Makefile
+new file mode 100644
+index 00000000..2cb554c8
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/Makefile
+@@ -0,0 +1,8 @@
++obj-$(CONFIG_RPROC_SUPPORT)	+= host/rproc_ambarella.o
++obj-$(CONFIG_RPROC_CA9_A)	+= host/rproc_ca9_a.o
++obj-$(CONFIG_RPROC_CA9_B)	+= host/rproc_ca9_b.o
++obj-$(CONFIG_RPROC_S2)		+= host/rproc_s2.o
++
++obj-$(CONFIG_RPCLNT_SUPPORT)	+= clnt/vq.o
++obj-$(CONFIG_RPCLNT_SUPPORT)	+= clnt/rpdev.o
++obj-$(CONFIG_RPCLNT_CA9_B)	+= clnt/rpclnt_ca9_b.o
+diff --git a/drivers/remoteproc/ambarella/clnt/rpclnt.h b/drivers/remoteproc/ambarella/clnt/rpclnt.h
+new file mode 100644
+index 00000000..bbc69536
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/clnt/rpclnt.h
+@@ -0,0 +1,49 @@
++/**
++ * system/src/rpclnt/rpclnt.h
++ *
++ * History:
++ *    2012/08/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __RPCLNT_H__
++#define __RPCLNT_H__
++
++struct rpclnt
++{
++	struct work_struct	svq_work;
++	struct work_struct	rvq_work;
++
++	int			inited;
++	char			*name;
++
++	void			*svq;
++	int			svq_tx_irq;
++	int			svq_rx_irq;
++	int			svq_num_bufs;
++	u32			svq_buf_phys;
++	u32			svq_vring_phys;
++	int			svq_vring_algn;
++
++	void			*rvq;
++	int			rvq_tx_irq;
++	int			rvq_rx_irq;
++	int			rvq_num_bufs;
++	u32			rvq_buf_phys;
++	u32			rvq_vring_phys;
++	int			rvq_vring_algn;
++};
++
++extern struct rpclnt *rpclnt_sync(const char *bus_name);
++
++#endif /* __RPCLNT_H__ */
+diff --git a/drivers/remoteproc/ambarella/clnt/rpclnt_ca9_b.c b/drivers/remoteproc/ambarella/clnt/rpclnt_ca9_b.c
+new file mode 100644
+index 00000000..9520d01f
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/clnt/rpclnt_ca9_b.c
+@@ -0,0 +1,202 @@
++/**
++ * system/src/rpclnt/rpclnt.h
++ *
++ * History:
++ *    2012/08/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++ 
++#include <linux/module.h>
++#include <linux/kthread.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++
++#include <plat/remoteproc_cfg.h>
++#include <plat/rpdev.h>
++#include <plat/rct.h>
++
++#include "rpclnt.h"
++#include "vq.h"
++
++extern void rpdev_svq_cb(struct vq *vq);
++extern void rpdev_rvq_cb(struct vq *vq);
++
++DECLARE_COMPLETION(rpclnt_comp);
++
++static struct rpclnt G_rproc_ca9_b = {
++
++	.name		= "rpclnt_ca9_a_and_b",
++	.inited		= 0,
++
++	.svq_tx_irq	= VRING_CA9_B_TO_A_HOST_IRQ,
++	.svq_rx_irq	= VRING_CA9_B_TO_A_CLNT_IRQ,
++	.svq_num_bufs	= RPMSG_NUM_BUFS >> 1,
++	.svq_buf_phys	= VRING_BUF_CA9_A_AND_B,
++	.svq_vring_phys	= VRING_CA9_B_TO_A,
++	.svq_vring_algn	= RPMSG_VRING_ALIGN,
++
++	.rvq_tx_irq	= VRING_CA9_A_TO_B_HOST_IRQ,
++	.rvq_rx_irq	= VRING_CA9_A_TO_B_CLNT_IRQ,
++	.rvq_num_bufs	= RPMSG_NUM_BUFS >> 1,
++	.rvq_buf_phys	= VRING_BUF_CA9_A_AND_B + (RPMSG_TOTAL_BUF_SPACE >> 1),
++	.rvq_vring_phys	= VRING_CA9_A_TO_B,
++	.rvq_vring_algn	= RPMSG_VRING_ALIGN,
++};
++
++struct rpclnt *rpclnt_sync(const char *bus_name)
++{
++	struct rpclnt *rpclnt = &G_rproc_ca9_b;
++
++	if (strcmp(bus_name, "ca9_a_and_b"))
++		return NULL;
++
++	if (!rpclnt->inited)
++		wait_for_completion(&rpclnt_comp);
++
++	return &G_rproc_ca9_b;
++}
++
++static void rpclnt_complete_registration(struct rpclnt *rpclnt)
++{
++	u32 buf = rpclnt->rvq_buf_phys;
++
++	vq_init_unused_bufs(rpclnt->rvq, (void*)buf, RPMSG_BUF_SIZE);
++
++	rpclnt->inited = 1;
++	complete_all(&rpclnt_comp);
++}
++
++static irqreturn_t rpclnt_isr(int irq, void *dev_id)
++{
++	struct rpclnt *rpclnt = dev_id;
++
++	if (!rpclnt->inited && irq == rpclnt->svq_rx_irq) {
++
++		rpclnt_complete_registration(rpclnt);
++
++		amba_writel(AHB_SCRATCHPAD_REG(0x14),
++			    0x1 << (irq - AXI_SOFT_IRQ(0)));
++
++		return IRQ_HANDLED;
++	}
++
++	/*
++	 * Before scheduling the bottom half for processing the messages,
++	 * we tell the remote host not to notify us (generate interrupts) when
++	 * subsequent messages are enqueued.  The bottom half will pull out
++	 * this message and the pending ones.  Once it processed all the messages
++	 * in the queue, it will re-enable remote host for the notification.
++	 */
++	if (irq == rpclnt->rvq_rx_irq) {
++
++		vq_disable_used_notify(rpclnt->rvq);
++		schedule_work(&rpclnt->rvq_work);
++
++	} else if (irq == rpclnt->svq_rx_irq) {
++
++		vq_disable_used_notify(rpclnt->svq);
++		schedule_work(&rpclnt->svq_work);
++	}
++
++	amba_writel(AHB_SCRATCHPAD_REG(0x14),
++		    0x1 << (irq - AXI_SOFT_IRQ(0)));
++
++	return IRQ_HANDLED;
++}
++
++static void rpclnt_rvq_worker(struct work_struct *work)
++{
++	struct rpclnt *rpclnt = container_of(work, struct rpclnt, rvq_work);
++	struct vq *vq = rpclnt->rvq;
++
++	if (vq->cb)
++		vq->cb(vq);
++}
++
++static void rpclnt_svq_worker(struct work_struct *work)
++{
++	struct rpclnt *rpclnt = container_of(work, struct rpclnt, svq_work);
++	struct vq *vq = rpclnt->svq;
++
++	if (vq->cb)
++		vq->cb(vq);
++}
++
++static void rpclnt_kick_rvq(struct vq *vq)
++{
++	/*
++	 * Honor the flag set by the remote host.
++	 *
++	 * Most of the time, the remote host want to supress their
++	 * tx-complete interrupts.  In this case, we don't bother it.
++	 */
++	if (vq_kick_prepare(vq)) {
++
++		amba_writel(AHB_SCRATCHPAD_REG(0x10),
++			    0x1 << (107 - AXI_SOFT_IRQ(0)));
++	}
++}
++
++static void rpclnt_kick_svq(struct vq *vq)
++{
++	/*
++	 * Honor the flag set by the remote host.
++	 *
++	 * When the remote host is already busy enough processing the
++	 * messages, it might suppress the interrupt and work in polling
++	 * mode.
++	 */
++	if (vq_kick_prepare(vq)) {
++
++		amba_writel(AHB_SCRATCHPAD_REG(0x10),
++			    0x1 << (109 - AXI_SOFT_IRQ(0)));
++	}
++}
++
++static int rpclnt_drv_init(void)
++{
++	int ret;
++	struct rpclnt *rpclnt = &G_rproc_ca9_b;
++
++	rpclnt->svq = vq_create(rpdev_svq_cb,
++				rpclnt_kick_svq,
++				rpclnt->svq_num_bufs,
++				ambarella_phys_to_virt(rpclnt->svq_vring_phys),
++				rpclnt->svq_vring_algn);
++
++	rpclnt->rvq = vq_create(rpdev_rvq_cb,
++				rpclnt_kick_rvq,
++				rpclnt->rvq_num_bufs,
++				ambarella_phys_to_virt(rpclnt->rvq_vring_phys),
++				rpclnt->rvq_vring_algn);
++
++	INIT_WORK(&rpclnt->svq_work, rpclnt_svq_worker);
++	INIT_WORK(&rpclnt->rvq_work, rpclnt_rvq_worker);
++
++	ret = request_irq(rpclnt->svq_rx_irq, rpclnt_isr,
++			  IRQF_SHARED, "rpclnt_svq_rx", rpclnt);
++	if (ret)
++		printk("Error: failed to request svq_rx_irq: %d, err: %d\n",
++		       rpclnt->svq_rx_irq, ret);
++
++	ret = request_irq(rpclnt->rvq_rx_irq, rpclnt_isr,
++			  IRQF_SHARED, "rpclnt_rvq_rx", rpclnt);
++
++	if (ret)
++		printk("Error: failed to request rvq_rx_irq: %d, err: %d\n",
++		       rpclnt->rvq_rx_irq, ret);
++
++	return 0;
++}
++
++module_init(rpclnt_drv_init);
+diff --git a/drivers/remoteproc/ambarella/clnt/rpdev.c b/drivers/remoteproc/ambarella/clnt/rpdev.c
+new file mode 100644
+index 00000000..854e8446
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/clnt/rpdev.c
+@@ -0,0 +1,223 @@
++/**
++ * system/src/rpclnt/rpdev.c
++ *
++ * History:
++ *    2012/08/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++#include <linux/string.h>
++#include <linux/kernel.h>
++#include <linux/rpmsg.h>
++#include <linux/slab.h>
++#include <linux/io.h>
++
++#include <mach/hardware.h>
++#include <plat/rpdev.h>
++
++#include "rpclnt.h"
++#include "vq.h"
++
++static struct rpdev *g_registered_rpdev[64];
++static int g_registered_cnt;
++DEFINE_SPINLOCK(spinlock_rpdev_tbl);
++
++static struct rpdev *rpdev_lookup(int src, int dst)
++{
++	struct rpdev *rpdev = NULL;
++	unsigned long flag;
++	int i;
++
++	spin_lock_irqsave(&spinlock_rpdev_tbl, flag);
++
++	for (i = 0; i < g_registered_cnt; i++) {
++
++		rpdev = g_registered_rpdev[i];
++
++		if (rpdev->src == src && rpdev->dst == dst) {
++		    spin_unlock_irqrestore(&spinlock_rpdev_tbl, flag);
++		    return rpdev;
++		}
++
++	}
++
++	spin_unlock_irqrestore(&spinlock_rpdev_tbl, flag);
++
++	return NULL;
++}
++
++void rpdev_rvq_cb(struct vq *vq)
++{
++	struct rpmsg_hdr	*hdr;
++	struct rpdev		*rpdev;
++	int			len;
++	int			idx;
++
++	while (1) {
++
++		idx = vq_get_avail_buf(vq, (void**)&hdr, &len);
++		if (idx < 0) {
++
++			vq_enable_used_notify(vq);
++
++			/*
++			 * In case any message slipped in the window, check
++			 * again.  Otherwise, it will be delayed until next
++			 * interrupt.
++			 */
++			idx = vq_get_avail_buf(vq, (void**)&hdr, &len);
++			if (idx < 0)
++				break;
++
++			/* Disable the intruupt, and continue to poll */
++			vq_disable_used_notify(vq);
++		}
++
++		rpdev = rpdev_lookup(hdr->dst, hdr->src);
++		if (rpdev) {
++
++			rpdev->cb(rpdev, &hdr->data, hdr->len, rpdev->priv, hdr->src);
++			vq_add_used_buf(vq, idx, RPMSG_BUF_SIZE);
++
++			continue;
++		}
++
++		rpdev = rpdev_lookup(hdr->dst, RPMSG_NS_ADDR);
++		if (rpdev) {
++
++			if (hdr->len == sizeof(struct rpmsg_ns_msg)) {
++
++				rpdev->dst = hdr->src;
++				complete(&rpdev->comp);
++				vq_add_used_buf(vq, idx, RPMSG_BUF_SIZE);
++			}
++		}
++	}
++
++	vq->kick(vq);
++
++}
++
++void rpdev_svq_cb(struct vq *vq)
++{
++	vq_complete(vq);
++	vq_enable_used_notify(vq);
++}
++
++int rpdev_send_offchannel(struct rpdev *rpdev, u32 src, u32 dst, void *data, int len)
++{
++	int idx				= 0;
++	int buf_len			= 0;
++	struct rpmsg_hdr *hdr		= NULL;
++	struct vq *vq;
++
++	vq = rpdev->rpclnt->svq;
++
++	idx = vq_get_avail_buf(vq, (void**)&hdr, &buf_len);
++	if (idx < 0)
++		return -1;
++
++	hdr->src	= src;
++	hdr->dst	= dst;
++	hdr->reserved	= 0;
++	hdr->len	= len;
++	hdr->flags	= 0;
++
++	memcpy(hdr->data, data, len);
++
++	vq_add_used_buf(vq, idx, buf_len);
++
++	vq->kick(vq);
++
++	return 0;
++}
++
++int rpdev_send(struct rpdev *rpdev, void *data, int len)
++{
++	struct vq *vq;
++
++	while (rpdev_send_offchannel(rpdev, rpdev->src, rpdev->dst, data, len)) {
++
++		vq = rpdev->rpclnt->svq;
++
++		vq_enable_used_notify(vq);
++		vq_wait_for_completion(vq);
++		vq_disable_used_notify(vq);
++	}
++
++	return 0;
++}
++
++int rpdev_trysend(struct rpdev *rpdev, void *data, int len)
++{
++	return rpdev_send_offchannel(rpdev, rpdev->src, rpdev->dst,
++				     data, len);
++}
++
++int rpdev_register(struct rpdev *rpdev, const char *bus_name)
++{
++	struct rpmsg_ns_msg nsm;
++	struct rpclnt *rpclnt;
++	unsigned long flag;
++
++	rpclnt = rpclnt_sync(bus_name);
++	rpdev->rpclnt = rpclnt;
++
++	memcpy(&nsm.name, rpdev->name, RPMSG_NAME_LEN);
++	nsm.addr = rpdev->src;
++	nsm.flags = rpdev->flags;
++
++	rpdev_send_offchannel(rpdev, rpdev->src, RPMSG_NS_ADDR,
++			      &nsm, sizeof(nsm));
++
++	wait_for_completion(&rpdev->comp);
++
++	/*
++	 * Supress the tx-complete interrupt by default.
++	 *
++	 * This interuupt will be re-enabled when necessary.
++	 * When all available tx buffers are used up, users may
++	 * be blocked if they were calling rpdev_send() API.
++	 *
++	 * In this case, we'd like to recieve interrupt when any
++	 * tx-buffer is available so we can waken up the blocked
++	 * users.
++	 */
++	vq_disable_used_notify(rpclnt->svq);
++
++	return 0;
++}
++
++struct rpdev *rpdev_alloc(const char *name, int flags, rpdev_cb cb, void *priv)
++{
++	struct rpdev *rpdev;
++	unsigned long flag;
++
++	rpdev = kmalloc(sizeof(*rpdev), GFP_KERNEL);
++
++	strcpy(rpdev->name, name);
++
++	spin_lock_irqsave(&spinlock_rpdev_tbl, flag);
++	g_registered_rpdev[g_registered_cnt] = rpdev;
++
++	rpdev->src	= RPMSG_RESERVED_ADDRESSES + g_registered_cnt++;
++	spin_unlock_irqrestore(&spinlock_rpdev_tbl, flag);
++
++	rpdev->dst	= RPMSG_NS_ADDR;
++	rpdev->flags	= flags;
++	rpdev->cb	= cb;
++	rpdev->priv	= priv;
++
++	init_completion(&rpdev->comp);
++
++	return rpdev;
++}
+diff --git a/drivers/remoteproc/ambarella/clnt/vq.c b/drivers/remoteproc/ambarella/clnt/vq.c
+new file mode 100644
+index 00000000..7d224529
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/clnt/vq.c
+@@ -0,0 +1,382 @@
++/**
++ * system/src/rpclnt/vq.c
++ *
++ * History:
++ *    2012/08/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#if defined(__KERNEL__)
++#include <linux/slab.h>
++#else
++#include <itron.h>
++#include <kutil.h>
++extern void clean_d_cache_region(void *addr, unsigned int size);
++extern void flush_d_cache_region(void *addr, unsigned int size);
++#endif
++
++#include "vq.h"
++
++/******************************************************************************
++ * OS dependent utility functions
++ *****************************************************************************/
++
++#if defined(__KERNEL__)
++
++static inline struct vq *vq_alloc(void)
++{
++	return kmalloc(sizeof(struct vq), GFP_KERNEL);
++}
++
++static inline void vq_init_completion(struct vq *vq)
++{
++	init_completion(&vq->comp);
++}
++
++inline void vq_wait_for_completion(struct vq *vq)
++{
++	wait_for_completion(&vq->comp);
++}
++
++inline void vq_complete(struct vq *vq)
++{
++	complete(&vq->comp);
++}
++
++/*
++ * For Linux, we map the whole PPM region as non-cached.
++ * So no cache operation needed.
++ *
++ */
++static inline void vq_clean_d_cache_region(void *addr, unsigned int size)
++{
++}
++
++static inline void vq_flush_d_cache_region(void *addr, unsigned int size)
++{
++}
++
++static inline void vq_lock_init(struct vq *vq)
++{
++	spin_lock_init(&vq->lock);
++}
++
++#define vq_lock(vq, flag)	spin_lock_irqsave(&vq->lock, flag)
++#define vq_unlock(vq, flag)	spin_unlock_irqrestore(&vq->lock, flag)
++
++#else /* ITRON */
++
++static inline struct vq *vq_alloc(void)
++{
++	struct vq *vq;
++
++	pget_mpl(HEAP_MPLID, sizeof(*vq), (VP *)&vq);
++	return vq;
++}
++
++static inline void vq_init_completion(struct vq *vq)
++{
++	T_CFLG pk_cflg;
++
++	pk_cflg.flgatr	= (TA_TFIFO | TA_WMUL | TA_CLR);
++	pk_cflg.iflgptn	= 0x0;
++	vq->flgid	= acre_flg(&pk_cflg);
++
++	K_ASSERT(vq->flgid > 0);
++}
++
++void vq_wait_for_completion(struct vq *vq)
++{
++	ER ercd;
++	FLGPTN flgptn;
++
++	ercd = wai_flg(vq->flgid, 0x1, TWF_ANDW, &flgptn);
++	K_ASSERT(ercd == E_OK);
++}
++
++void vq_complete(struct vq *vq)
++{
++	ER ercd;
++
++	ercd = set_flg(vq->flgid, 0x1);
++	K_ASSERT(ercd == E_OK);
++}
++
++static inline void vq_clean_d_cache_region(void *addr, unsigned int size)
++{
++	u32 mask = (1 << CLINE) - 1;
++
++	addr = (u32)addr &~ mask;
++	size = (size + mask) &~ mask;
++
++	clean_d_cache_region(addr, size);
++}
++
++static inline void vq_flush_d_cache_region(void *addr, unsigned int size)
++{
++	u32 mask = (1 << CLINE) - 1;
++
++	addr = (u32)addr &~ mask;
++	size = (size + mask) &~ mask;
++
++	flush_d_cache_region(addr, size);
++}
++
++static inline void vq_lock_init(struct vq *vq)
++{
++	T_CMTX pk_cmtx;
++
++	pk_cmtx.mtxatr  = TA_TFIFO;
++	pk_cmtx.ceilpri = 0;
++	vq->mtxid = acre_mtx(&pk_cmtx);
++	K_ASSERT(vq->mtxid > 0);
++}
++
++static inline void vq_lock(struct vq *vq)
++{
++	ER er;
++
++	er = loc_mtx(vq->mtxid);
++	K_ASSERT (er == E_OK);
++}
++
++static inline void vq_unlock(struct vq *vq)
++{
++	ER er;
++
++	er = unl_mtx(vq->mtxid);
++	K_ASSERT (er == E_OK);
++}
++#endif /* __KERNEL__ */
++
++/******************************************************************************/
++
++int vq_kick_prepare(struct vq *vq)
++{
++	vq_flush_d_cache_region(&vq->vring.avail->flags,
++				sizeof(vq->vring.avail->flags));
++
++	return !(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
++}
++void vq_enable_used_notify(struct vq *vq)
++{
++	vq_flush_d_cache_region(&vq->vring.used->flags,
++				sizeof(vq->vring.used->flags));
++
++	vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
++
++	vq_clean_d_cache_region(&vq->vring.used->flags,
++				sizeof(vq->vring.used->flags));
++}
++
++void vq_disable_used_notify(struct vq *vq)
++{
++	vq_flush_d_cache_region(&vq->vring.used->flags,
++				sizeof(vq->vring.used->flags));
++
++	vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
++
++	vq_clean_d_cache_region(&vq->vring.used->flags,
++				sizeof(vq->vring.used->flags));
++}
++
++int vq_more_avail_buf(struct vq *vq)
++{
++	struct vring_avail *avail = vq->vring.avail;
++
++	vq_flush_d_cache_region(avail, sizeof(*avail));
++
++	return vq->last_avail_idx != avail->idx;
++}
++
++struct vq *vq_create(void (*cb)(struct vq *vq),
++		     void (*kick)(struct vq *vq),
++		     int num_bufs,
++		     u32 vring_addr, int vring_algn)
++{
++	struct vq *vq = vq_alloc();
++
++	vq_init_completion(vq);
++	vq_lock_init(vq);
++
++	vq->cb 			= cb;
++	vq->kick		= kick;
++	vq->last_avail_idx	= 0;
++	vq->last_used_idx	= 0;
++
++	vring_init(&vq->vring, num_bufs, (void*)vring_addr, vring_algn);
++	printk("vring size: 0x%x\n", vring_size(num_bufs, vring_algn));
++
++	return vq;
++}
++
++/*
++ * vq_get_avail_buf and vq_add_used_buf usually used in pairs to
++ * grab a "available" buffer, use it, and then tell the HOST, we
++ * finish our usage.
++ */
++int vq_get_avail_buf(struct vq *vq, void **buf, int *len)
++{
++	int				idx;
++	u16				last_avail_idx;
++	struct vring_avail		*avail;
++	struct vring_desc		*desc;
++	unsigned long			flag;
++
++	vq_lock(vq, flag);
++
++	if (!vq_more_avail_buf(vq)) {
++		vq_unlock(vq, flag);
++		return -1;
++	}
++
++	last_avail_idx	= vq->last_avail_idx++ % vq->vring.num;
++	avail		= vq->vring.avail;
++
++	vq_flush_d_cache_region(avail, sizeof(*avail));
++	vq_flush_d_cache_region(&avail->ring[last_avail_idx], sizeof(*avail->ring));
++
++	idx		= avail->ring[last_avail_idx];
++	desc		= &vq->vring.desc[idx];
++	vq_flush_d_cache_region(desc, sizeof(*desc));
++
++	*buf		= (void*)ambarella_phys_to_virt(desc->addr);
++	*len		= desc->len;
++
++	vq_flush_d_cache_region(*buf, *len);
++
++	vq_unlock(vq, flag);
++
++	return idx;
++}
++
++int vq_add_used_buf(struct vq *vq, int idx, int len)
++{
++	struct vring_used_elem	*used_elem;
++	struct vring_used	*used;
++	unsigned long		flag;
++
++	vq_lock(vq, flag);
++
++	/* Clean the cache of buffer of the used buffer */
++	vq_clean_d_cache_region((void*)(unsigned long)vq->vring.desc[idx].addr, len);
++
++	/* Update the used descriptor and clean its cache region */
++	used		= vq->vring.used;
++	used_elem	= &used->ring[used->idx % vq->vring.num];
++	used_elem->id	= idx;
++	used_elem->len	= len;
++	vq_clean_d_cache_region(used_elem, sizeof(*used_elem));
++
++	/*
++	 * Update the used descriptor index and clean its cache region.
++	 * This step has to be done as the last step.  The order matters.
++	 */
++	used->idx++;
++	vq_clean_d_cache_region(used, sizeof(*used));
++
++	vq_unlock(vq, flag);
++
++	return 0;
++}
++
++/*
++ * Linux HOST rpmsg implementation only setup the RX buffer descriptors on HOST.
++ * Buffer descriptors for HOST TX (CLIENT RX) are left for CLIENT to setup.
++ *
++ * A very IMPORTANT thing should be noted: Though the Linux HOST does not setup
++ * the HOST TX descriptors, it "zeros out" them during vring initialization.
++ * So this API should be synchronized and called only after the Linux HOST has
++ * finished their initialization.
++ */
++int vq_init_unused_bufs(struct vq *vq, void *buf, int len)
++{
++	struct vring_desc	*desc;
++	unsigned long		flag;
++	int			i;
++
++	vq_lock(vq, flag);
++
++	for (i = 0; i < vq->vring.num; i++) {
++
++		desc		= &vq->vring.desc[i];
++		desc->addr	= ambarella_virt_to_phys((u32)buf);
++		desc->len	= len;
++		vq_clean_d_cache_region(desc, sizeof(*desc));
++
++		buf += len;
++	}
++
++	vq_unlock(vq, flag);
++
++	return 0;
++}
++
++#if 0
++/*
++ * Normally, this API should not be used for now. We just keep it in case the
++ * API expansion or more comprehensive bits are added in the future.
++ */
++
++int vq_add_avail_buf(struct vq *vq, void *buf, int len)
++{
++	struct vring_avail	*avail;
++	struct vring_desc	*desc;
++	unsigned long		flag;
++
++	vq_lock(vq, flag);
++	vq->num_free--;
++
++	avail		= vq->vring.avail;
++	desc		= &vq->vring.desc[avail->idx % vq->vring.num];
++	desc->addr	= ambarella_virt_to_phys((u32)buf);
++	desc->len	= len;
++	vq_clean_d_cache_region(desc, sizeof(*desc));
++
++	/*
++	 * Update the avail descriptor index and clean its cache region.
++	 * This step has to be done as the last step.  The order matters.
++	 */
++	avail->idx++;
++	vq_clean_d_cache_region(avail, sizeof(*avail));
++
++	vq_unlock(vq, flag);
++
++	return vq->num_free;
++}
++
++void *vq_get_used_buf(struct vq *vq)
++{
++	int			last_used_idx;
++	struct vring_used_elem	*used_elem;
++	struct vring_desc	*desc;
++	void			*buf;
++	unsigned long		flag;
++
++	vq_lock(vq, flag);
++
++	last_used_idx	= vq->last_used_idx++ % vq->vring.num;
++	used_elem	= &vq->vring.used->ring[last_used_idx];
++	vq_flush_d_cache_region(used_elem, sizeof(*used_elem));
++
++	desc		= &vq->vring.desc[used_elem->id];
++	vq_flush_d_cache_region(desc, sizeof(*desc));
++
++	buf		= (void*)ambarella_phys_to_virt(desc->addr);
++	vq_flush_d_cache_region(buf, desc->len);
++
++	vq_unlock(vq, flag);
++
++	return buf;
++}
++#endif
+diff --git a/drivers/remoteproc/ambarella/clnt/vq.h b/drivers/remoteproc/ambarella/clnt/vq.h
+new file mode 100644
+index 00000000..725d5990
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/clnt/vq.h
+@@ -0,0 +1,71 @@
++/**
++ * system/src/rpclnt/vq.h
++ *
++ * History:
++ *    2012/08/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __VQ_H__
++#define __VQ_H__
++
++#if defined(__KERNEL__)
++#include <linux/virtio_ring.h>
++#include <linux/sched.h>
++#else
++#include <itron.h>
++#include "virtio_ring.h"
++
++static inline void *ambarella_virt_to_phys(void *addr)
++{
++        return addr;
++}
++
++static inline void *ambarella_phys_to_virt(void *addr)
++{
++        return addr;
++}
++#endif
++
++struct vq {
++#if defined(__KERNEL__)
++	spinlock_t		lock;
++	struct completion	comp;
++#else
++	ID			mtxid;
++	ID			flgid;
++#endif
++	void			(*cb)(struct vq *vq);
++	void			(*kick)(struct vq *vq);
++	struct vring		vring;
++	u16			last_avail_idx;
++	u16			last_used_idx;
++};
++
++extern struct vq *vq_create(void (*cb)(struct vq *vq),
++			    void (*kick)(struct vq *vq),
++			    int num_bufs,
++			    u32 vring_virt, int vring_algn);
++
++extern void vq_wait_for_completion(struct vq *vq);
++extern void vq_complete(struct vq *vq);
++
++extern int vq_kick_prepare(struct vq *vq);
++extern void vq_enable_used_notify(struct vq *vq);
++extern void vq_disable_used_notify(struct vq *vq);
++extern int vq_more_avail_buf(struct vq *vq);
++extern int vq_get_avail_buf(struct vq *vq, void **buf, int *len);
++extern int vq_add_used_buf(struct vq *vq, int idx, int len);
++extern int vq_init_unused_bufs(struct vq *vq, void *buf, int len);
++
++#endif /* __VQ_H__ */
+diff --git a/drivers/remoteproc/ambarella/host/rproc_ambarella.c b/drivers/remoteproc/ambarella/host/rproc_ambarella.c
+new file mode 100644
+index 00000000..721ec6c2
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/host/rproc_ambarella.c
+@@ -0,0 +1,208 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/remoteproc.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++
++#include <plat/remoteproc.h>
++#include <plat/rct.h>
++
++#include "../../remoteproc_internal.h"
++
++static void rpmsg_send_irq(int irq)
++{
++	if (irq > 0) {
++		amba_writel(AHB_SCRATCHPAD_REG(0x10), 0x1 << (irq - AXI_SOFT_IRQ(0)));
++	}
++	else {
++		irq = -irq;
++		amba_writel(VIC3_REG(0x18), 0x1 << (irq - 96));
++	}
++}
++
++static void rpmsg_ack_irq(int irq)
++{
++	amba_writel(AHB_SCRATCHPAD_REG(0x14), 0x1 << (irq - AXI_SOFT_IRQ(0)));
++}
++
++static void ambarella_rproc_kick(struct rproc *rproc, int vqid)
++{
++	struct ambarella_rproc_pdata *pdata = rproc->priv;
++
++	if (vqid == 0)
++		rpmsg_send_irq(pdata->rvq_tx_irq);
++	else
++		rpmsg_send_irq(pdata->svq_tx_irq);
++}
++
++static void rproc_svq_worker(struct work_struct *work)
++{
++	struct ambarella_rproc_pdata *pdata;
++	struct rproc *rproc;
++
++	pdata = container_of(work, struct ambarella_rproc_pdata, svq_work);
++	rproc = pdata->rproc;
++
++	rproc_vq_interrupt(rproc, 1);
++}
++
++static void rproc_rvq_worker(struct work_struct *work)
++{
++	struct ambarella_rproc_pdata *pdata;
++	struct rproc *rproc;
++	struct rproc_vring *rvring;
++
++	pdata = container_of(work, struct ambarella_rproc_pdata, rvq_work);
++	rproc = pdata->rproc;
++	rvring = idr_find(&pdata->rproc->notifyids, 0);
++
++	while (1) {
++
++		if (rproc_vq_interrupt(rproc, 0) == IRQ_HANDLED)
++			continue;
++
++		virtqueue_enable_cb(rvring->vq);
++
++		if (rproc_vq_interrupt(rproc, 0) == IRQ_HANDLED) {
++
++			virtqueue_disable_cb(rvring->vq);
++			continue;
++		}
++
++		break;
++	}
++}
++
++static irqreturn_t rproc_ambarella_isr(int irq, void *dev_id)
++{
++	struct ambarella_rproc_pdata *pdata = dev_id;
++	struct rproc_vring *rvring;
++
++	if (irq == pdata->rvq_rx_irq) {
++		rvring = idr_find(&pdata->rproc->notifyids, 0);
++		virtqueue_disable_cb(rvring->vq);
++		schedule_work(&pdata->rvq_work);
++	}
++	else if (irq == pdata->svq_rx_irq) {
++		schedule_work(&pdata->svq_work);
++	}
++
++	rpmsg_ack_irq(irq);
++
++	return IRQ_HANDLED;
++}
++
++static int ambarella_rproc_start(struct rproc *rproc)
++{
++	return 0;
++}
++
++static int ambarella_rproc_stop(struct rproc *rproc)
++{
++	return 0;
++}
++
++static struct rproc_ops ambarella_rproc_ops = {
++	.start		= ambarella_rproc_start,
++	.stop		= ambarella_rproc_stop,
++	.kick		= ambarella_rproc_kick,
++};
++
++extern const struct rproc_fw_ops rproc_dummy_fw_ops;
++
++static int ambarella_rproc_probe(struct platform_device *pdev)
++{
++	struct ambarella_rproc_pdata *pdata = pdev->dev.platform_data;
++	struct rproc *rproc;
++	int ret;
++
++	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
++	if (ret) {
++		dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret);
++		return ret;
++	}
++
++	rproc = rproc_alloc(&pdev->dev, pdata->name, &ambarella_rproc_ops,
++			    pdata->firmware, 8192);
++	if (!rproc) {
++		ret = -ENOMEM;
++		goto free_rproc;
++	}
++
++	ret = request_irq(pdata->svq_rx_irq, rproc_ambarella_isr, IRQF_SHARED,
++			"rproc-svq_rx", pdata);
++	if (ret)
++		goto free_rproc;
++
++	ret = request_irq(pdata->rvq_rx_irq, rproc_ambarella_isr, IRQF_SHARED,
++			"rproc-rvq_rx", pdata);
++	if (ret)
++		goto free_rproc;
++
++	INIT_WORK(&pdata->svq_work, rproc_svq_worker);
++	INIT_WORK(&pdata->rvq_work, rproc_rvq_worker);
++
++	mutex_init(&rproc->lock);
++
++	rproc->priv = pdata;
++	pdata->rproc = rproc;
++
++	platform_set_drvdata(pdev, rproc);
++
++	rproc->fw_ops = &rproc_dummy_fw_ops;
++	ret = rproc_add(rproc);
++	if (ret)
++		goto free_rproc;
++
++	return 0;
++
++free_rproc:
++	rproc_put(rproc);
++	return ret;
++}
++
++static int ambarella_rproc_remove(struct platform_device *pdev)
++{
++	struct rproc *rproc = platform_get_drvdata(pdev);
++
++	rproc_del(rproc);
++	rproc_put(rproc);
++	return 0;
++}
++
++static struct platform_device_id id_table[] = {
++	{ "ca9_a_and_b", 0},
++	{ "ca9_a_and_arm11", 0},
++	{ "ca9_b_and_arm11", 0},
++    { "c0_and_c1", 0},
++	{ /* sentinel */ }
++};
++
++static struct platform_driver ambarella_rproc_driver = {
++	.probe = ambarella_rproc_probe,
++	.remove = ambarella_rproc_remove,
++	.driver = {
++		.name = "ambarella-rproc",
++		.owner = THIS_MODULE,
++	},
++	.id_table = id_table,
++};
++
++static int ambarella_rproc_driver_init(void)
++{
++	platform_driver_register(&ambarella_rproc_driver);
++	return 0;
++}
++
++static void ambarella_rproc_driver_fini(void)
++{
++	platform_driver_unregister(&ambarella_rproc_driver);
++}
++
++module_init(ambarella_rproc_driver_init);
++module_exit(ambarella_rproc_driver_fini);
++
++MODULE_DESCRIPTION("Ambarella Remote Processor control driver");
+diff --git a/drivers/remoteproc/ambarella/host/rproc_ca9_a.c b/drivers/remoteproc/ambarella/host/rproc_ca9_a.c
+new file mode 100644
+index 00000000..04646a4b
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/host/rproc_ca9_a.c
+@@ -0,0 +1,193 @@
++/*
++ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
++ *
++ * Copyright (C) 2012-2012, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++
++#include <linux/slab.h>
++#include <linux/virtio_ids.h>
++#include <linux/rpmsg.h>
++#include <linux/dma-mapping.h>
++
++#include <plat/remoteproc.h>
++#include <plat/remoteproc_cfg.h>
++
++/*
++ * The gen_rsc_table_* functions below fabricate the "resource table", which is
++ * used to initialize the vring configurations by the RPROC subsystem.
++ *
++ * The tables were originally meant to be loaded from ELF files on filesystem.
++ * It's a flexible and generic design, but requires extra maintenance out side
++ * the kernel space. So we currently code it plainly and directly here.
++ *
++ * The following illustrate the layout and structure of the table we use.
++ * Watch out the "sizeof()", since most of the structures here are embedded with
++ * variable-length array.
++ *
++ *  0x0000  &table
++ *
++ *          < sizeof(*table) >
++ *          < sizeof(u32) * table->num >
++ *
++ *  0x0014  &hdr (&table->offset)
++ *
++ *          < sizeof(*hdr) >
++ *
++ *  0x0018  &vdev (&hdr->data)
++ *
++ *          < sizeof(*vdev) >
++ *
++ *  0x0030  &vdev->ring[0] (&hdr->data)
++ *
++ *          < sizeof(*vring) >
++ *
++ *  0x0044  &vdev->ring[1];
++ *
++ *         < sizeof(*vring) >
++ *  0x0058
++ */
++
++static struct resource_table *gen_rsc_table_ca9_b(int *tablesz)
++{
++	struct resource_table		*table;
++	struct fw_rsc_hdr		*hdr;
++	struct fw_rsc_vdev		*vdev;
++	struct fw_rsc_vdev_vring	*vring;
++
++	*tablesz		= sizeof(*table) + sizeof(u32) * 1
++				    + sizeof(*hdr) + sizeof(*vdev)
++				    + sizeof(*vring) * 2;
++
++	table			= kzalloc((*tablesz), GFP_KERNEL);
++	table->ver		= 1;
++	table->num		= 1;
++	table->offset[0]	= sizeof(*table) + sizeof(u32) * table->num;
++
++	hdr			= (void*)table + table->offset[0];
++	hdr->type		= RSC_VDEV;
++	vdev			= (void*)&hdr->data;
++	vdev->id		= VIRTIO_ID_RPMSG;
++	vdev->notifyid		= 123;
++	vdev->dfeatures		= (1 << VIRTIO_RPMSG_F_NS);
++	vdev->config_len	= 0;
++	vdev->num_of_vrings	= 2;
++
++	vring			= (void*)&vdev->vring[0];
++	vring->da		= VRING_CA9_B_TO_A;
++	vring->align		= PAGE_SIZE;
++	vring->num		= RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 111;
++
++	vring			= (void*)&vdev->vring[1];
++	vring->da		= VRING_CA9_A_TO_B;
++	vring->align		= PAGE_SIZE;
++	vring->num		= RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 112;
++
++	return table;
++}
++
++static struct resource_table *gen_rsc_table_arm11(int *tablesz)
++{
++	struct resource_table		*table;
++	struct fw_rsc_hdr		*hdr;
++	struct fw_rsc_vdev		*vdev;
++	struct fw_rsc_vdev_vring	*vring;
++
++	*tablesz		= sizeof(*table) + sizeof(u32) * 1
++				    + sizeof(*hdr) + sizeof(*vdev)
++				    + sizeof(*vring) * 2;
++
++	table			= kzalloc((*tablesz), GFP_KERNEL);
++	table->ver		= 1;
++	table->num		= 1;
++	table->offset[0]	= sizeof(*table) + sizeof(u32) * table->num;
++
++	hdr			= (void*)table + table->offset[0];
++	hdr->type		= RSC_VDEV;
++	vdev			= (void*)&hdr->data;
++	vdev->id		= VIRTIO_ID_RPMSG;
++	vdev->notifyid		= 124;
++	vdev->dfeatures		= (1 << VIRTIO_RPMSG_F_NS);
++	vdev->config_len	= 0;
++	vdev->num_of_vrings	= 2;
++
++	vring			= (void*)&vdev->vring[0];
++	vring->da		= VRING_ARM11_TO_CA9_A;
++	vring->align		= PAGE_SIZE;
++	vring->num		= RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 111;
++
++	vring			= (void*)&vdev->vring[1];
++	vring->da		= VRING_CA9_A_TO_ARM11;
++	vring->align		= PAGE_SIZE;
++	vring->num		= RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 112;
++
++	return table;
++}
++
++static struct ambarella_rproc_pdata pdata_ca9_b = {
++	.name			= "ca9_a_and_b",
++	.firmware		= "dummy",
++	.svq_tx_irq		= VRING_CA9_A_TO_B_CLNT_IRQ,
++	.svq_rx_irq		= VRING_CA9_A_TO_B_HOST_IRQ,
++	.rvq_tx_irq		= VRING_CA9_B_TO_A_CLNT_IRQ,
++	.rvq_rx_irq		= VRING_CA9_B_TO_A_HOST_IRQ,
++	.ops			= NULL,
++	.buf_addr_pa		= VRING_BUF_CA9_A_AND_B,
++	.gen_rsc_table		= gen_rsc_table_ca9_b,
++};
++
++struct platform_device ambarella_rproc_ca9_a_and_b_dev = {
++	.name			= "ca9_a_and_b",
++	.id			= VIRTIO_ID_RPMSG,
++	.resource		= NULL,
++	.num_resources		= 0,
++	.dev			= {
++		.platform_data		= &pdata_ca9_b,
++		.dma_mask		= &ambarella_dmamask,
++		.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++};
++
++static struct ambarella_rproc_pdata pdata_arm11 = {
++	.name			= "ca9_a_and_arm11",
++	.firmware		= "dummy",
++	.svq_tx_irq		= -VRING_CA9_A_TO_ARM11_CLNT_IRQ,
++	.svq_rx_irq		= VRING_CA9_A_TO_ARM11_HOST_IRQ,
++	.rvq_tx_irq		= -VRING_ARM11_TO_CA9_A_CLNT_IRQ,
++	.rvq_rx_irq		= VRING_ARM11_TO_CA9_A_HOST_IRQ,
++	.ops			= NULL,
++	.buf_addr_pa		= VRING_BUF_CA9_A_AND_ARM11,
++	.gen_rsc_table		= gen_rsc_table_arm11,
++};
++
++struct platform_device ambarella_rproc_ca9_a_and_arm11_dev = {
++	.name			= "ca9_a_and_arm11",
++	.id	      	  	= VIRTIO_ID_RPMSG,
++	.resource     	  	= NULL,
++	.num_resources		= 0,
++	.dev			= {
++		.platform_data		= &pdata_arm11,
++		.dma_mask		= &ambarella_dmamask,
++		.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++};
+diff --git a/drivers/remoteproc/ambarella/host/rproc_ca9_b.c b/drivers/remoteproc/ambarella/host/rproc_ca9_b.c
+new file mode 100644
+index 00000000..f519ef0e
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/host/rproc_ca9_b.c
+@@ -0,0 +1,129 @@
++/*
++ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
++ *
++ * Copyright (C) 2012-2012, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++
++#include <linux/slab.h>
++#include <linux/virtio_ids.h>
++#include <linux/rpmsg.h>
++#include <linux/dma-mapping.h>
++
++#include <plat/remoteproc.h>
++#include <plat/remoteproc_cfg.h>
++
++/*
++ * The gen_rsc_table_* functions below fabricate the "resource table", which is
++ * used to initialize the vring configurations by the RPROC subsystem.
++ *
++ * The tables were originally meant to be loaded from ELF files on filesystem.
++ * It's a flexible and generic design, but requires extra maintenance out side
++ * the kernel space. So we currently code it plainly and directly here.
++ *
++ * The following illustrate the layout and structure of the table we use.
++ * Watch out the "sizeof()", since most of the structures here are embedded with
++ * variable-length array.
++ *
++ *  0x0000  &table
++ *
++ *          < sizeof(*table) >
++ *          < sizeof(u32) * table->num >
++ *
++ *  0x0014  &hdr (&table->offset)
++ *
++ *          < sizeof(*hdr) >
++ *
++ *  0x0018  &vdev (&hdr->data)
++ *
++ *          < sizeof(*vdev) >
++ *
++ *  0x0030  &vdev->ring[0] (&hdr->data)
++ *
++ *          < sizeof(*vring) >
++ *
++ *  0x0044  &vdev->ring[1];
++ *
++ *         < sizeof(*vring) >
++ *  0x0058
++ */
++
++static struct resource_table *gen_rsc_table_arm11(int *tablesz)
++{
++	struct resource_table		*table;
++	struct fw_rsc_hdr		*hdr;
++	struct fw_rsc_vdev		*vdev;
++	struct fw_rsc_vdev_vring	*vring;
++
++	*tablesz		= sizeof(*table) + sizeof(u32) * 1
++				    + sizeof(*hdr) + sizeof(*vdev)
++				    + sizeof(*vring) * 2;
++
++	table			= kzalloc((*tablesz), GFP_KERNEL);
++	table->ver		= 1;
++	table->num		= 1;
++	table->offset[0]	= sizeof(*table) + sizeof(u32) * table->num;
++
++	hdr			= (void*)table + table->offset[0];
++	hdr->type		= RSC_VDEV;
++	vdev			= (void*)&hdr->data;
++	vdev->id		= VIRTIO_ID_RPMSG;
++	vdev->notifyid		= 124;
++	vdev->dfeatures		= (1 << VIRTIO_RPMSG_F_NS);
++	vdev->config_len	= 0;
++	vdev->num_of_vrings	= 2;
++
++	vring			= (void*)&vdev->vring[0];
++	vring->da		= VRING_ARM11_TO_CA9_B;
++	vring->align		= PAGE_SIZE;
++	vring->num		= RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 111;
++
++	vring			= (void*)&vdev->vring[1];
++	vring->da		= VRING_CA9_B_TO_ARM11;
++	vring->align		= PAGE_SIZE;
++	vring->num		= RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 112;
++
++	return table;
++}
++
++static struct ambarella_rproc_pdata pdata_arm11 = {
++	.name			= "ca9_b_and_arm11",
++	.firmware		= "dummy",
++	.svq_tx_irq		= -VRING_CA9_B_TO_ARM11_CLNT_IRQ,
++	.svq_rx_irq		= VRING_CA9_B_TO_ARM11_HOST_IRQ,
++	.rvq_tx_irq		= -VRING_ARM11_TO_CA9_B_CLNT_IRQ,
++	.rvq_rx_irq		= VRING_ARM11_TO_CA9_B_HOST_IRQ,
++	.ops			= NULL,
++	.buf_addr_pa		= VRING_BUF_CA9_B_AND_ARM11,
++	.gen_rsc_table		= gen_rsc_table_arm11,
++};
++
++struct platform_device ambarella_rproc_ca9_b_and_arm11_dev = {
++	.name			= "ca9_b_and_arm11",
++	.id			= VIRTIO_ID_RPMSG,
++	.resource		= NULL,
++	.num_resources		= 0,
++	.dev			= {
++		.platform_data		= &pdata_arm11,
++		.dma_mask		= &ambarella_dmamask,
++		.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++};
+diff --git a/drivers/remoteproc/ambarella/host/rproc_s2.c b/drivers/remoteproc/ambarella/host/rproc_s2.c
+new file mode 100644
+index 00000000..dde36747
+--- /dev/null
++++ b/drivers/remoteproc/ambarella/host/rproc_s2.c
+@@ -0,0 +1,129 @@
++/*
++ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
++ *
++ * Copyright (C) 2012-2012, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/platform_device.h>
++
++#include <linux/slab.h>
++#include <linux/virtio_ids.h>
++#include <linux/rpmsg.h>
++#include <linux/dma-mapping.h>
++
++#include <plat/remoteproc.h>
++#include <plat/remoteproc_cfg.h>
++
++/*
++ * The gen_rsc_table_* functions below fabricate the "resource table", which is
++ * used to initialize the vring configurations by the RPROC subsystem.
++ *
++ * The tables were originally meant to be loaded from ELF files on filesystem.
++ * It's a flexible and generic design, but requires extra maintenance out side
++ * the kernel space. So we currently code it plainly and directly here.
++ *
++ * The following illustrate the layout and structure of the table we use.
++ * Watch out the "sizeof()", since most of the structures here are embedded with
++ * variable-length array.
++ *
++ *  0x0000  &table
++ *
++ *          < sizeof(*table) >
++ *          < sizeof(u32) * table->num >
++ *
++ *  0x0014  &hdr (&table->offset)
++ *
++ *          < sizeof(*hdr) >
++ *
++ *  0x0018  &vdev (&hdr->data)
++ *
++ *          < sizeof(*vdev) >
++ *
++ *  0x0030  &vdev->ring[0] (&hdr->data)
++ *
++ *          < sizeof(*vring) >
++ *
++ *  0x0044  &vdev->ring[1];
++ *
++ *         < sizeof(*vring) >
++ *  0x0058
++ */
++
++static struct resource_table *gen_rsc_table_cortex(int *tablesz)
++{
++	struct resource_table		*table;
++	struct fw_rsc_hdr		    *hdr;
++	struct fw_rsc_vdev		    *vdev;
++	struct fw_rsc_vdev_vring	*vring;
++
++	*tablesz		= sizeof(*table) + sizeof(u32) * 1
++				    + sizeof(*hdr) + sizeof(*vdev)
++				    + sizeof(*vring) * 2;
++
++	table			    = kzalloc((*tablesz), GFP_KERNEL);
++	table->ver		    = 1;
++	table->num		    = 1;
++	table->offset[0]    = sizeof(*table) + sizeof(u32) * table->num;
++
++	hdr			        = (void*)table + table->offset[0];
++	hdr->type		    = RSC_VDEV;
++	vdev			    = (void*)&hdr->data;
++	vdev->id		    = VIRTIO_ID_RPMSG;
++	vdev->notifyid	    = 124;
++	vdev->dfeatures	    = (1 << VIRTIO_RPMSG_F_NS);
++	vdev->config_len	= 0;
++	vdev->num_of_vrings	= 2;
++
++	vring			    = (void*)&vdev->vring[0];
++	vring->da		    = VRING_C0_TO_C1;
++	vring->align		= PAGE_SIZE;
++	vring->num		    = RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 111;
++
++	vring			    = (void*)&vdev->vring[1];
++	vring->da		    = VRING_C1_TO_C0;
++	vring->align		= PAGE_SIZE;
++	vring->num		    = RPMSG_NUM_BUFS >> 1;
++	vring->notifyid		= 112;
++
++	return table;
++}
++
++static struct ambarella_rproc_pdata pdata_cortex = {
++	.name			= "c0_and_c1",
++	.firmware		= "dummy",
++	.svq_tx_irq		= VRING_IRQ_C1_TO_C0_KICK,  //108
++	.svq_rx_irq		= VRING_IRQ_C0_TO_C1_ACK,   //107
++	.rvq_tx_irq		= VRING_IRQ_C1_TO_C0_ACK,   //109
++	.rvq_rx_irq		= VRING_IRQ_C0_TO_C1_KICK,  //106
++	.ops			= NULL,
++	.buf_addr_pa	= VRING_C0_AND_C1_BUF,
++	.gen_rsc_table	= gen_rsc_table_cortex,
++};
++
++struct platform_device ambarella_rproc_cortex_dev = {
++	.name			= "c0_and_c1",
++	.id			    = VIRTIO_ID_RPMSG,
++	.resource		= NULL,
++	.num_resources	= 0,
++	.dev			= {
++		.platform_data		= &pdata_cortex,
++		.dma_mask		    = &ambarella_dmamask,
++		.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++};
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index 022dc635..30072a83 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -206,7 +206,12 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
+ 	 * Allocate non-cacheable memory for the vring. In the future
+ 	 * this call will also configure the IOMMU for us
+ 	 */
++#if 0
+ 	va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
++#else
++	va = (void*)ambarella_phys_to_virt(rvring->da);
++	dma = rvring->da;
++#endif
+ 	if (!va) {
+ 		dev_err(dev->parent, "dma_alloc_coherent failed\n");
+ 		return -EINVAL;
+@@ -271,6 +276,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
+ 	rvring->len = vring->num;
+ 	rvring->align = vring->align;
+ 	rvring->rvdev = rvdev;
++	rvring->da = vring->da;
+ 
+ 	return 0;
+ }
+@@ -930,7 +936,8 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
+ 	ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler);
+ 
+ out:
+-	release_firmware(fw);
++	rproc_fw_release_firmware(rproc, fw);
++
+ 	/* allow rproc_del() contexts, if any, to proceed */
+ 	complete_all(&rproc->firmware_loading_complete);
+ }
+@@ -950,9 +957,13 @@ static int rproc_add_virtio_devices(struct rproc *rproc)
+ 	 * We're initiating an asynchronous firmware loading, so we can
+ 	 * be built-in kernel code, without hanging the boot process.
+ 	 */
++#if 1
++	ret = rproc_fw_request_firmware_nowait(rproc, rproc_fw_config_virtio);
++#else
+ 	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ 				      rproc->firmware, &rproc->dev, GFP_KERNEL,
+ 				      rproc, rproc_fw_config_virtio);
++#endif
+ 	if (ret < 0) {
+ 		dev_err(&rproc->dev, "request_firmware_nowait err: %d\n", ret);
+ 		complete_all(&rproc->firmware_loading_complete);
+@@ -1076,7 +1087,7 @@ int rproc_boot(struct rproc *rproc)
+ 	dev_info(dev, "powering up %s\n", rproc->name);
+ 
+ 	/* load firmware */
+-	ret = request_firmware(&firmware_p, rproc->firmware, dev);
++	ret = rproc_fw_request_firmware(rproc, &firmware_p);
+ 	if (ret < 0) {
+ 		dev_err(dev, "request_firmware failed: %d\n", ret);
+ 		goto downref_rproc;
+@@ -1084,7 +1095,7 @@ int rproc_boot(struct rproc *rproc)
+ 
+ 	ret = rproc_fw_boot(rproc, firmware_p);
+ 
+-	release_firmware(firmware_p);
++	rproc_fw_release_firmware(rproc, firmware_p);
+ 
+ downref_rproc:
+ 	if (ret) {
+diff --git a/drivers/remoteproc/remoteproc_dummy_loader.c b/drivers/remoteproc/remoteproc_dummy_loader.c
+new file mode 100644
+index 00000000..90c53aad
+--- /dev/null
++++ b/drivers/remoteproc/remoteproc_dummy_loader.c
+@@ -0,0 +1,81 @@
++/*
++ * Remote Processor Framework Elf loader
++ *
++ * Copyright (C) 2011 Texas Instruments, Inc.
++ * Copyright (C) 2011 Google, Inc.
++ *
++ * Ohad Ben-Cohen <ohad@wizery.com>
++ * Brian Swetland <swetland@google.com>
++ * Mark Grosen <mgrosen@ti.com>
++ * Fernando Guzman Lugo <fernando.lugo@ti.com>
++ * Suman Anna <s-anna@ti.com>
++ * Robert Tivy <rtivy@ti.com>
++ * Armando Uribe De Leon <x0095078@ti.com>
++ * Sjur Brændeland <sjur.brandeland@stericsson.com>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/firmware.h>
++#include <linux/remoteproc.h>
++#include <linux/slab.h>
++#include <linux/virtio_ids.h>
++
++#include <plat/remoteproc.h>
++
++#include "remoteproc_internal.h"
++
++static struct resource_table *
++rproc_dummy_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
++							int *tablesz)
++{
++	struct ambarella_rproc_pdata *pdata = rproc->priv;
++
++	return pdata->gen_rsc_table(tablesz);
++}
++
++static int rproc_dummy_load_segments(struct rproc *rproc,
++				     const struct firmware *fw)
++{
++	return 0;
++}
++
++static int rproc_dummy_request_firmware_nowait( struct module *module, bool uevent,
++	       const char *name, struct device *device, gfp_t gfp, void *context,
++	       void (*cont)(const struct firmware *fw, void *context))
++{
++	cont(NULL, context);
++
++	return 0;
++}
++
++static int rproc_dummy_request_firmware(const struct firmware **firmware_p,
++		const char *name, struct device *device)
++{
++	*firmware_p = kzalloc(sizeof(**firmware_p), GFP_KERNEL);
++
++	return 0;
++}
++
++static void rproc_dummy_release_firmware(const struct firmware *fw)
++{
++	kfree(fw);
++}
++
++const struct rproc_fw_ops rproc_dummy_fw_ops = {
++	.request_firmware		= rproc_dummy_request_firmware,
++	.request_firmware_nowait	= rproc_dummy_request_firmware_nowait,
++	.release_firmware		= rproc_dummy_release_firmware,
++	.load				= rproc_dummy_load_segments,
++	.find_rsc_table			= rproc_dummy_find_rsc_table,
++	.sanity_check			= NULL,
++	.get_boot_addr			= NULL
++};
+diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
+index ce283a5b..250dfc99 100644
+--- a/drivers/remoteproc/remoteproc_elf_loader.c
++++ b/drivers/remoteproc/remoteproc_elf_loader.c
+@@ -329,6 +329,10 @@ rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
+ }
+ 
+ const struct rproc_fw_ops rproc_elf_fw_ops = {
++	.request_firmware = request_firmware,
++	.get_boot_addr = rproc_elf_get_boot_addr,
++	.request_firmware_nowait = request_firmware_nowait,
++	.release_firmware = release_firmware,
+ 	.load = rproc_elf_load_segments,
+ 	.find_rsc_table = rproc_elf_find_rsc_table,
+ 	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
+index 157e762c..b5f9d09c 100644
+--- a/drivers/remoteproc/remoteproc_internal.h
++++ b/drivers/remoteproc/remoteproc_internal.h
+@@ -22,6 +22,7 @@
+ 
+ #include <linux/irqreturn.h>
+ #include <linux/firmware.h>
++#include <linux/module.h>
+ 
+ struct rproc;
+ 
+@@ -40,6 +41,12 @@ struct rproc_fw_ops {
+ 						int *tablesz);
+ 	struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc,
+ 						const struct firmware *fw);
++	int (*request_firmware)(const struct firmware **firmware_p,
++				const char *name, struct device *device);
++	int (*request_firmware_nowait)(struct module *module, bool uevent,
++		   const char *name, struct device *device, gfp_t gfp, void *context,
++		   void (*cont)(const struct firmware *fw, void *context));
++	void (*release_firmware)(const struct firmware *fw);
+ 	int (*load)(struct rproc *rproc, const struct firmware *fw);
+ 	int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
+ 	u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
+@@ -68,6 +75,38 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i);
+ void *rproc_da_to_va(struct rproc *rproc, u64 da, int len);
+ int rproc_trigger_recovery(struct rproc *rproc);
+ 
++static inline
++int rproc_fw_request_firmware(struct rproc *rproc, const struct firmware **fw)
++{
++	if (rproc->fw_ops->request_firmware)
++		return rproc->fw_ops->request_firmware(fw,
++						       rproc->firmware,
++						       &rproc->dev);
++
++	return 0;
++}
++
++static inline
++int rproc_fw_request_firmware_nowait(struct rproc *rproc,
++		     void (*cont)(const struct firmware *fw, void *context))
++{
++	if (rproc->fw_ops->request_firmware_nowait) {
++		return rproc->fw_ops->request_firmware_nowait(THIS_MODULE,
++					  FW_ACTION_HOTPLUG, rproc->firmware,
++					  &rproc->dev, GFP_KERNEL, rproc,
++					  cont);
++	}
++
++	return 0;
++}
++
++static inline
++void rproc_fw_release_firmware(struct rproc *rproc, const struct firmware *fw)
++{
++	if (rproc->fw_ops->release_firmware)
++		rproc->fw_ops->release_firmware(fw);
++}
++
+ static inline
+ int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
+ {
+diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
+index 69a21938..93205bd6 100644
+--- a/drivers/rpmsg/Kconfig
++++ b/drivers/rpmsg/Kconfig
+@@ -6,4 +6,11 @@ config RPMSG
+ 	select VIRTIO
+ 	select VIRTUALIZATION
+ 
++config RPMSG_TX_SPINLOCK
++	bool "Support non-blocking TX in interrupt context"
++	default y
++	depends on RPMSG
++
++source "drivers/rpmsg/ambarella/Kconfig"
++
+ endmenu
+diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
+index 7617fcb8..a6e02158 100644
+--- a/drivers/rpmsg/Makefile
++++ b/drivers/rpmsg/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_RPMSG)	+= virtio_rpmsg_bus.o
++obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC)	+= ambarella/
+diff --git a/drivers/rpmsg/ambarella/Kconfig b/drivers/rpmsg/ambarella/Kconfig
+new file mode 100644
+index 00000000..47f518db
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/Kconfig
+@@ -0,0 +1,24 @@
++menu "RPMSG Host Programs"
++depends on RPROC_SUPPORT
++source "drivers/rpmsg/ambarella/host/ambxc/Kconfig"
++source "drivers/rpmsg/ambarella/host/aservice/Kconfig"
++source "drivers/rpmsg/ambarella/host/echo/Kconfig"
++source "drivers/rpmsg/ambarella/host/rsh/Kconfig"
++source "drivers/rpmsg/ambarella/host/veth/Kconfig"
++source "drivers/rpmsg/ambarella/host/wnfs/Kconfig"
++source "drivers/rpmsg/ambarella/host/rnfs/Kconfig"
++source "drivers/rpmsg/ambarella/host/vgpio/Kconfig"
++
++endmenu
++
++menu "RPMSG Client Programs"
++depends on RPCLNT_SUPPORT
++
++source "drivers/rpmsg/ambarella/clnt/rsh/Kconfig"
++source "drivers/rpmsg/ambarella/clnt/echo/Kconfig"
++source "drivers/rpmsg/ambarella/clnt/veth/Kconfig"
++
++endmenu
++
++source "drivers/rpmsg/ambarella/common/rsh/Kconfig"
++source "drivers/rpmsg/ambarella/common/veth/Kconfig"
+diff --git a/drivers/rpmsg/ambarella/Makefile b/drivers/rpmsg/ambarella/Makefile
+new file mode 100644
+index 00000000..023530aa
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/Makefile
+@@ -0,0 +1,15 @@
++obj-$(CONFIG_RPROC_SUPPORT) += host/ambxc/
++obj-$(CONFIG_RPROC_SUPPORT) += host/aservice/
++obj-$(CONFIG_RPROC_SUPPORT) += host/rsh/
++obj-$(CONFIG_RPROC_SUPPORT) += host/echo/
++obj-$(CONFIG_RPROC_SUPPORT) += host/veth/
++obj-$(CONFIG_RPROC_SUPPORT) += host/wnfs/
++obj-$(CONFIG_RPROC_SUPPORT) += host/rnfs/
++obj-$(CONFIG_RPROC_SUPPORT) += host/vgpio/
++
++obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/rsh/
++obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/echo/
++obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/veth/
++
++obj-y += common/rsh/
++obj-y += common/veth/
+diff --git a/drivers/rpmsg/ambarella/clnt/echo/Kconfig b/drivers/rpmsg/ambarella/clnt/echo/Kconfig
+new file mode 100644
+index 00000000..8df1983b
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/echo/Kconfig
+@@ -0,0 +1,4 @@
++config RPDEV_ECHO
++	tristate "Echo"
++	help
++	  A sample of rpmsg program which implement an "echo client".
+diff --git a/drivers/rpmsg/ambarella/clnt/echo/Makefile b/drivers/rpmsg/ambarella/clnt/echo/Makefile
+new file mode 100644
+index 00000000..c91826f4
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/echo/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPDEV_ECHO)	+= rpdev_echo.o
+diff --git a/drivers/rpmsg/ambarella/clnt/echo/rpdev_echo.c b/drivers/rpmsg/ambarella/clnt/echo/rpdev_echo.c
+new file mode 100644
+index 00000000..9a021986
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/echo/rpdev_echo.c
+@@ -0,0 +1,77 @@
++/**
++ * History:
++ *    2012/07/30 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/rpmsg.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/remoteproc.h>
++
++#include <plat/rpdev.h>
++
++static void rpdev_echo_cb(struct rpdev *rpdev, void *data, int len,
++				 void *priv, u32 src)
++{
++	printk("[ %20s ] recv message: [%s]\n", __func__, (char *)data);
++}
++
++static void rpdev_echo_init_work(struct work_struct *work)
++{
++	struct rpdev *rpdev;
++	char *str = "Hello from CA9-B";
++	char buf[64];
++	int i;
++
++	rpdev = rpdev_alloc("echo_ca9_b", 0, rpdev_echo_cb, NULL);
++
++	rpdev_register(rpdev, "ca9_a_and_b");
++
++	printk("[ %20s ] send message: [%s]\n", __func__, str);
++
++	for (i = 0; i < 512; i++) {
++		sprintf(buf, "%s  %d", str, i);
++		printk("try sending: %s   OK\n", buf);
++		while (rpdev_trysend(rpdev, buf, strlen(buf) + 1) != 0) {
++			printk("retry sending: %s\n", buf);
++			msleep(10);
++		}
++	}
++
++	for (i = 0; i < 512; i++) {
++		sprintf(buf, "%s %d (wait)", str, i);
++		printk("sending: %s   OK\n", buf);
++		rpdev_send(rpdev, buf, strlen(buf) + 1);
++	}
++}
++
++static struct work_struct work;
++
++static int rpdev_echo_init(void)
++{
++	INIT_WORK(&work, rpdev_echo_init_work);
++	schedule_work(&work);
++	return 0;
++}
++
++static void rpdev_echo_fini(void)
++{
++}
++
++module_init(rpdev_echo_init);
++module_exit(rpdev_echo_fini);
+diff --git a/drivers/rpmsg/ambarella/clnt/rsh/Kconfig b/drivers/rpmsg/ambarella/clnt/rsh/Kconfig
+new file mode 100644
+index 00000000..4be32a86
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/rsh/Kconfig
+@@ -0,0 +1,6 @@
++config RPDEV_RSH
++	tristate "Remote Shell"
++	select AMBARELLA_RSH
++	help
++	  A Remote shell server for CA9-B to accept remote
++	  connection from CA9-A
+diff --git a/drivers/rpmsg/ambarella/clnt/rsh/Makefile b/drivers/rpmsg/ambarella/clnt/rsh/Makefile
+new file mode 100644
+index 00000000..9045f8ec
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/rsh/Makefile
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_RPDEV_RSH)	+= rpdev_rsh.o
++
+diff --git a/drivers/rpmsg/ambarella/clnt/rsh/rpdev_rsh.c b/drivers/rpmsg/ambarella/clnt/rsh/rpdev_rsh.c
+new file mode 100644
+index 00000000..cfeb8632
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/rsh/rpdev_rsh.c
+@@ -0,0 +1,75 @@
++/**
++ * History:
++ *    2012/09/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/remoteproc.h>
++
++#include <plat/rpdev.h>
++
++extern int rsh_init_driver(void);
++extern int rsh_init_device(int index, void *rpdev);
++
++extern void rsh_cb(int index, void *data, int len);
++
++int do_rsh_write(void *rpdev, const unsigned char *buf, int count)
++{
++	while (rpdev_trysend(rpdev, (char*)buf, count))
++		;
++
++	return count;
++}
++
++static void rpdev_rsh_cb(struct rpdev *rpdev, void *data, int len,
++			 void *priv, u32 src)
++{
++	rsh_cb((int)priv, data, len);
++}
++
++static void rpdev_rsh_init_work(struct work_struct *work)
++{
++	struct rpdev *rpdev;
++	int index = 0;
++
++	rpdev = rpdev_alloc("rsh_ca9_b", 0, rpdev_rsh_cb, NULL);
++
++	rsh_init_driver();
++	rpdev->priv = (void*)index;
++
++	rpdev_register(rpdev, "ca9_a_and_b");
++
++	rsh_init_device(index, rpdev);
++}
++
++static struct work_struct work;
++
++static int rpdev_rsh_init(void)
++{
++	INIT_WORK(&work, rpdev_rsh_init_work);
++	schedule_work(&work);
++
++        return 0;
++}
++
++static void rpdev_rsh_fini(void)
++{
++}
++
++module_init(rpdev_rsh_init);
++module_exit(rpdev_rsh_fini);
++
++MODULE_DESCRIPTION("RPMSG Remote Shell");
+diff --git a/drivers/rpmsg/ambarella/clnt/veth/Kconfig b/drivers/rpmsg/ambarella/clnt/veth/Kconfig
+new file mode 100644
+index 00000000..37930a41
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/veth/Kconfig
+@@ -0,0 +1,5 @@
++config RPDEV_VETH
++	tristate "Virtual Ethernet"
++	select AMBARELLA_VETH
++	help
++	  A virtualized ethernet device over RPMSG bus.
+diff --git a/drivers/rpmsg/ambarella/clnt/veth/Makefile b/drivers/rpmsg/ambarella/clnt/veth/Makefile
+new file mode 100644
+index 00000000..1bcbdc7d
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/veth/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPDEV_VETH)	+= rpdev_veth.o
+diff --git a/drivers/rpmsg/ambarella/clnt/veth/rpdev_veth.c b/drivers/rpmsg/ambarella/clnt/veth/rpdev_veth.c
+new file mode 100644
+index 00000000..d99f888b
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/clnt/veth/rpdev_veth.c
+@@ -0,0 +1,50 @@
++#include <plat/rpdev.h>
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++extern struct platform_device ambveth_device;
++extern void ambveth_enqueue(void *priv, void *data, int len);
++
++struct rpdev *g_rpdev;
++
++int ambveth_do_send(void *data, int len)
++{
++	return rpdev_trysend(g_rpdev, data, len);
++}
++
++static void rpdev_veth_client_cb(struct rpdev *rpdev, void *data, int len,
++				 void *priv, u32 src)
++{
++	ambveth_enqueue(priv, data, len);
++}
++
++static void rpdev_veth_client_init_work(struct work_struct *work)
++{
++	struct rpdev *rpdev;
++
++	platform_device_register(&ambveth_device);
++
++	rpdev = rpdev_alloc("veth_ca9_b", 0, rpdev_veth_client_cb, &ambveth_device);
++
++	rpdev_register(rpdev, "ca9_a_and_b");
++	g_rpdev = rpdev;
++}
++
++static struct work_struct work;
++
++static int rpdev_veth_client_init(void)
++{
++	INIT_WORK(&work, rpdev_veth_client_init_work);
++	schedule_work(&work);
++	return 0;
++}
++
++static void rpdev_veth_client_fini(void)
++{
++}
++
++module_init(rpdev_veth_client_init);
++module_exit(rpdev_veth_client_fini);
++
++MODULE_DESCRIPTION("RPMSG VETH");
+diff --git a/drivers/rpmsg/ambarella/common/rsh/Kconfig b/drivers/rpmsg/ambarella/common/rsh/Kconfig
+new file mode 100644
+index 00000000..c24abd26
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/common/rsh/Kconfig
+@@ -0,0 +1,4 @@
++config AMBARELLA_RSH
++	bool
++	default n
++	depends on RPDEV_RSH || RPMSG_RSH
+diff --git a/drivers/rpmsg/ambarella/common/rsh/Makefile b/drivers/rpmsg/ambarella/common/rsh/Makefile
+new file mode 100644
+index 00000000..553391aa
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/common/rsh/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_AMBARELLA_RSH)	+= rsh.o
+diff --git a/drivers/rpmsg/ambarella/common/rsh/rsh.c b/drivers/rpmsg/ambarella/common/rsh/rsh.c
+new file mode 100644
+index 00000000..54cc5f27
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/common/rsh/rsh.c
+@@ -0,0 +1,160 @@
++#include <linux/err.h>
++#include <linux/kfifo.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++
++extern int do_rsh_write(void *rpdev,
++			const unsigned char *buf,
++			int count);
++
++struct rsh_struct
++{
++	struct tty_port		port;
++	struct timer_list	timer;
++	struct kfifo		fifo;
++	void 			*rpdev;
++
++	spinlock_t		lock;
++};
++
++static struct rsh_struct g_rsh[3];
++static struct tty_driver *g_driver;
++
++void rsh_cb(int index, void *data, int len)
++{
++	struct rsh_struct *rsh = &g_rsh[index];
++
++	kfifo_in_locked(&rsh->fifo, (char *)data, len, &rsh->lock);
++}
++
++static void rsh_receive_chars(unsigned long data)
++{
++	struct rsh_struct *rsh = (struct rsh_struct *)data;
++	struct tty_port *port = &rsh->port;
++	char c;
++
++	while (kfifo_out_locked(&rsh->fifo, &c, sizeof(c), &rsh->lock))
++		tty_insert_flip_char(port, c, 0);
++
++	tty_schedule_flip(port);
++
++	spin_lock(&port->lock);
++	if (port->tty)
++		mod_timer(&rsh->timer, jiffies + 50);
++	spin_unlock(&port->lock);
++}
++
++static int rsh_write(struct tty_struct *tty, const unsigned char *buf,
++		     int count)
++{
++	struct rsh_struct *rsh = &g_rsh[tty->index];
++
++	return do_rsh_write(rsh->rpdev, buf, count);
++}
++
++static int rsh_write_room(struct tty_struct *tty)
++{
++	return INT_MAX;
++}
++
++static int rsh_chars_in_buffer(struct tty_struct *tty)
++{
++	return 0;
++}
++
++static int rsh_open(struct tty_struct *tty, struct file *filp)
++{
++	struct rsh_struct *rsh = &g_rsh[tty->index];
++	struct tty_port *port = &rsh->port;
++
++	if (!port->tty) {
++		tty->driver_data = rsh;
++		tty->port = port;
++		port->tty = tty;
++		mod_timer(&rsh->timer, jiffies + 10);
++	}
++
++	return 0;
++}
++
++static void rsh_close(struct tty_struct *tty, struct file *filp)
++{
++	struct rsh_struct *rsh = &g_rsh[tty->index];
++	struct tty_port *port = &rsh->port;
++
++	if (tty->count == 1) {
++		port->tty = NULL;
++		del_timer(&rsh->timer);
++	}
++}
++
++static const struct tty_operations rsh_ops =
++{
++	.open			= rsh_open,
++	.close			= rsh_close,
++	.write			= rsh_write,
++	.write_room		= rsh_write_room,
++	.chars_in_buffer	= rsh_chars_in_buffer,
++};
++
++extern int rsh_init_device(int index, void *rpdev)
++{
++	struct rsh_struct *rsh = &g_rsh[index];
++	struct tty_port *port;
++	int ret;
++	const char *name[3] = {
++		"CA9-A <-> CA9-B",
++		"CA9-A <-> ARM11",
++		"CA9-B <-> ARM11",
++	};
++
++	rsh = &g_rsh[index];
++	rsh->rpdev = rpdev;
++	port = &rsh->port;
++
++	tty_port_init(port);
++
++	setup_timer(&rsh->timer, rsh_receive_chars, (unsigned long)rsh);
++
++	spin_lock_init(&rsh->lock);
++
++        ret = kfifo_alloc(&rsh->fifo, 1024 * 64, GFP_KERNEL);
++        if (ret)
++                return ret;
++
++        tty_port_register_device(port, g_driver, index, NULL);
++
++	printk("RPMSG: Remote Shell /dev/ttyRSH%d (%s)\n", index, name[index]);
++
++	return 0;
++}
++
++int rsh_init_driver(void)
++{
++	struct tty_driver *driver;
++	int ret;
++
++	driver = tty_alloc_driver(3, 0);
++	if (!driver)
++		return -ENOMEM;
++
++	driver->driver_name	= "ttyRSH";
++	driver->name		= "ttyRSH";
++	driver->major		= 0;
++	driver->minor_start	= 0;
++	driver->type		= TTY_DRIVER_TYPE_SYSTEM;
++	driver->subtype		= SYSTEM_TYPE_SYSCONS;
++	driver->init_termios	= tty_std_termios;
++	driver->flags		= TTY_DRIVER_DYNAMIC_DEV;
++
++	tty_set_operations(driver, &rsh_ops);
++	ret = tty_register_driver(driver);
++	if (ret) {
++		put_tty_driver(driver);
++		return ret;
++	}
++
++	g_driver = driver;
++
++	return 0;
++}
+diff --git a/drivers/rpmsg/ambarella/common/veth/Kconfig b/drivers/rpmsg/ambarella/common/veth/Kconfig
+new file mode 100644
+index 00000000..52ca6906
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/common/veth/Kconfig
+@@ -0,0 +1,4 @@
++config AMBARELLA_VETH
++	bool
++	default n
++	depends on RPDEV_VETH || RPMSG_VETH
+diff --git a/drivers/rpmsg/ambarella/common/veth/Makefile b/drivers/rpmsg/ambarella/common/veth/Makefile
+new file mode 100644
+index 00000000..e5d33873
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/common/veth/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_AMBARELLA_VETH)	+= veth.o
+diff --git a/drivers/rpmsg/ambarella/common/veth/veth.c b/drivers/rpmsg/ambarella/common/veth/veth.c
+new file mode 100644
+index 00000000..a7c2125e
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/common/veth/veth.c
+@@ -0,0 +1,237 @@
++/*
++ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
++ * Copyright (C) 2012-2013, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/err.h>
++
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/spinlock.h>
++#include <linux/time.h>
++#include <linux/crc16.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/rpmsg.h>
++
++#include <plat/ambcache.h>
++
++#define MIN_MTU 68
++#define MAX_MTU (4096 - ETH_HLEN - sizeof(struct rpmsg_hdr))
++#define DEF_MTU MAX_MTU
++
++extern int ambveth_do_send(void *data, int len);
++
++struct ambveth
++{
++	spinlock_t		lock;
++
++	struct net_device_stats	stats;
++	struct net_device	*ndev;
++};
++
++void ambveth_enqueue(void *priv, void *data, int len)
++{
++	struct ambveth		*lp;
++	struct sk_buff		*skb;
++
++	lp = ((struct platform_device*)priv)->dev.platform_data;
++
++	skb = dev_alloc_skb(len + NET_IP_ALIGN);
++	if (!skb) {
++		lp->stats.rx_dropped++;
++		return;
++	}
++	skb_put(skb, len);
++
++	memcpy(skb->data, data, len);
++
++	lp->stats.rx_packets++;
++	lp->stats.rx_bytes += len;
++
++	skb->dev = lp->ndev;
++	skb->protocol = eth_type_trans(skb, skb->dev);
++
++	netif_rx_ni(skb);
++}
++
++static int ambveth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++	struct ambveth		*lp;
++	int			ret;
++
++	lp = netdev_priv(ndev);
++
++	ret = ambveth_do_send(skb->data, skb->len);
++	if (ret) {
++	    lp->stats.tx_dropped++;
++
++	    return NETDEV_TX_BUSY;
++	}
++
++	lp->stats.tx_packets++;
++	lp->stats.tx_bytes += skb->len;
++
++	dev_kfree_skb(skb);
++
++	return NETDEV_TX_OK;
++}
++
++static int ambveth_open(struct net_device *ndev)
++{
++	struct ambveth	*lp;
++
++	lp = netdev_priv(ndev);
++
++	netif_start_queue(ndev);
++
++	return 0;
++}
++
++static int ambveth_stop(struct net_device *ndev)
++{
++	struct ambveth	*lp;
++
++	lp = netdev_priv(ndev);
++
++	netif_stop_queue(ndev);
++	flush_scheduled_work();
++
++	return 0;
++}
++
++static void ambveth_timeout(struct net_device *ndev)
++{
++	netif_wake_queue(ndev);
++}
++
++static struct net_device_stats *ambveth_get_stats(struct net_device *ndev)
++{
++	struct ambveth *lp;
++
++	lp = netdev_priv(ndev);
++
++	return &lp->stats;
++}
++
++static int ambveth_change_mtu(struct net_device *dev, int mtu)
++{
++	if (mtu < MIN_MTU || mtu + dev->hard_header_len > MAX_MTU)
++
++		return -EINVAL;
++
++	dev->mtu = mtu;
++
++	return 0;
++}
++
++static int ambveth_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
++{
++	int		ret = 0;
++
++	if (!netif_running(ndev)) {
++		ret = -EINVAL;
++		goto ambveth_get_settings_exit;
++	}
++
++ambveth_get_settings_exit:
++	return ret;
++}
++
++/* ==========================================================================*/
++static const struct net_device_ops ambveth_netdev_ops = {
++	.ndo_open		= ambveth_open,
++	.ndo_stop		= ambveth_stop,
++	.ndo_start_xmit		= ambveth_start_xmit,
++	.ndo_set_mac_address 	= eth_mac_addr,
++	.ndo_validate_addr	= eth_validate_addr,
++	.ndo_do_ioctl		= ambveth_ioctl,
++	.ndo_tx_timeout		= ambveth_timeout,
++	.ndo_get_stats		= ambveth_get_stats,
++	.ndo_change_mtu		= ambveth_change_mtu,
++};
++
++struct platform_device ambveth_device = {
++	.name		= "ambveth",
++	.id		= 0,
++	.resource	= NULL,
++	.num_resources	= 0,
++	.dev		= {
++		.platform_data		= NULL,
++	}
++};
++
++static int ambveth_drv_probe(struct platform_device *pdev)
++{
++	int			ret = 0;
++	struct net_device	*ndev;
++	struct ambveth		*lp;
++	char			mac_addr[6];
++
++	ndev = alloc_etherdev(sizeof(struct ambveth));
++	if (!ndev)
++		ret = -ENOMEM;
++	SET_NETDEV_DEV(ndev, &pdev->dev);
++
++	lp = netdev_priv(ndev);
++	lp->ndev = ndev;
++	spin_lock_init(&lp->lock);
++	pdev->dev.platform_data = lp;
++
++	ndev->netdev_ops = &ambveth_netdev_ops;
++	ndev->mtu = DEF_MTU;
++	sprintf(ndev->name, "veth0");
++
++	if (!is_valid_ether_addr(mac_addr))
++		random_ether_addr(mac_addr);
++
++	memcpy(ndev->dev_addr, mac_addr, 6);
++
++	ret = register_netdev(ndev);
++	if (ret)
++		dev_err(&pdev->dev, " register_netdev fail%d.\n", ret);
++
++	return ret;
++}
++
++static struct platform_driver ambveth_driver = {
++	.probe		= ambveth_drv_probe,
++	.driver = {
++		.name	= "ambveth",
++		.owner	= THIS_MODULE,
++	},
++};
++
++static int __init ambveth_init(void)
++{
++	return platform_driver_register(&ambveth_driver);
++}
++
++static void __exit ambveth_fini(void)
++{
++}
++
++module_init(ambveth_init);
++module_exit(ambveth_fini);
++
++MODULE_DESCRIPTION("Ambarella veth driver");
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/Kconfig b/drivers/rpmsg/ambarella/host/ambxc/Kconfig
+new file mode 100644
+index 00000000..f3940fba
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/Kconfig
+@@ -0,0 +1,11 @@
++config RPMSG_AMBXC
++	tristate "Ambarella A8 Codec driver"
++	depends on RPMSG
++	select VIDEO_V4L2
++	select V4L2_MEM2MEM_DEV
++	select VIDEOBUF2_CORE
++	select VIDEOBUF2_MEMOPS
++	select VIDEOBUF2_VMALLOC
++	default n
++	---help---
++	  V4L2 Display driver support for Ambarella A8.
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/Makefile b/drivers/rpmsg/ambarella/host/ambxc/Makefile
+new file mode 100644
+index 00000000..448c987e
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/Makefile
+@@ -0,0 +1,12 @@
++#
++# Makefile for the ambarella video device drivers.
++#
++
++# Ambarella A8 CODEC driver
++rpmsg_ambxc-y +=	ambxc_vdev.o \
++			ambxc_ioctl.o \
++			ambxc_ctrls.o \
++			ambxc_ctl.o \
++			ambxc_rpmsg.o
++
++obj-$(CONFIG_RPMSG_AMBXC) += rpmsg_ambxc.o
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc.h b/drivers/rpmsg/ambarella/host/ambxc/ambxc.h
+new file mode 100644
+index 00000000..312d5a03
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc.h
+@@ -0,0 +1,80 @@
++#ifndef __AMBXC_H__
++#define __AMBXC_H__
++
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/kthread.h>
++
++#include <media/v4l2-device.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-ctrls.h>
++#include <media/videobuf2-vmalloc.h>
++
++#define AMBXC_NAME		"ambxc"
++
++#define MEM2MEM_DEF_NUM_BUFS	VIDEO_MAX_FRAME
++#define MEM2MEM_VID_MEM_LIMIT	(16 * 1024 * 1024)
++
++#define dprintk(dev, fmt, arg...) \
++	v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
++
++#define BUF_SIZE (0x80000)
++
++struct ambxc_fmt {
++	char	*name;
++	u32	fourcc;
++	u32	types;
++	int	field;
++};
++
++#define NUM_FORMATS ARRAY_SIZE(formats)
++
++/* Per-queue, driver-specific private data */
++struct ambxc_q_data {
++	unsigned int		width;
++	unsigned int		height;
++	unsigned int		sizeimage;
++	struct ambxc_fmt	*fmt;
++};
++
++enum {
++	V4L2_M2M_SRC = 0,
++	V4L2_M2M_DST = 1,
++};
++
++struct ambxc_dev {
++	struct v4l2_device	v4l2_dev;
++	struct video_device	*vfd;
++
++	atomic_t		inst;
++	atomic_t		ref_cnt;
++	struct ambxc_ctx	*ctx;
++	struct mutex		dev_mutex;
++	spinlock_t		irqlock;
++	struct task_struct	*kthread_capture;
++	struct task_struct	*kthread_feed;
++	wait_queue_head_t	queue_capture;
++	wait_queue_head_t	queue_feed;
++
++	struct v4l2_m2m_dev	*m2m_dev;
++};
++
++struct ambxc_ctx {
++	struct v4l2_fh		fh;
++	struct ambxc_dev	*dev;
++
++	struct v4l2_ctrl_handler hdl;
++	struct v4l2_ctrl *ctrls[128];
++
++	struct v4l2_m2m_ctx	*m2m_ctx;
++
++	/* Source and destination queue data */
++	struct ambxc_q_data	q_data[2];
++};
++
++static inline struct ambxc_ctx* file2ctx(struct file *file)
++{
++	return container_of(file->private_data, struct ambxc_ctx, fh);
++}
++
++#endif /* __AMBXC_H__ */
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctl.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctl.c
+new file mode 100644
+index 00000000..d5320aa4
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctl.c
+@@ -0,0 +1,75 @@
++/**
++ * History:
++ *    2012/09/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/tty.h>
++#include <linux/remoteproc.h>
++#include <linux/rpmsg.h>
++
++static struct rpmsg_channel *rpdev_ambxc_ctl;
++
++int ambxc_ctl_send(const char *buf, int count)
++{
++	struct rpmsg_channel *rpdev = rpdev_ambxc_ctl;
++
++	while (rpmsg_trysend(rpdev, (char*)buf, count))
++		;
++
++	return count;
++}
++
++static void rpmsg_ambxc_ctl_cb(struct rpmsg_channel *rpdev, void *data,
++				int len, void *priv, u32 src)
++{
++	//ambxc_ctl_cb((int)priv, data, len);
++}
++
++static int rpmsg_ambxc_ctl_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++	int index;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	rpdev->ept->priv = (void*)index;
++	rpdev_ambxc_ctl = rpdev;
++	rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
++
++	return ret;
++}
++
++static void rpmsg_ambxc_ctl_remove(struct rpmsg_channel *rpdev)
++{
++}
++
++static struct rpmsg_device_id rpmsg_ambxc_ctl_id_table[] = {
++	{ .name	= "ambxc_ctl_arm11", }, /* H: CA9-A, C: ARM11 */
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_ambxc_ctl_id_table);
++
++struct rpmsg_driver rpmsg_ambxc_ctl_driver =
++{
++	.drv.name	= "rpmsg_ambxc_ctl",
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_ambxc_ctl_id_table,
++	.probe		= rpmsg_ambxc_ctl_probe,
++	.callback	= rpmsg_ambxc_ctl_cb,
++	.remove		= rpmsg_ambxc_ctl_remove,
++};
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.c
+new file mode 100644
+index 00000000..e50e62cc
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.c
+@@ -0,0 +1,551 @@
++#include <media/v4l2-device.h>
++#include <media/v4l2-ioctl.h>
++#include <media/videobuf2-vmalloc.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ambxc.h"
++#include "ambxc_ctrls.h"
++
++#define IS_AMBXC_PRIV(x) ((V4L2_CTRL_ID2CLASS(x) == V4L2_CTRL_CLASS_MPEG) \
++						&& V4L2_CTRL_DRIVER_PRIV(x))
++
++struct ambxc_control {
++	__u32			id;
++	enum v4l2_ctrl_type	type;
++	__u8			name[32];  /* Whatever */
++	__s32			minimum;   /* Note signedness */
++	__s32			maximum;
++	__s32			step;
++	__u32			menu_skip_mask;
++	__s32			default_value;
++	__u32			flags;
++	__u32			reserved[2];
++	__u8			is_volatile;
++};
++
++static struct ambxc_control controls[] = {
++	{
++		.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
++		.maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
++		.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 1,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 1900,
++		.maximum = (1 << 30) - 1,
++		.step = 1,
++		.default_value = 1900,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
++		.type = V4L2_CTRL_TYPE_BOOLEAN,
++		.minimum = 0,
++		.maximum = 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_BITRATE,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 1,
++		.maximum = (1 << 30) - 1,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_VBV_SIZE,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
++		.maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
++		.default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = 2,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
++		.maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
++		.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
++		.menu_skip_mask = ~(
++				    (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
++				    (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
++				    (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
++				    ),
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
++		.maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
++		.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
++		.maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
++		.default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
++		.maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,
++		.default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = -6,
++		.maximum = 6,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = -6,
++		.maximum = 6,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
++		.maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
++		.default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
++		.type = V4L2_CTRL_TYPE_BOOLEAN,
++		.minimum = 0,
++		.maximum = 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
++		.type = V4L2_CTRL_TYPE_BOOLEAN,
++		.minimum = 0,
++		.maximum = 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = 51,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = 51,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = 51,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = 51,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = 51,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.name = "MPEG4 I-Frame QP value",
++		.minimum = 1,
++		.maximum = 31,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.name = "MPEG4 Minimum QP value",
++		.minimum = 1,
++		.maximum = 31,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.name = "MPEG4 Maximum QP value",
++		.minimum = 0,
++		.maximum = 51,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.name = "MPEG4 P frame QP value",
++		.minimum = 1,
++		.maximum = 31,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.name = "MPEG4 B frame QP value",
++		.minimum = 1,
++		.maximum = 31,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
++		.type = V4L2_CTRL_TYPE_BOOLEAN,
++		.minimum = 0,
++		.maximum = 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
++		.maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
++		.default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
++		.type = V4L2_CTRL_TYPE_BOOLEAN,
++		.minimum = 0,
++		.maximum = 1,
++		.step = 1,
++		.default_value = 1,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
++		.type = V4L2_CTRL_TYPE_INTEGER,
++		.minimum = 0,
++		.maximum = (1 << 16) - 1,
++		.step = 1,
++		.default_value = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
++		.type = V4L2_CTRL_TYPE_MENU,
++		.minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
++		.maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE,
++		.default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
++		.menu_skip_mask = 0,
++	},
++	{
++		.id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
++		.type = V4L2_CTRL_TYPE_BOOLEAN,
++		.minimum = 0,
++		.maximum = 1,
++		.step = 1,
++		.default_value = 0,
++	},
++};
++
++#define NUM_CTRLS ARRAY_SIZE(controls)
++
++/* Set controls - v4l2 control framework */
++static int ambxc_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++	struct ambxc_ctx *ctx;
++	struct ambxc_dev *dev;
++	int ret = 0;
++
++	ctx = container_of(ctrl->handler, struct ambxc_ctx, hdl);
++	dev = ctx->dev;
++
++	switch (ctrl->id) {
++	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
++		break;
++	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
++		break;
++	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_BITRATE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
++		switch (ctrl->val) {
++		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
++			break;
++		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
++			break;
++		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
++			break;
++		case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
++			break;
++		default:
++			ret = -EINVAL;
++		}
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
++	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
++	case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
++	case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
++	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
++	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
++		break;
++	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
++		break;
++	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
++		switch (ctrl->val) {
++		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
++			break;
++		case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
++			break;
++		default:
++			ret = -EINVAL;
++		}
++		break;
++	case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
++		break;
++	default:
++		v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",
++							ctrl->id, ctrl->val);
++		ret = -EINVAL;
++	}
++	return ret;
++}
++
++static int ambxc_g_v_ctrl(struct v4l2_ctrl *ctrl)
++{
++	struct ambxc_ctx *ctx;
++	struct ambxc_dev *dev;
++
++	ctx = container_of(ctrl->handler, struct ambxc_ctx, hdl);
++	dev = ctx->dev;
++
++	switch (ctrl->id) {
++	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++		break;
++	}
++
++	return 0;
++}
++
++static const struct v4l2_ctrl_ops ambxc_ctrl_ops = {
++	.s_ctrl = ambxc_s_ctrl,
++	.g_volatile_ctrl = ambxc_g_v_ctrl,
++};
++
++int ambxc_init_ctrls(struct ambxc_ctx *ctx)
++{
++	struct ambxc_dev *dev = ctx->dev;
++	struct v4l2_ctrl_config cfg;
++	struct ambxc_control *ctrl;
++	int i;
++
++	v4l2_ctrl_handler_init(&ctx->hdl, NUM_CTRLS);
++	if (ctx->hdl.error) {
++		dprintk(dev, "v4l2_ctrl_handler_init failed\n");
++		return ctx->hdl.error;
++	}
++
++	for (i = 0; i < NUM_CTRLS; i++) {
++
++		ctrl = &controls[i];
++
++		if (IS_AMBXC_PRIV(ctrl->id)) {
++
++			memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
++			cfg.ops = &ambxc_ctrl_ops;
++			cfg.id = ctrl->id;
++			cfg.min = ctrl->minimum;
++			cfg.max = ctrl->maximum;
++			cfg.def = ctrl->default_value;
++			cfg.name = ctrl->name;
++			cfg.type = ctrl->type;
++
++			cfg.step = ctrl->step;
++			cfg.menu_skip_mask = 0;
++
++			ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->hdl,
++							     &cfg, NULL);
++		}
++		else {
++			if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
++				ctx->ctrls[i] = v4l2_ctrl_new_std_menu(
++					&ctx->hdl,
++					&ambxc_ctrl_ops, ctrl->id,
++					ctrl->maximum, 0,
++					ctrl->default_value);
++			}
++			else {
++				ctx->ctrls[i] = v4l2_ctrl_new_std(
++					&ctx->hdl,
++					&ambxc_ctrl_ops, ctrl->id,
++					ctrl->minimum,
++					ctrl->maximum, ctrl->step,
++					ctrl->default_value);
++			}
++		}
++		if (ctx->hdl.error) {
++			dprintk(dev, "Adding control (%d) failed\n", i);
++			return ctx->hdl.error;
++		}
++		if (ctrl->is_volatile && ctx->ctrls[i])
++		    ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
++	}
++
++	v4l2_ctrl_handler_setup(&ctx->hdl);
++
++	return 0;
++}
++
++void ambxc_release_ctrls(struct ambxc_ctx *ctx)
++{
++	v4l2_ctrl_handler_free(&ctx->hdl);
++}
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.h b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.h
+new file mode 100644
+index 00000000..9657575a
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.h
+@@ -0,0 +1,8 @@
++#ifndef __AMBXC_CTRLS_H__
++#define __AMBXC_CTRLS_H__
++
++extern int ambxc_init_ctrls(struct ambxc_ctx *ctx);
++extern void ambxc_release_ctrls(struct ambxc_ctx *ctx);
++extern const struct v4l2_ioctl_ops ambxc_ioctl_ops;
++
++#endif /* __AMBXC_CTRLS_H__ */
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ioctl.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ioctl.c
+new file mode 100644
+index 00000000..38cf36b3
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ioctl.c
+@@ -0,0 +1,651 @@
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include <linux/timer.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++
++#include <linux/platform_device.h>
++#include <media/v4l2-mem2mem.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-event.h>
++#include <media/videobuf2-vmalloc.h>
++
++#include "ambxc.h"
++
++/* Flags that indicate a format can be used for capture/output */
++#define MEM2MEM_CAPTURE	(1 << 0)
++#define MEM2MEM_OUTPUT	(1 << 1)
++
++extern struct ambxc_q_data* get_q_data(struct ambxc_ctx *ctx,
++				       enum v4l2_buf_type type);
++
++struct ambxc_fmt formats[] = {
++	{
++		.name	= "H264 with start codes",
++		.fourcc	= V4L2_PIX_FMT_H264,
++		.types	= MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
++	},
++	{
++		.name	= "MPEG-2 ES",
++		.fourcc	= V4L2_PIX_FMT_MPEG2,
++		.types	= MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
++	},
++	{
++		.name	= "MPEG-1/2/4 Multiplexed",
++		.fourcc	= V4L2_PIX_FMT_MPEG,
++		.types	= MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
++	},
++};
++
++struct v4l2_frmsize_discrete framesize[] = {
++
++	{ 1920, 1080},
++	{ 1280, 720},
++};
++
++static struct ambxc_fmt* find_format(struct v4l2_format *f)
++{
++	struct ambxc_fmt *fmt;
++	unsigned int k;
++
++	for (k = 0; k < NUM_FORMATS; k++) {
++		fmt = &formats[k];
++		if (fmt->fourcc == f->fmt.pix.pixelformat)
++			break;
++	}
++
++	if (k == NUM_FORMATS)
++		return NULL;
++
++	return &formats[k];
++}
++
++struct v4l2_frmsize_discrete* find_framesize(struct ambxc_ctx *ctx,
++					     struct v4l2_format *f)
++{
++	struct v4l2_frmsize_discrete *frmsz;
++	struct ambxc_q_data *q_data;
++
++	int i = 0;
++	frmsz = &framesize[0];
++
++	/* find the exact match first */
++	for (i = 0; i < ARRAY_SIZE(framesize); i++) {
++
++		frmsz = &framesize[i];
++
++		if (frmsz->height == f->fmt.pix.height &&
++		    frmsz->width == f->fmt.pix.width)
++			return frmsz;
++	}
++
++	/* return current framesize */
++	q_data = get_q_data(ctx, f->type);
++
++	for (i = 0; i < ARRAY_SIZE(framesize); i++) {
++
++		frmsz = &framesize[i];
++
++		if (frmsz->height == q_data->height &&
++		    frmsz->width == q_data->width)
++			return frmsz;
++	}
++
++	/* return the last available framesize */
++	return frmsz;
++}
++
++
++/*
++ * video ioctls
++ */
++static int vidioc_querycap(struct file *file, void *priv,
++			   struct v4l2_capability *cap)
++{
++	strncpy(cap->driver, AMBXC_NAME, sizeof(cap->driver) - 1);
++	strncpy(cap->card, AMBXC_NAME, sizeof(cap->card) - 1);
++	snprintf(cap->bus_info, sizeof(cap->bus_info),
++		 "platform:%s", AMBXC_NAME);
++	cap->device_caps = V4L2_CAP_VIDEO_M2M |
++			V4L2_CAP_VIDEO_CAPTURE |
++			V4L2_CAP_VIDEO_OUTPUT |
++			V4L2_CAP_STREAMING;
++	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++
++	return 0;
++}
++
++static struct v4l2_input input = {
++	.name = "Camera 0",
++	.type = V4L2_INPUT_TYPE_CAMERA,
++	.index = 0,
++};
++
++static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
++{
++	int i, num;
++	struct ambxc_fmt *fmt;
++
++	num = 0;
++
++	for (i = 0; i < NUM_FORMATS; ++i) {
++		if (formats[i].types & type) {
++			/* index-th format of type type found ? */
++			if (num == f->index)
++				break;
++			/* Correct type but haven't reached our index yet,
++			 * just increment per-type index */
++			++num;
++		}
++	}
++
++	if (i < NUM_FORMATS) {
++		/* Format found */
++		fmt = &formats[i];
++		strncpy(f->description, fmt->name, sizeof(f->description) - 1);
++		f->pixelformat = fmt->fourcc;
++		f->flags = V4L2_FMT_FLAG_COMPRESSED;
++		return 0;
++	}
++
++	/* Format not found */
++	return -EINVAL;
++}
++
++static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
++				   struct v4l2_fmtdesc *f)
++{
++	return enum_fmt(f, MEM2MEM_CAPTURE);
++}
++
++static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
++				   struct v4l2_fmtdesc *f)
++{
++	return enum_fmt(f, MEM2MEM_OUTPUT);
++}
++
++static int vidioc_g_fmt(struct ambxc_ctx *ctx, struct v4l2_format *f)
++{
++	struct vb2_queue *vq;
++	struct ambxc_q_data *q_data;
++
++	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++	if (!vq)
++		return -EINVAL;
++
++	q_data = get_q_data(ctx, f->type);
++
++	f->fmt.pix.width	= q_data->width;
++	f->fmt.pix.height	= q_data->height;
++	f->fmt.pix.field	= V4L2_FIELD_NONE;
++	f->fmt.pix.pixelformat	= q_data->fmt->fourcc;
++	f->fmt.pix.bytesperline	= 0;
++	f->fmt.pix.sizeimage	= BUF_SIZE;
++
++	return 0;
++}
++
++static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
++				struct v4l2_format *f)
++{
++	return vidioc_g_fmt(file2ctx(file), f);
++}
++
++static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
++				struct v4l2_format *f)
++{
++	return vidioc_g_fmt(file2ctx(file), f);
++}
++
++static int vidioc_try_fmt(struct v4l2_format *f, struct ambxc_fmt *fmt)
++{
++	enum v4l2_field field;
++
++	field = f->fmt.pix.field;
++
++	if (field == V4L2_FIELD_ANY)
++		field = V4L2_FIELD_NONE;
++	else if (field != V4L2_FIELD_NONE)
++		return -EINVAL;
++
++	f->fmt.pix.field = field;
++	f->fmt.pix.bytesperline = 0;
++	f->fmt.pix.sizeimage = BUF_SIZE;
++
++	return 0;
++}
++
++static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
++				  struct v4l2_format *f)
++{
++	struct ambxc_fmt *fmt;
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	fmt = find_format(f);
++	if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
++		v4l2_err(&ctx->dev->v4l2_dev,
++			 "Fourcc format (0x%08x) invalid.\n",
++			 f->fmt.pix.pixelformat);
++		return -EINVAL;
++	}
++
++	return vidioc_try_fmt(f, fmt);
++}
++
++static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
++				  struct v4l2_format *f)
++{
++	struct ambxc_fmt *fmt;
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	fmt = find_format(f);
++	if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
++		v4l2_err(&ctx->dev->v4l2_dev,
++			 "Fourcc format (0x%08x) invalid.\n",
++			 f->fmt.pix.pixelformat);
++		return -EINVAL;
++	}
++
++	return vidioc_try_fmt(f, fmt);
++}
++
++static int vidioc_s_fmt(struct ambxc_ctx *ctx, struct v4l2_format *f)
++{
++	struct ambxc_q_data *q_data;
++	struct vb2_queue *vq;
++	struct v4l2_frmsize_discrete *frmsz;
++
++	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++	if (!vq)
++		return -EINVAL;
++
++	q_data = get_q_data(ctx, f->type);
++	if (!q_data)
++		return -EINVAL;
++
++	if (vb2_is_busy(vq)) {
++		v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
++		return -EBUSY;
++	}
++
++	frmsz = find_framesize(ctx, f);
++
++	q_data->fmt		= find_format(f);
++	q_data->width		= frmsz->width;
++	q_data->height		= frmsz->height;
++	q_data->sizeimage	= BUF_SIZE;
++
++	return 0;
++}
++
++static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
++				struct v4l2_format *f)
++{
++	int ret;
++
++	ret = vidioc_try_fmt_vid_cap(file, priv, f);
++	if (ret)
++		return ret;
++
++	return vidioc_s_fmt(file2ctx(file), f);
++}
++
++static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
++				struct v4l2_format *f)
++{
++	int ret;
++
++	ret = vidioc_try_fmt_vid_out(file, priv, f);
++	if (ret)
++		return ret;
++
++	ret = vidioc_s_fmt(file2ctx(file), f);
++	return ret;
++}
++
++static int vidioc_enum_framesizes(struct file *file,
++				  void *priv, struct v4l2_frmsizeenum *frms)
++{
++	if (frms->index >= ARRAY_SIZE(framesize))
++		return -EINVAL;
++
++	switch (frms->pixel_format) {
++	case V4L2_PIX_FMT_H264:
++	case V4L2_PIX_FMT_MPEG2:
++		frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
++		frms->discrete = framesize[frms->index];
++
++		return 0;
++	default:
++		return -EINVAL;
++	}
++}
++
++static int vidioc_reqbufs(struct file *file, void *priv,
++			  struct v4l2_requestbuffers *reqbufs)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
++}
++
++static int vidioc_querybuf(struct file *file, void *priv,
++			   struct v4l2_buffer *buf)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
++}
++
++static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
++}
++
++static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
++}
++
++static int vidioc_streamon(struct file *file, void *priv,
++			   enum v4l2_buf_type type)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
++}
++
++static int vidioc_streamoff(struct file *file, void *priv,
++			    enum v4l2_buf_type type)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
++}
++
++static int vidioc_enum_input(struct file *file, void *priv,
++			     struct v4l2_input *inp)
++{
++	if (inp->index >= 1)
++		return -EINVAL;
++
++	inp->type  = V4L2_INPUT_TYPE_CAMERA;
++	return 0;
++}
++
++static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
++{
++	*i = 0;
++	return 0;
++}
++
++static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
++{
++	if (i >= 1)
++		return -EINVAL;
++
++	return 0;
++}
++
++static int vidioc_enum_output(struct file *file, void *priv,
++			     struct v4l2_output *outp)
++{
++	if (outp->index >= 1)
++		return -EINVAL;
++
++	return 0;
++}
++
++static int vidioc_g_output(struct file *file, void *priv, unsigned int *i)
++{
++	*i = 0;
++	return 0;
++}
++
++static int vidioc_s_output(struct file *file, void *priv, unsigned int i)
++{
++	if (i >= 1)
++		return -EINVAL;
++
++	return 0;
++}
++
++extern int ambxc_ctl_send(const char *buf, int count);
++
++struct ambxc_cmd {
++
++	char *cmd;
++	int dly;
++};
++
++struct ambxc_cmd cmd_1080i_xc_start[] = {
++//	{"d:\\ash\\Xcode\\XCODE_H2H_1080I_ES_NFS_CFG.ash", 8},
++//	{"d:\\ash\\Xcode\\XCODE_H2H_1080I_ES_NFS_START.ash", 0},
++	{ NULL, 0 }
++};
++
++struct ambxc_cmd cmd_720p_xc_start[] = {
++//	{"d:\\ash\\Xcode\\XCODE_H2H_720P_ES_NFS_CFG.ash", 8},
++//	{"d:\\ash\\Xcode\\XCODE_H2H_720P_ES_NFS_START.ash", 0},
++	{ NULL, 0 }
++};
++
++struct ambxc_cmd *cmd_xc_start = cmd_720p_xc_start;
++
++struct timer_list	cmd_timer;
++
++struct ambxc_cmd cmd_enc_stop[] = {
++	{ "amba voch stop --par ENC_H264_1080I_AO_STOP -s 0 -c 0T", 1 },
++	{ NULL, 0 }
++};
++
++static void do_xc_cmd(unsigned long priv)
++{
++	struct ambxc_cmd *cmds = (void *)priv;
++	char cmd_buf[128];
++
++	while (cmds->cmd) {
++
++		sprintf(cmd_buf, "%s\n", cmds->cmd);
++		printk(KERN_DEBUG "%s\n", cmd_buf);
++		ambxc_ctl_send(cmd_buf, strlen(cmd_buf));
++		mdelay(cmds->dly * 1000);
++		cmds++;
++	}
++}
++
++void do_xc_start(struct ambxc_ctx *ctx)
++{
++	struct ambxc_q_data *q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
++
++	dprintk(ctx->dev, "do_xc_start:\n");
++
++	if (q_data->height == 720)
++		cmd_xc_start = cmd_720p_xc_start;
++	else
++		cmd_xc_start = cmd_1080i_xc_start;
++
++	do_xc_cmd((unsigned long)cmd_xc_start);
++}
++
++static void do_xc_stop(struct ambxc_ctx *ctx)
++{
++	dprintk(ctx->dev, "do_xcode_stop: (wait EOS from itron for 20 secs)\n");
++
++	setup_timer(&cmd_timer, do_xc_cmd, (unsigned long)cmd_enc_stop);
++	mod_timer(&cmd_timer, jiffies + msecs_to_jiffies(20 * 1000));
++}
++
++int vidioc_encoder_cmd(struct file *file, void *priv,
++		       struct v4l2_encoder_cmd *cmd)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	switch (cmd->cmd) {
++	case V4L2_ENC_CMD_START:
++
++		if (cmd->flags != 0)
++			return -EINVAL;
++
++		do_xc_start(ctx);
++
++		break;
++
++	case V4L2_ENC_CMD_STOP:
++
++		if (cmd->flags != 0)
++			return -EINVAL;
++
++		break;
++
++	default:
++		return -EINVAL;
++	}
++	return 0;
++}
++
++int vidioc_decoder_cmd(struct file *file, void *priv,
++		       struct v4l2_decoder_cmd *cmd)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++	switch (cmd->cmd) {
++	case V4L2_DEC_CMD_START:
++		if (cmd->flags != 0)
++			return -EINVAL;
++
++		do_xc_start(ctx);
++		break;
++
++	case V4L2_DEC_CMD_STOP:
++		if (cmd->flags != 0)
++			return -EINVAL;
++
++		while (!list_empty(&ctx->m2m_ctx->out_q_ctx.rdy_queue)) {
++			dprintk(ctx->dev, "wait until all queued OUTPUT buffers are sent\n");
++			msleep(1000);
++		}
++
++		do_xc_stop(ctx);
++
++		break;
++
++	default:
++		return -EINVAL;
++
++	}
++	return 0;
++}
++
++static int vidioc_subscribe_event(struct v4l2_fh *fh,
++				  const struct v4l2_event_subscription *sub)
++{
++	switch (sub->type) {
++	case V4L2_EVENT_EOS:
++		return v4l2_event_subscribe(fh, sub, 2, NULL);
++	default:
++		return -EINVAL;
++	}
++}
++
++static int vidioc_g_parm(struct file *file, void *fh,
++			 struct v4l2_streamparm *a) {
++	int rval = 0;
++#if 0
++	struct omap24xxcam_fh *ofh = fh;
++	struct omap24xxcam_device *cam = ofh->cam;
++
++	mutex_lock(&cam->mutex);
++	rval = vidioc_int_g_parm(cam->sdev, a);
++	mutex_unlock(&cam->mutex);
++#endif
++	return rval;
++}
++
++static int vidioc_s_parm(struct file *file, void *fh,
++			 struct v4l2_streamparm *a)
++{
++	int rval = 0;
++#if 0
++	struct omap24xxcam_fh *ofh = fh;
++	struct omap24xxcam_device *cam = ofh->cam;
++	struct v4l2_streamparm old_streamparm;
++	int rval;
++
++	mutex_lock(&cam->mutex);
++	if (cam->streaming) {
++		rval = -EBUSY;
++		goto out;
++	}
++
++	old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++	rval = vidioc_int_g_parm(cam->sdev, &old_streamparm);
++	if (rval)
++		goto out;
++
++	rval = vidioc_int_s_parm(cam->sdev, a);
++	if (rval)
++		goto out;
++
++	rval = omap24xxcam_sensor_if_enable(cam);
++	/*
++	 * Revert to old streaming parameters if enabling sensor
++	 * interface with the new ones failed.
++	 */
++	if (rval)
++		vidioc_int_s_parm(cam->sdev, &old_streamparm);
++
++out:
++	mutex_unlock(&cam->mutex);
++#endif
++
++	return rval;
++}
++
++const struct v4l2_ioctl_ops ambxc_ioctl_ops = {
++
++	.vidioc_querycap	= vidioc_querycap,
++
++	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
++	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
++	.vidioc_try_fmt_vid_cap	= vidioc_try_fmt_vid_cap,
++	.vidioc_s_fmt_vid_cap	= vidioc_s_fmt_vid_cap,
++
++	.vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
++	.vidioc_g_fmt_vid_out	= vidioc_g_fmt_vid_out,
++	.vidioc_try_fmt_vid_out	= vidioc_try_fmt_vid_out,
++	.vidioc_s_fmt_vid_out	= vidioc_s_fmt_vid_out,
++
++	.vidioc_reqbufs		= vidioc_reqbufs,
++	.vidioc_querybuf	= vidioc_querybuf,
++
++	.vidioc_qbuf		= vidioc_qbuf,
++	.vidioc_dqbuf		= vidioc_dqbuf,
++
++	.vidioc_streamon	= vidioc_streamon,
++	.vidioc_streamoff	= vidioc_streamoff,
++
++	.vidioc_enum_input	= vidioc_enum_input,
++	.vidioc_g_input		= vidioc_g_input,
++	.vidioc_s_input		= vidioc_s_input,
++
++	.vidioc_enum_output	= vidioc_enum_output,
++	.vidioc_g_output	= vidioc_g_output,
++	.vidioc_s_output	= vidioc_s_output,
++
++	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
++	.vidioc_decoder_cmd	= vidioc_decoder_cmd,
++
++	.vidioc_enum_framesizes = vidioc_enum_framesizes,
++
++	.vidioc_subscribe_event = vidioc_subscribe_event,
++	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
++
++	.vidioc_g_parm		= vidioc_g_parm,
++	.vidioc_s_parm		= vidioc_s_parm,
++};
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_rpmsg.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_rpmsg.c
+new file mode 100644
+index 00000000..2def2c91
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_rpmsg.c
+@@ -0,0 +1,170 @@
++#include <linux/module.h>
++#include <linux/rpmsg.h>
++#include <linux/err.h>
++#include <linux/remoteproc.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++
++#include <linux/kfifo.h>
++#include <linux/delay.h>
++
++#include <plat/ambcache.h>
++
++typedef struct xnfs_info_s {
++
++	char		*addr;
++	int		size;
++	int		count;
++	void		*priv;
++} xnfs_info_t;
++
++struct xnfs_struct {
++
++	int			id;
++	struct kfifo		fifo;
++	spinlock_t		lock;
++	wait_queue_head_t	queue;
++	struct rpmsg_channel	*rpdev;
++};
++
++static struct xnfs_struct g_wnfs;
++static struct xnfs_struct g_rnfs;
++
++ssize_t xnfs_read(char *buf, size_t len)
++{
++	struct xnfs_struct *xnfs = &g_wnfs;
++	xnfs_info_t info;
++	int n = 0;
++	char *va;
++	struct timespec ts, ts1, ts2;
++
++	getnstimeofday(&ts1);
++	wait_event_interruptible(xnfs->queue,
++				 kfifo_out_locked(&xnfs->fifo, &info,
++						  sizeof(info), &xnfs->lock));
++
++	getnstimeofday(&ts2);
++	if (!info.size) {
++		rpmsg_send(xnfs->rpdev, &n, sizeof(n));
++		return 0;
++	}
++
++	va = (void *)ambarella_phys_to_virt((unsigned long)info.addr);
++	n = info.size * info.count;
++	ts = timespec_sub(ts2, ts1);
++
++	printk(KERN_DEBUG "rpmsg: Linux got 0x%08x Bytes for %lu.%09lu Seconds\n",
++	       info.count, ts.tv_sec, ts.tv_nsec);
++
++	ambcache_flush_range((void *)va, n);
++	memcpy(buf, va, n);
++
++	/* ack to release fread of iTRON side */
++	rpmsg_send(xnfs->rpdev, &n, sizeof(n));
++
++	return n;
++}
++
++ssize_t xnfs_write(char *buf, size_t len)
++{
++	struct xnfs_struct *xnfs = &g_rnfs;
++	char *va;
++	int size;
++	xnfs_info_t info;
++
++	wait_event_interruptible(xnfs->queue,
++				 kfifo_out_locked(&xnfs->fifo, &info,
++						  sizeof(info), &xnfs->lock));
++
++	va = (void *)ambarella_phys_to_virt((unsigned long)info.addr);
++	size = info.size * info.count;
++
++	BUG_ON(size < len);
++
++	if (len > 0) {
++
++		memcpy(va, buf, len);
++		ambcache_clean_range((void *)va, len);
++	}
++	if (len == 0)
++		printk(KERN_DEBUG "rpmsg: uItron got 0 bytes\n");
++
++	rpmsg_send(xnfs->rpdev, &len, sizeof(len));
++
++	return len;
++}
++
++static void rpmsg_xnfs_cb(struct rpmsg_channel *rpdev, void *data,
++			  int len, void *priv, u32 src)
++{
++	struct xnfs_struct *xnfs = priv;
++
++	BUG_ON(len != sizeof(xnfs_info_t));
++	kfifo_in_locked(&xnfs->fifo, (char *)data, len, &xnfs->lock);
++	wake_up_interruptible(&xnfs->queue);
++}
++
++static int xnfs_init(struct xnfs_struct *xnfs)
++{
++	int ret;
++
++	spin_lock_init(&xnfs->lock);
++	init_waitqueue_head(&xnfs->queue);
++
++	ret = kfifo_alloc(&xnfs->fifo, 4096 * 16, GFP_KERNEL);
++	if (ret)
++		return ret;
++
++	return 0;
++}
++
++static struct rpmsg_device_id rpmsg_xnfs_id_table[] = {
++	{ .name = "rnfs_arm11", },
++	{ .name	= "wnfs_arm11", },
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_xnfs_id_table);
++
++static int rpmsg_xnfs_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++	struct xnfs_struct *xnfs = NULL;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	if (!strcmp(rpdev->id.name, rpmsg_xnfs_id_table[0].name)) {
++		xnfs = &g_rnfs;
++		xnfs->id = 0;
++		printk("RPMSG Ready from NFS Server [ARM11] is ready\n");
++
++	} else if (!strcmp(rpdev->id.name, rpmsg_xnfs_id_table[1].name)) {
++		xnfs = &g_wnfs;
++		xnfs->id = 1;
++		printk("RPMSG Write to NFS Server [ARM11] is ready\n");
++	}
++
++	xnfs_init(xnfs);
++	xnfs->rpdev = rpdev;
++
++	rpdev->ept->priv = xnfs;
++
++	rpmsg_send(rpdev, &nsm, sizeof(nsm));
++
++	return ret;
++}
++
++static void rpmsg_xnfs_remove(struct rpmsg_channel *rpdev)
++{
++}
++
++struct rpmsg_driver rpmsg_xnfs_driver = {
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_xnfs_id_table,
++	.probe		= rpmsg_xnfs_probe,
++	.callback	= rpmsg_xnfs_cb,
++	.remove		= rpmsg_xnfs_remove,
++};
+diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_vdev.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_vdev.c
+new file mode 100644
+index 00000000..5f07eb9d
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_vdev.c
+@@ -0,0 +1,595 @@
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/kthread.h>
++#include <linux/freezer.h>
++#include <linux/rpmsg.h>
++
++#include <linux/platform_device.h>
++#include <media/v4l2-mem2mem.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-event.h>
++#include <media/videobuf2-vmalloc.h>
++
++#include "ambxc.h"
++#include "ambxc_ctrls.h"
++
++#define AMBXC_MODULE_NAME "ambxc"
++
++struct ambxc_dev *g_dev;
++
++extern struct rpmsg_driver rpmsg_ambxc_ctl_driver;
++extern struct rpmsg_driver rpmsg_xnfs_driver;
++
++extern struct ambxc_fmt formats[];
++extern struct v4l2_frmsize_discrete framesize[];
++
++extern void output_buf_queued(void);
++extern ssize_t xnfs_read(char __user *buf, size_t len);
++extern ssize_t xnfs_write(char __user *buf, size_t len);
++
++static void ambxc_dev_release(struct device *dev)
++{
++}
++
++static struct platform_device ambxc_pdev = {
++	.name		= AMBXC_NAME,
++	.dev.release	= ambxc_dev_release,
++};
++
++struct ambxc_q_data* get_q_data(struct ambxc_ctx *ctx,
++				  enum v4l2_buf_type type)
++{
++	switch (type) {
++	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
++		return &ctx->q_data[V4L2_M2M_SRC];
++	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
++		return &ctx->q_data[V4L2_M2M_DST];
++	default:
++		BUG();
++	}
++	return NULL;
++}
++
++/*
++ * mem2mem callbacks
++ */
++
++static int job_ready(void *priv)
++{
++#if 0
++	struct ambxc_ctx *ctx = priv;
++
++	if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx)
++	    || v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) {
++		dprintk(ctx->dev, "Not enough buffers available\n");
++		return 0;
++	}
++#endif
++
++	return 1;
++}
++
++static void job_abort(void *priv)
++{
++	// struct ambxc_ctx *ctx = priv;
++}
++
++static void ambxc_lock(void *priv)
++{
++	struct ambxc_ctx *ctx = priv;
++	struct ambxc_dev *dev = ctx->dev;
++
++	mutex_lock(&dev->dev_mutex);
++}
++
++static void ambxc_unlock(void *priv)
++{
++	struct ambxc_ctx *ctx = priv;
++	struct ambxc_dev *dev = ctx->dev;
++
++	mutex_unlock(&dev->dev_mutex);
++}
++
++
++/* device_run() - prepares and starts the device
++ *
++ * This simulates all the immediate preparations required before starting
++ * a device. This will be called by the framework when it decides to schedule
++ * a particular instance.
++ */
++/***************************************************************************/
++
++static int thread_capture(void *data)
++{
++	struct ambxc_dev *dev = data;
++	struct ambxc_ctx *ctx = dev->ctx;
++	struct vb2_buffer *vb;
++	char *p;
++	ssize_t n;
++
++	set_freezable();
++
++	for (;;) {
++
++		if (kthread_should_stop()) {
++			try_to_freeze();
++			break;
++		}
++
++		wait_event_interruptible(dev->queue_capture,
++					 v4l2_m2m_next_dst_buf(ctx->m2m_ctx));
++
++		vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
++
++		p = vb2_plane_vaddr(vb, 0);
++		n = xnfs_read(p, BUF_SIZE);
++
++		if (n > 0) {
++
++			vb->v4l2_buf.field = V4L2_FIELD_NONE;
++			do_gettimeofday(&vb->v4l2_buf.timestamp);
++			vb2_set_plane_payload(vb, 0, n);
++			vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
++		}
++		if (n == 0) {
++			const struct v4l2_event ev = {
++				.type = V4L2_EVENT_EOS
++			};
++			dprintk(ctx->dev, "got EOS from itron, and queue it to userspace\n");
++			v4l2_event_queue_fh(& ctx->fh, & ev);
++		}
++	}
++
++	return 0;
++}
++
++static int thread_feed(void *data)
++{
++	struct ambxc_dev *dev = data;
++	struct ambxc_ctx *ctx = dev->ctx;
++	struct vb2_buffer *vb;
++	char *p;
++	ssize_t n;
++
++	set_freezable();
++
++	for (;;) {
++
++		if (kthread_should_stop()) {
++			try_to_freeze();
++			break;
++		}
++
++		wait_event_interruptible(dev->queue_feed,
++					 v4l2_m2m_next_src_buf(ctx->m2m_ctx));
++
++		vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
++		p = vb2_plane_vaddr(vb, 0);
++		n = vb2_get_plane_payload(vb, 0);
++		xnfs_write(p, n);
++
++		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
++	}
++
++	return 0;
++}
++
++static void device_run(void *priv)
++{
++	// struct ambxc_ctx *ctx = priv;
++}
++
++/*
++ * Queue operations
++ */
++
++static int ambxc_queue_setup(struct vb2_queue *vq,
++				const struct v4l2_format *fmt,
++				unsigned int *nbuffers, unsigned int *nplanes,
++				unsigned int sizes[], void *alloc_ctxs[])
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(vq);
++	struct ambxc_q_data *q_data;
++	unsigned int size, count = *nbuffers;
++
++	q_data = get_q_data(ctx, vq->type);
++
++	size = BUF_SIZE;
++
++	while (size * count > MEM2MEM_VID_MEM_LIMIT)
++		(count)--;
++
++	*nplanes = 1;
++	*nbuffers = count;
++	sizes[0] = size;
++
++	dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
++
++	return 0;
++}
++
++static int ambxc_buf_prepare(struct vb2_buffer *vb)
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
++	struct ambxc_q_data *q_data;
++
++	q_data = get_q_data(ctx, vb->vb2_queue->type);
++
++	if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
++		dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
++				__func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static void ambxc_buf_queue(struct vb2_buffer *vb)
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
++	v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
++
++	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
++		wake_up_interruptible(&ctx->dev->queue_feed);
++	else
++		wake_up_interruptible(&ctx->dev->queue_capture);
++}
++
++static void ambxc_wait_prepare(struct vb2_queue *q)
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
++	ambxc_unlock(ctx);
++}
++
++static void ambxc_wait_finish(struct vb2_queue *q)
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
++	ambxc_lock(ctx);
++}
++
++extern void do_xc_start(struct ambxc_ctx *ctx);
++static int start_streaming(struct vb2_queue *q, unsigned int count)
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
++
++	dprintk(ctx->dev, "start streaming type:%d\n", q->type);
++
++	if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
++	     ctx->m2m_ctx->out_q_ctx.q.streaming) ||
++	    (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
++	     ctx->m2m_ctx->cap_q_ctx.q.streaming)) {
++		do_xc_start(ctx);
++	}
++
++	return 0;
++}
++
++static int stop_streaming(struct vb2_queue *q)
++{
++	struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
++
++	dprintk(ctx->dev, "stop streaming type:%d\n", q->type);
++
++	return 0;
++}
++
++static struct vb2_ops ambxc_qops = {
++	.queue_setup		= ambxc_queue_setup,
++	.buf_prepare		= ambxc_buf_prepare,
++	.buf_queue		= ambxc_buf_queue,
++	.wait_prepare		= ambxc_wait_prepare,
++	.wait_finish		= ambxc_wait_finish,
++	.start_streaming	= start_streaming,
++	.stop_streaming		= stop_streaming,
++};
++
++static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
++{
++	struct ambxc_ctx *ctx = priv;
++	int ret;
++
++	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
++	src_vq->drv_priv = ctx;
++	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
++	src_vq->ops = &ambxc_qops;
++	src_vq->mem_ops = &vb2_vmalloc_memops;
++	src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
++
++	ret = vb2_queue_init(src_vq);
++	if (ret)
++		return ret;
++
++	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
++	dst_vq->drv_priv = ctx;
++	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
++	dst_vq->ops = &ambxc_qops;
++	dst_vq->mem_ops = &vb2_vmalloc_memops;
++	dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
++
++	return vb2_queue_init(dst_vq);
++}
++
++/*
++ * File operations
++ */
++static int ambxc_open(struct file *file)
++{
++	struct ambxc_dev *dev = video_drvdata(file);
++	struct ambxc_ctx *ctx = NULL;
++	int rc = 0;
++
++	if (mutex_lock_interruptible(&dev->dev_mutex))
++		return -ERESTARTSYS;
++#if 0
++	if ((atomic_read(&dev->ref_cnt) == 2)) {
++		rc = -EBUSY;
++		goto open_unlock;
++	}
++#endif
++
++	if ((atomic_read(&dev->ref_cnt) > 0)) {
++		rc = 0;
++		atomic_inc(&dev->ref_cnt);
++		ctx = dev->ctx;
++		file->private_data = &ctx->fh;
++		goto open_unlock;
++	}
++
++	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
++	if (!ctx) {
++		rc = -ENOMEM;
++		goto open_unlock;
++	}
++
++	v4l2_fh_init(&ctx->fh, video_devdata(file));
++	file->private_data = &ctx->fh;
++	ctx->dev = dev;
++
++	if (ambxc_init_ctrls(ctx))
++		goto open_unlock;
++
++	ctx->fh.ctrl_handler = &ctx->hdl;
++
++	ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
++	ctx->q_data[V4L2_M2M_SRC].sizeimage = BUF_SIZE;
++	ctx->q_data[V4L2_M2M_SRC].width = framesize[0].width;
++	ctx->q_data[V4L2_M2M_SRC].height = framesize[0].height;
++	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
++
++	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
++
++	if (IS_ERR(ctx->m2m_ctx)) {
++		rc = PTR_ERR(ctx->m2m_ctx);
++		ambxc_release_ctrls(ctx);
++		kfree(ctx);
++		goto open_unlock;
++	}
++
++	v4l2_fh_add(&ctx->fh);
++
++	atomic_inc(&dev->ref_cnt);
++	dev->ctx = ctx;
++	init_waitqueue_head(&dev->queue_capture);
++	init_waitqueue_head(&dev->queue_feed);
++	dev->kthread_capture = kthread_run(thread_capture, dev,
++					   dev->v4l2_dev.name);
++	dev->kthread_feed = kthread_run(thread_feed, dev, dev->v4l2_dev.name);
++
++	dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
++
++open_unlock:
++	mutex_unlock(&dev->dev_mutex);
++	return rc;
++}
++
++static int ambxc_release(struct file *file)
++{
++	struct ambxc_dev *dev = video_drvdata(file);
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	if ((atomic_read(&dev->ref_cnt) == 1)) {
++#if 0
++		dprintk(dev, "Releasing instance %p\n", ctx);
++
++		kthread_stop(dev->kthread);
++		if (IS_ERR(dev->kthread)) {
++			v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
++			return PTR_ERR(dev->kthread);
++		}
++
++		v4l2_fh_del(&ctx->fh);
++		v4l2_fh_exit(&ctx->fh);
++		v4l2_ctrl_handler_free(&ctx->hdl);
++		mutex_lock(&dev->dev_mutex);
++		v4l2_m2m_ctx_release(ctx->m2m_ctx);
++		mutex_unlock(&dev->dev_mutex);
++		kfree(ctx);
++#endif
++	}
++
++	// atomic_dec(&dev->ref_cnt);
++
++	return 0;
++}
++
++static unsigned int ambxc_poll(struct file *file,
++				 struct poll_table_struct *wait)
++{
++	struct ambxc_ctx *ctx = file2ctx(file);
++
++	return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
++}
++
++static int ambxc_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	struct ambxc_dev *dev = video_drvdata(file);
++	struct ambxc_ctx *ctx = file2ctx(file);
++	int res;
++
++	if (mutex_lock_interruptible(&dev->dev_mutex))
++		return -ERESTARTSYS;
++
++	res = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
++
++	mutex_unlock(&dev->dev_mutex);
++
++	return res;
++}
++
++static const struct v4l2_file_operations ambxc_fops = {
++	.owner		= THIS_MODULE,
++	.open		= ambxc_open,
++	.release	= ambxc_release,
++	.poll		= ambxc_poll,
++	.unlocked_ioctl	= video_ioctl2,
++	.mmap		= ambxc_mmap,
++};
++
++static struct v4l2_m2m_ops m2m_ops = {
++	.device_run	= device_run,
++	.job_ready	= job_ready,
++	.job_abort	= job_abort,
++	.lock		= ambxc_lock,
++	.unlock		= ambxc_unlock,
++};
++
++static struct video_device ambxc_videodev = {
++	.name		= AMBXC_NAME,
++	.vfl_dir	= VFL_DIR_M2M,
++	.fops		= &ambxc_fops,
++	.ioctl_ops	= &ambxc_ioctl_ops,
++	.minor		= -1,
++	.release	= video_device_release,
++};
++
++static int ambxc_probe(struct platform_device *pdev)
++{
++	struct ambxc_dev *dev;
++	struct video_device *vfd;
++	int ret;
++
++	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
++	if (!dev)
++		return -ENOMEM;
++
++	spin_lock_init(&dev->irqlock);
++
++	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
++	if (ret)
++		return ret;
++
++	atomic_set(&dev->inst, 0);
++	atomic_set(&dev->ref_cnt, 0);
++	mutex_init(&dev->dev_mutex);
++
++	vfd = video_device_alloc();
++	if (!vfd) {
++		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
++		ret = -ENOMEM;
++		goto unreg_dev;
++	}
++
++	*vfd = ambxc_videodev;
++	vfd->lock = &dev->dev_mutex;
++
++	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
++	if (ret) {
++		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
++		goto rel_vdev;
++	}
++
++	video_set_drvdata(vfd, dev);
++	snprintf(vfd->name, sizeof(vfd->name), "%s", ambxc_videodev.name);
++	dev->vfd = vfd;
++	// v4l2_device_set_name(&dev->v4l2_dev, vfd->name, &dev->inst);
++
++	v4l2_info(&dev->v4l2_dev, AMBXC_MODULE_NAME
++			"Device registered as /dev/%d\n", vfd->num);
++
++	platform_set_drvdata(pdev, dev);
++
++	dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
++	if (IS_ERR(dev->m2m_dev)) {
++		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
++		ret = PTR_ERR(dev->m2m_dev);
++		goto err_m2m;
++	}
++
++	g_dev = dev; // FIXME;
++	return 0;
++
++err_m2m:
++	v4l2_m2m_release(dev->m2m_dev);
++	video_unregister_device(dev->vfd);
++rel_vdev:
++	video_device_release(vfd);
++unreg_dev:
++	v4l2_device_unregister(&dev->v4l2_dev);
++
++	return ret;
++}
++
++static int ambxc_remove(struct platform_device *pdev)
++{
++	struct ambxc_dev *dev = platform_get_drvdata(pdev);
++
++	v4l2_info(&dev->v4l2_dev, "Removing " AMBXC_MODULE_NAME);
++	v4l2_m2m_release(dev->m2m_dev);
++	video_unregister_device(dev->vfd);
++	v4l2_device_unregister(&dev->v4l2_dev);
++
++	return 0;
++}
++
++static struct platform_driver ambxc_pdrv = {
++	.probe		= ambxc_probe,
++	.remove		= ambxc_remove,
++	.driver		= {
++		.name	= AMBXC_NAME,
++		.owner	= THIS_MODULE,
++	},
++};
++
++static int __init ambxc_init(void)
++{
++	int ret;
++
++	ret = register_rpmsg_driver(&rpmsg_ambxc_ctl_driver);
++	if (ret)
++		return ret;
++	ret = register_rpmsg_driver(&rpmsg_xnfs_driver);
++	if (ret)
++		return ret;
++
++	ret = platform_device_register(&ambxc_pdev);
++	if (ret)
++		return ret;
++
++	ret = platform_driver_register(&ambxc_pdrv);
++	if (ret)
++		platform_device_unregister(&ambxc_pdev);
++
++	return 0;
++}
++
++static void __exit ambxc_exit(void)
++{
++	platform_driver_unregister(&ambxc_pdrv);
++	platform_device_unregister(&ambxc_pdev);
++	unregister_rpmsg_driver(&rpmsg_xnfs_driver);
++	unregister_rpmsg_driver(&rpmsg_ambxc_ctl_driver);
++}
++
++module_init(ambxc_init);
++module_exit(ambxc_exit);
++
++MODULE_DESCRIPTION("Ambarella A8 Video Codec Driver");
++MODULE_AUTHOR("Tzu-Jung Lee, <tjlee@ambarella.com>");
++MODULE_VERSION("0.0.1");
+diff --git a/drivers/rpmsg/ambarella/host/aservice/Kconfig b/drivers/rpmsg/ambarella/host/aservice/Kconfig
+new file mode 100644
+index 00000000..4f2e986c
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/aservice/Kconfig
+@@ -0,0 +1,5 @@
++config RPMSG_AUDIOSERVICE
++	tristate "audio service"
++	depends on RPMSG
++	help
++	  A audio service client for interacting with Itron on ARM11
+diff --git a/drivers/rpmsg/ambarella/host/aservice/Makefile b/drivers/rpmsg/ambarella/host/aservice/Makefile
+new file mode 100644
+index 00000000..5b8d2df9
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/aservice/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_AUDIOSERVICE)	+= rpmsg_aservice.o
+diff --git a/drivers/rpmsg/ambarella/host/aservice/rpmsg_aservice.c b/drivers/rpmsg/ambarella/host/aservice/rpmsg_aservice.c
+new file mode 100644
+index 00000000..59e64d47
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/aservice/rpmsg_aservice.c
+@@ -0,0 +1,348 @@
++/*
++ * rpmsg audio service driver
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/rpmsg.h>
++#include <linux/err.h>
++#include <linux/remoteproc.h>
++
++#include <linux/poll.h>
++#include <linux/uaccess.h>
++#include <linux/miscdevice.h>
++#include <linux/kfifo.h>
++
++#include <linux/virtio_ring.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/mm.h>
++#include <linux/wait.h>
++
++#define DEVICE_NAME "aservice"
++
++enum aio_cmd {
++  AIO_CMD_SETUP = 0,
++  AIO_CMD_START = 1,
++  AIO_CMD_STOP = 2,
++  AIO_CMD_CLOSE = 3,
++  AIO_CMD_NONE = 0xFF
++};
++
++enum aio_type {
++	ENCODER = 0,
++	DECODER,
++	XCODER,
++	BYPASS
++};
++
++enum aio_dir {
++	ARM_TO_LINUX = 0,
++	LINUX_TO_ARM,
++	BIDRECTION,
++};
++
++enum aio_encoder {
++	AAC_ENC = 0,
++	AC3_ENC,
++	MP2_ENC
++};
++
++enum aio_decoder {
++	AAC_DEC = 0,
++	AC3_DEC,
++	MP2_DEC
++}; 
++
++//test aservice structure
++
++typedef struct aio_buf_s {
++	u32 command;
++  	u8 *arm_buf_base;    /**< ARM side buffer write pointer >*/
++  	u32 arm_buf_limit;    /**< ARM side buffer write pointer >*/
++  	u32 arm_buf_wptr;    /**< ARM side buffer write pointer >*/
++	u32 arm_buf_rptr;   /**< ARM side buffer read pointer >*/
++	u32 arm_buf_vaddr;	/** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
++
++	u8 *linux_buf_base;    /**< ARM side buffer write pointer >*/
++	u32 linux_buf_limit;    /**< ARM side buffer write pointer >*/
++	u32 linux_buf_wptr;	/**< Linux side buffer write pointer >*/
++	u32 linux_buf_rptr;	/**< Linux side buffer read pointer >*/
++	u32 linux_buf_vaddr;	/** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
++	u32 decoder;
++	u32 encoder;
++	u32 aio_type;
++	u32 aio_direction;
++	u32 self;
++} aio_buf_t;
++
++struct aservice_ret_msg {
++	s32 rval;
++};
++
++struct aservice_struct {
++        spinlock_t              lock;
++        struct rpmsg_channel    *rpdev;
++        struct miscdevice fdev;
++	aio_buf_t *aio_buf;
++	u32 finish_flag;
++};
++
++//init waiting queue
++static DECLARE_WAIT_QUEUE_HEAD(msgq);
++static struct aservice_struct g_aservice;
++
++static int device_open(struct inode *inode, struct file *filp)
++{
++	filp->private_data = &g_aservice;
++
++	return 0;
++}
++
++static ssize_t device_write(struct file *filp, const char *buf,
++			    size_t count, loff_t * off)
++{
++	struct aservice_struct *aservice = filp->private_data;
++
++	printk("Enter devide write\n");
++	//might deal with different write msgs
++	aservice->finish_flag = 1;
++	wake_up_interruptible(&msgq);
++	return count;
++}
++
++static ssize_t device_read(struct file *filp, char *buf,
++			   size_t len, loff_t * offset)
++{
++	struct aservice_struct *aservice = filp->private_data;
++	aio_buf_t *aio_buf = aservice->aio_buf;
++	int rval;
++
++	printk("Enter device read\n");
++
++	if (aio_buf != NULL) {
++		switch(aio_buf->command) {
++			case AIO_CMD_SETUP:
++			case AIO_CMD_START:
++                        case AIO_CMD_STOP:
++                        case AIO_CMD_CLOSE: {
++                                printk("Command! %d\n", aio_buf->command);
++				rval = copy_to_user(buf, aio_buf, sizeof(aio_buf_t));
++				if(rval)
++				{
++					printk("copy to user failed %d %d\n", rval, sizeof(aio_buf_t));
++					return -1;
++				}
++				aio_buf->command = AIO_CMD_NONE;
++				break;
++			}
++			case AIO_CMD_NONE: //no command
++				return -1;
++				break;
++		}
++		return 0;
++	}
++	else
++		return -1;
++}
++
++static int device_release(struct inode *inode, struct file *file)
++{
++	return 0;
++}
++
++static int device_mmap(struct file *filp, struct vm_area_struct *vma)
++{
++	struct aservice_struct *aservice = filp->private_data;
++	aio_buf_t *aio_buf = aservice->aio_buf;
++	int rval = 0;
++	unsigned long size;
++
++	size = vma->vm_end - vma->vm_start; //size from userspace
++
++	printk("Doing mmap, size = %lu\n", size);
++
++	vma->vm_pgoff = (aio_buf->self) >> PAGE_SHIFT;
++
++	rval = remap_pfn_range(vma,
++			vma->vm_start,
++			vma->vm_pgoff,
++			size,
++			vma->vm_page_prot);
++	
++	if (rval < 0)
++		printk("We got some error\n");
++
++	//mmap this size of memory based on memory address from uItron side
++	//maybe more memory management if there is only one kernel device
++	return rval;
++}
++
++static struct file_operations fops = {
++	.read = device_read,
++	.write = device_write,
++	.open = device_open,
++	.mmap = device_mmap,
++	.release = device_release
++};
++
++static int aservice_init(struct aservice_struct *aservice)
++{
++	spin_lock_init(&aservice->lock);
++
++	printk("RPMSG aservice [ARM11] now is ready at /dev/%s\n", DEVICE_NAME);
++
++	aservice->fdev.name = DEVICE_NAME;
++	aservice->fdev.fops = &fops;
++	aservice->aio_buf = NULL;
++	aservice->finish_flag = 0;
++	misc_register(&aservice->fdev);
++
++	return 0;
++}
++
++static void rpmsg_aservice_cb(struct rpmsg_channel *rpdev, void *data,
++				int len, void *priv, u32 src)
++{
++	struct aservice_struct *aservice = priv; 
++	struct aservice_ret_msg msg;
++	aio_buf_t *aio_buf_test;
++
++	aio_buf_t *aio_buf = data;
++	aservice->aio_buf = data;
++
++	printk("recieve msg : rpmsg_aservice_cb +\n");
++	
++	printk("length %d\n", len);
++	printk("My address is %08X\n", (u32)aio_buf);
++        printk("command %d\n",aio_buf->command);
++        printk("buf base %08X\n",(u32)aio_buf->arm_buf_base);    /**< ARM side buffer write pointer >*/
++        printk("buf limit %08X\n",aio_buf->arm_buf_limit);    /**< ARM side buffer write pointer >*/
++        printk("wptr %08X\n",aio_buf->arm_buf_wptr);    /**< ARM side buffer write pointer >*/
++        printk("rptr %08X\n",aio_buf->arm_buf_rptr);   /**< ARM side buffer read pointer >*/
++        printk("buf vaddr %08X\n",aio_buf->arm_buf_vaddr);      /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
++
++        printk("buf base %08X\n",(u32)aio_buf->linux_buf_base);    /**< ARM side buffer write pointer >*/
++        printk("buf limit %08X\n",aio_buf->linux_buf_limit);    /**< ARM side buffer write pointer >*/
++        printk("buf wptr %08X\n",aio_buf->linux_buf_wptr);     /**< Linux side buffer write pointer >*/
++        printk("rptr %08X\n",aio_buf->linux_buf_rptr);     /**< Linux side buffer read pointer >*/
++        printk("buf vaddr %08X\n",aio_buf->linux_buf_vaddr);    /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
++
++	printk("encode %d\n",aio_buf->encoder);
++	printk("decode %d\n",aio_buf->decoder);
++	printk("type %d\n",aio_buf->aio_type);
++	printk("dir %d\n",aio_buf->aio_direction);	
++	printk("self %08X\n", aio_buf->self);
++	
++	aio_buf_test = (aio_buf_t *)phys_to_virt(aio_buf->self);
++	printk("aio buf test to %08X\n", (u32)aio_buf_test);
++        printk("command %d\n",aio_buf_test->command);
++        printk("buf base %08X\n",(u32)aio_buf_test->arm_buf_base);    /**< ARM side buffer write pointer >*/
++        printk("buf limit %08X\n",aio_buf_test->arm_buf_limit);    /**< ARM side buffer write pointer >*/
++        printk("wptr %08X\n",aio_buf_test->arm_buf_wptr);    /**< ARM side buffer write pointer >*/
++        printk("rptr %08X\n",aio_buf_test->arm_buf_rptr);   /**< ARM side buffer read pointer >*/
++        printk("buf vaddr %08X\n",aio_buf_test->arm_buf_vaddr);      /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
++
++	printk("Let's write something\n");
++	aio_buf_test->command = 2;
++	aio_buf_test->arm_buf_base = 0xDEADBEEF;
++	aio_buf_test->arm_buf_limit = 0x2000;
++	aio_buf_test->arm_buf_wptr = 0x12345678;
++	aio_buf_test->arm_buf_rptr = 0x87654321;
++	aio_buf_test->arm_buf_vaddr = 0x11111111;
++
++        printk("command %d\n",aio_buf_test->command);
++        printk("buf base %08X\n",(u32)aio_buf_test->arm_buf_base);    /**< ARM side buffer write pointer >*/
++        printk("buf limit %08X\n",aio_buf_test->arm_buf_limit);    /**< ARM side buffer write pointer >*/
++        printk("wptr %08X\n",aio_buf_test->arm_buf_wptr);    /**< ARM side buffer write pointer >*/
++        printk("rptr %08X\n",aio_buf_test->arm_buf_rptr);   /**< ARM side buffer read pointer >*/
++        printk("buf vaddr %08X\n",aio_buf_test->arm_buf_vaddr);      /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
++
++	switch(aio_buf->command)
++	{
++		case AIO_CMD_SETUP:
++			printk("setup command\n");
++			break;
++		case AIO_CMD_START:
++			printk("start command\n");
++			break;
++		case AIO_CMD_STOP:
++                        printk("start command\n");
++                        break;
++		case AIO_CMD_CLOSE:
++			printk("close command\n");
++		default:
++			printk("Bad command\n");
++			break;  
++	}
++
++	msg.rval = -1;
++	printk("msg val %d\n", msg.rval);
++	wait_event_interruptible(msgq, aservice->finish_flag != 0);
++	if (aservice->finish_flag)
++		aservice->finish_flag = 0;
++	printk("waiting queue done, send back to uItron\n");
++	//return a msg done, will using wait queue for application handshaking
++	rpmsg_sendto(rpdev, &msg, sizeof(msg), rpdev->dst);
++	
++}
++
++static int rpmsg_aservice_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++	struct aservice_struct *aservice = &g_aservice;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	aservice_init(aservice);
++	aservice->rpdev = rpdev;
++
++	rpdev->ept->priv = aservice;
++
++	rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
++
++	return ret;
++}
++
++static void rpmsg_aservice_remove(struct rpmsg_channel *rpdev)
++{
++	struct aservice_struct *aservice = &g_aservice;
++	misc_deregister(&aservice->fdev);
++}
++
++static struct rpmsg_device_id rpmsg_aservice_id_table[] = {
++	{ .name	= "aservice_arm11", },
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_aservice_id_table);
++
++static struct rpmsg_driver rpmsg_aservice_driver = {
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_aservice_id_table,
++	.probe		= rpmsg_aservice_probe,
++	.callback	= rpmsg_aservice_cb,
++	.remove		= rpmsg_aservice_remove,
++};
++
++static int __init rpmsg_aservice_init(void)
++{
++	return register_rpmsg_driver(&rpmsg_aservice_driver);
++}
++
++static void __exit rpmsg_aservice_fini(void)
++{
++	unregister_rpmsg_driver(&rpmsg_aservice_driver);
++}
++
++module_init(rpmsg_aservice_init);
++module_exit(rpmsg_aservice_fini);
++
++MODULE_DESCRIPTION("RPMSG audio service");
+diff --git a/drivers/rpmsg/ambarella/host/echo/Kconfig b/drivers/rpmsg/ambarella/host/echo/Kconfig
+new file mode 100644
+index 00000000..ac0b9f2d
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/echo/Kconfig
+@@ -0,0 +1,5 @@
++config RPMSG_ECHO
++	tristate "Echo"
++	depends on RPMSG
++	help
++	  A sample of rpmsg program which implement an echo server
+diff --git a/drivers/rpmsg/ambarella/host/echo/Makefile b/drivers/rpmsg/ambarella/host/echo/Makefile
+new file mode 100644
+index 00000000..dc166881
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/echo/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_ECHO)	+= rpmsg_echo.o
+diff --git a/drivers/rpmsg/ambarella/host/echo/rpmsg_echo.c b/drivers/rpmsg/ambarella/host/echo/rpmsg_echo.c
+new file mode 100644
+index 00000000..3e4ad33b
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/echo/rpmsg_echo.c
+@@ -0,0 +1,71 @@
++/*
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/rpmsg.h>
++#include <linux/err.h>
++#include <linux/remoteproc.h>
++
++static void rpmsg_echo_cb(struct rpmsg_channel *rpdev, void *data, int len,
++			void *priv, u32 src)
++{
++	printk("[ %20s ] recv msg: [%s] from 0x%x and len %d\n",
++	       __func__, (const char*)data, src, len);
++
++	/* Echo the recved message back */
++	rpmsg_send(rpdev, data, len);
++}
++
++static int rpmsg_echo_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	rpmsg_send(rpdev, &nsm, sizeof(nsm));
++
++	return ret;
++}
++
++static void rpmsg_echo_remove(struct rpmsg_channel *rpdev)
++{
++}
++
++static struct rpmsg_device_id rpmsg_echo_id_table[] = {
++	{ .name	= "echo_ca9_b", },
++	{ .name	= "echo_arm11", },
++	{ .name	= "echo_cortex", },
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_echo_id_table);
++
++static struct rpmsg_driver rpmsg_echo_driver = {
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_echo_id_table,
++	.probe		= rpmsg_echo_probe,
++	.callback	= rpmsg_echo_cb,
++	.remove		= rpmsg_echo_remove,
++};
++
++static int __init rpmsg_echo_init(void)
++{
++	return register_rpmsg_driver(&rpmsg_echo_driver);
++}
++
++static void __exit rpmsg_echo_fini(void)
++{
++	unregister_rpmsg_driver(&rpmsg_echo_driver);
++}
++
++module_init(rpmsg_echo_init);
++module_exit(rpmsg_echo_fini);
++
++MODULE_DESCRIPTION("RPMSG Echo Server");
+diff --git a/drivers/rpmsg/ambarella/host/rnfs/Kconfig b/drivers/rpmsg/ambarella/host/rnfs/Kconfig
+new file mode 100644
+index 00000000..ca407b90
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/rnfs/Kconfig
+@@ -0,0 +1,6 @@
++config RPMSG_RNFS
++	tristate "Read from NFS Server"
++	depends on RPMSG
++	depends on !RPMSG_AMBXC
++	help
++		A sample of read file from NFS Server
+diff --git a/drivers/rpmsg/ambarella/host/rnfs/Makefile b/drivers/rpmsg/ambarella/host/rnfs/Makefile
+new file mode 100644
+index 00000000..b48d2444
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/rnfs/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_RNFS)	+= rpmsg_rnfs.o
+diff --git a/drivers/rpmsg/ambarella/host/rnfs/rpmsg_rnfs.c b/drivers/rpmsg/ambarella/host/rnfs/rpmsg_rnfs.c
+new file mode 100644
+index 00000000..b06074d2
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/rnfs/rpmsg_rnfs.c
+@@ -0,0 +1,338 @@
++/*
++ * rpmsg read from nfs server driver
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/rpmsg.h>
++#include <linux/err.h>
++#include <linux/remoteproc.h>
++
++#include <linux/poll.h>
++#include <linux/uaccess.h>
++#include <linux/miscdevice.h>
++#include <linux/kfifo.h>
++
++#include <linux/virtio_ring.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++
++#define DEVICE_NAME "rnfs"
++
++
++typedef int redev_nfs_FILE;
++typedef struct nfs_fread_info_s {
++  int *addr;
++  int size;
++  int count;
++  redev_nfs_FILE *file;
++}
++nfs_fread_info_t;
++
++struct rnfs_struct {
++  struct kfifo    fifo;
++  spinlock_t    lock;
++  struct rpmsg_channel  *rpdev;
++  struct miscdevice fdev;
++  nfs_fread_info_t unfinished;
++};
++
++static struct rnfs_struct g_rnfs;
++
++static int device_open(struct inode *inode, struct file *filp)
++{
++  filp->private_data = &g_rnfs;
++
++  return 0;
++}
++
++static ssize_t device_write(struct file *filp, const char *buf,
++                            size_t count, loff_t *off)
++{
++  struct rnfs_struct *rnfs = filp->private_data;
++  //struct rpmsg_channel *rpdev = rnfs->rpdev;
++  unsigned int ret;
++  unsigned int avail;
++  unsigned int unfinished = count;
++  unsigned int cpsize;
++  unsigned int cpsize_total;
++  char *rp = buf;
++
++  //printk("device_write: rp 0x%x unfinished %x\n", rp, unfinished);
++
++  cpsize_total = 0;
++  while(unfinished > 0) {
++    avail = kfifo_avail(&rnfs->fifo);
++    if(avail == 0) {
++      //printk("rpmsg_rnfs_cb: msleep(1000);");
++      msleep(5);
++      cpsize = 0;
++    } else if(avail > unfinished){
++      cpsize = unfinished;
++    } else if(avail <= unfinished) {
++      cpsize = avail;
++    }
++
++    if(cpsize > 0) {
++      ret = kfifo_in_locked(&rnfs->fifo, (char *)rp, cpsize, &rnfs->lock);
++      rp += cpsize;
++      unfinished -= cpsize;
++      cpsize_total += cpsize;
++    }
++    //printk("device_write: avail %x rp 0x%x unfinished %x\n", avail, rp, unfinished);
++  }
++
++  if(cpsize_total != count)
++    printk("rnfs device_write: cpsize_total != count\n");
++
++  return cpsize_total;
++}
++
++int rnfs_test_counter = 0;
++static ssize_t device_read(struct file *filp, char *buf,
++                           size_t len, loff_t *offset)
++{
++  struct rnfs_struct *rnfs = filp->private_data;
++  int bytes_read = 0;
++  // char c;
++  char *vaddr;
++  nfs_fread_info_t nfs_fread_info;
++  int copy_size;
++  int unfinished_size;
++  int ret;
++  int len_remain = len;
++
++  //printk(" ====================== device_read %d ======================\n", rnfs_test_counter);
++
++//rnfs_test_counter ++;
++  if(rnfs_test_counter > 2000) {
++    printk("device_read: force 0\n");
++    rnfs_test_counter = 0;
++    return 0;
++  }
++
++//  while (kfifo_out_locked(&rnfs->fifo, &c, sizeof(c), &rnfs->lock)) {
++//
++//    *buf++ = c;
++//    bytes_read++;
++//  }
++
++//         blocking = filp->??
++
++  while(len_remain > 0) {
++    switch (rnfs->unfinished.count) {
++      case 0:
++        //reload
++//                          while(1) {
++        ret = kfifo_out_locked(&rnfs->fifo, &nfs_fread_info, sizeof(nfs_fread_info_t), &rnfs->lock);
++        //printk("reload: info %d/%d\n", ret, sizeof(nfs_fread_info_t));
++//          //if ret==not ready, sleep
++//          if(ret < sizeof(nfs_fread_info_t))
++//            if(blocking)
++//              sleep();
++//            else return -EAGAIN;
++//          else
++//            break;
++//        }
++        if(ret < sizeof(nfs_fread_info_t)) {
++          msleep(5);
++          //printk("reload: not ready %d\n", ret);
++          break;
++        } else {
++          if(nfs_fread_info.size == 0xdeadbeef) {
++            printk("nfs_fread_info.size == 0xdeadbeef");
++            rnfs_test_counter = 2000000;
++            rpmsg_sendto(rnfs->rpdev, &bytes_read, sizeof(int), rnfs->rpdev->dst); //ack to release fread of iTRON side
++            return 0;
++          }
++          memcpy(&(rnfs->unfinished), &nfs_fread_info, sizeof(nfs_fread_info_t));
++          //printk("reload: x%x %d %d\n", rnfs->unfinished.addr, rnfs->unfinished.size, rnfs->unfinished.count);
++        }
++
++      default:
++        //fill-up buf
++        unfinished_size = rnfs->unfinished.size * rnfs->unfinished.count;
++        copy_size = (len_remain > unfinished_size) ? unfinished_size : len_remain;
++        if(copy_size>0) {
++          vaddr = (void *)ambarella_phys_to_virt((unsigned long)rnfs->unfinished.addr);
++          memcpy(buf, vaddr, copy_size);
++          bytes_read += copy_size;
++          buf += copy_size;
++          unfinished_size -= copy_size;
++
++          if(unfinished_size > 0) {
++            rnfs->unfinished.count = unfinished_size / rnfs->unfinished.size;
++            rnfs->unfinished.addr = (int *)((unsigned int)rnfs->unfinished.addr + copy_size);
++          } else {
++            memset(&(rnfs->unfinished), 0, sizeof(nfs_fread_info_t));
++            rpmsg_sendto(rnfs->rpdev, &bytes_read, sizeof(int), rnfs->rpdev->dst); //ack to release fread of iTRON side
++            //printk("ack\n");
++          }
++          len_remain -= copy_size;
++        }
++        //printk("fillup: %d/%d \n", bytes_read, len);
++    }
++  }
++
++//  while (kfifo_out_locked(&rnfs->fifo, &nfs_fread_info, sizeof(nfs_fread_info_t), &rnfs->lock)) {
++// //     vaddr = ambarella_phys_to_virt(nfs_fread_info.addr);
++// //                 bytes_read += nfs_fread_info.size*nfs_fread_info.count;
++// //                 memcpy(buf, vaddr, nfs_fread_info.size*nfs_fread_info.count);
++// //                 buf += bytes_read;
++//    //printk("device_read: x%x x%x\n", vaddr, bytes_read);
++//    bytes_read = len;
++//  }
++
++  //rpmsg_sendto(g_rnfs.rpdev, &bytes_read, sizeof(int), g_rnfs.rpdev->dst);
++  //printk("device_read: final bytes_read %d/%d \n", bytes_read, len);
++
++  return bytes_read;
++}
++
++static int device_release(struct inode *inode, struct file *file)
++{
++  return 0;
++}
++
++static struct file_operations fops = {
++  .read = device_read,
++  .write = device_write,
++  .open = device_open,
++  .release = device_release
++};
++
++static int rnfs_init(struct rnfs_struct *rnfs)
++{
++  int ret;
++
++  spin_lock_init(&rnfs->lock);
++
++  ret = kfifo_alloc(&rnfs->fifo, 1024*1024*2, GFP_KERNEL);
++  if (ret)
++    return ret;
++
++  printk("RPMSG Read from NFS Server [ARM11] now is ready at /dev/%s\n", DEVICE_NAME);
++
++  rnfs->fdev.name = DEVICE_NAME;
++  rnfs->fdev.fops = &fops;
++  rnfs->fdev.minor = MISC_DYNAMIC_MINOR;
++  memset(&(rnfs->unfinished), 0, sizeof(nfs_fread_info_t));
++  misc_register(&rnfs->fdev);
++
++  return 0;
++}
++
++static void rpmsg_rnfs_cb(struct rpmsg_channel *rpdev, void *data,
++                          int len, void *priv, u32 src)
++{
++  struct rnfs_struct *rnfs = priv;
++  unsigned int ret;
++  unsigned int avail;
++  unsigned int unfinished = len;
++  unsigned int cpsize;
++  unsigned int cpsize_total;
++  char *wp;
++  nfs_fread_info_t *info = data;
++#define EOF_TIMEOUT (20)
++  unsigned int timeout = EOF_TIMEOUT;
++
++  cpsize_total = 0;
++  unfinished = info->size*info->count;
++  printk("rpmsg_rnfs_cb: p 0x%x v 0x%x %x %x\n", info->addr, wp, info->size, info->count);
++  wp = (void *)ambarella_phys_to_virt((unsigned long)info->addr);
++  printk("rpmsg_rnfs_cb: p 0x%x v 0x%x %x %x\n", info->addr, wp, info->size, info->count);
++
++  while(unfinished > 0) {
++    avail = kfifo_len(&rnfs->fifo);
++    if(avail == 0) {
++      //printk("rpmsg_rnfs_cb: msleep(1000);");
++      msleep(5);
++      cpsize = 0;
++      timeout--;
++      if(timeout == 0) {
++        printk("rpmsg_rnfs_cb: could be eof\n");
++	break;
++      }
++    } else if(avail > unfinished){
++      cpsize = unfinished;
++    } else if(avail <= unfinished) {
++      cpsize = avail;
++    }
++
++    if(cpsize > 0) {
++      ret = kfifo_out_locked(&rnfs->fifo, wp, cpsize, &rnfs->lock);
++      wp += cpsize;
++      unfinished -= cpsize;
++      cpsize_total += cpsize;
++    }
++    printk("rpmsg_rnfs_cb: avail %x wp %x, unfinished %x\n", avail, wp, unfinished);
++  }
++
++  if(cpsize_total != info->size*info->count)
++    printk("rnfs rpmsg_rnfs_cb: cpsize_total != count\n");
++
++  //ack to release fread of iTRON side
++  rpmsg_sendto(rnfs->rpdev, &cpsize_total, sizeof(unsigned int), rnfs->rpdev->dst);
++  printk("rnfs rpmsg_rnfs_cb: ack iTRON\n");
++
++}
++
++static int rpmsg_rnfs_probe(struct rpmsg_channel *rpdev)
++{
++  int ret = 0;
++  struct rpmsg_ns_msg nsm;
++  struct rnfs_struct *rnfs = &g_rnfs;
++
++  nsm.addr = rpdev->dst;
++  memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++  nsm.flags = 0;
++
++  rnfs_init(rnfs);
++  rnfs->rpdev = rpdev;
++
++  rpdev->ept->priv = rnfs;
++
++  rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
++
++  return ret;
++}
++
++static void rpmsg_rnfs_remove(struct rpmsg_channel *rpdev)
++{
++  struct rnfs_struct *rnfs = &g_rnfs;
++  misc_deregister(&rnfs->fdev);
++}
++
++static struct rpmsg_device_id rpmsg_rnfs_id_table[] = {
++  { .name = "rnfs_arm11", },
++  { },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_rnfs_id_table);
++
++static struct rpmsg_driver rpmsg_rnfs_driver = {
++  .drv.name = KBUILD_MODNAME,
++  .drv.owner  = THIS_MODULE,
++  .id_table = rpmsg_rnfs_id_table,
++  .probe    = rpmsg_rnfs_probe,
++  .callback = rpmsg_rnfs_cb,
++  .remove   = rpmsg_rnfs_remove,
++};
++
++static int __init rpmsg_rnfs_init(void)
++{
++  return register_rpmsg_driver(&rpmsg_rnfs_driver);
++}
++
++static void __exit rpmsg_rnfs_fini(void)
++{
++  unregister_rpmsg_driver(&rpmsg_rnfs_driver);
++}
++
++module_init(rpmsg_rnfs_init);
++module_exit(rpmsg_rnfs_fini);
++
++MODULE_DESCRIPTION("RPMSG Read from NFS Server");
+diff --git a/drivers/rpmsg/ambarella/host/rsh/Kconfig b/drivers/rpmsg/ambarella/host/rsh/Kconfig
+new file mode 100644
+index 00000000..f89c7e7a
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/rsh/Kconfig
+@@ -0,0 +1,7 @@
++config RPMSG_RSH
++	tristate "Remote Shell"
++	depends on RPMSG
++	select AMBARELLA_RSH
++	help
++	  A Remote shell client for interacting with Itron on ARM11
++	  and Linux on CA9-B
+diff --git a/drivers/rpmsg/ambarella/host/rsh/Makefile b/drivers/rpmsg/ambarella/host/rsh/Makefile
+new file mode 100644
+index 00000000..112c56a6
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/rsh/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_RSH)	+= rpmsg_rsh.o
+diff --git a/drivers/rpmsg/ambarella/host/rsh/rpmsg_rsh.c b/drivers/rpmsg/ambarella/host/rsh/rpmsg_rsh.c
+new file mode 100644
+index 00000000..52ca5f00
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/rsh/rpmsg_rsh.c
+@@ -0,0 +1,106 @@
++/**
++ * History:
++ *    2012/09/15 - [Tzu-Jung Lee] created file
++ *
++ * Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/tty.h>
++#include <linux/remoteproc.h>
++#include <linux/rpmsg.h>
++
++extern int rsh_init_driver(void);
++extern int rsh_init_device(int index, void *rpdev);
++
++extern void rsh_cb(int index, void *data, int len);
++
++int do_rsh_write(void *rpdev, const unsigned char *buf, int count)
++{
++	while (rpmsg_trysend(rpdev, (char*)buf, count))
++		;
++
++	return count;
++}
++
++static void rpmsg_rsh_cb(struct rpmsg_channel *rpdev, void *data,
++				int len, void *priv, u32 src)
++{
++	rsh_cb((int)priv, data, len);
++}
++
++static int rpmsg_rsh_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++	int index;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	if (!strcmp(rpdev->id.name, "rsh_ca9_b"))
++		index = 0;
++	else if (!strcmp(rpdev->id.name, "rsh_arm11"))
++		index = 1;
++	else if (!strcmp(rpdev->id.name, "rsh_ca9_b"))
++		index = 2;
++	else 
++		return -1;
++
++	rpdev->ept->priv = (void*)index;
++
++	rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
++
++	rsh_init_device(index, rpdev);
++
++	return ret;
++}
++
++static void rpmsg_rsh_remove(struct rpmsg_channel *rpdev)
++{
++}
++
++static struct rpmsg_device_id rpmsg_rsh_id_table[] = {
++	{ .name	= "rsh_ca9_b", }, /* H: CA9-A, C: CA9-B */
++	{ .name	= "rsh_arm11", }, /* H: CA9-A, C: ARM11 */
++	{ .name	= "rsh_ca9_a", }, /* H: CA9-B, C: ARM11 */
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_rsh_id_table);
++
++static struct rpmsg_driver rpmsg_rsh_driver =
++{
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_rsh_id_table,
++	.probe		= rpmsg_rsh_probe,
++	.callback	= rpmsg_rsh_cb,
++	.remove		= rpmsg_rsh_remove,
++};
++
++static int __init rpmsg_rsh_init(void)
++{
++	rsh_init_driver();
++
++	return register_rpmsg_driver(&rpmsg_rsh_driver);
++}
++
++static void __exit rpmsg_rsh_fini(void)
++{
++	unregister_rpmsg_driver(&rpmsg_rsh_driver);
++}
++
++module_init(rpmsg_rsh_init);
++module_exit(rpmsg_rsh_fini);
++
++MODULE_DESCRIPTION("RPMSG Remote Shell");
+diff --git a/drivers/rpmsg/ambarella/host/veth/Kconfig b/drivers/rpmsg/ambarella/host/veth/Kconfig
+new file mode 100644
+index 00000000..a315c12e
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/veth/Kconfig
+@@ -0,0 +1,6 @@
++config RPMSG_VETH
++	tristate "Virtual Ethernet"
++	depends on RPMSG
++	select AMBARELLA_VETH
++	help
++	  A virtualized ethernet device over RPMSG bus.
+diff --git a/drivers/rpmsg/ambarella/host/veth/Makefile b/drivers/rpmsg/ambarella/host/veth/Makefile
+new file mode 100644
+index 00000000..8f05d650
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/veth/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_VETH)	+= rpmsg_veth.o
+diff --git a/drivers/rpmsg/ambarella/host/veth/rpmsg_veth.c b/drivers/rpmsg/ambarella/host/veth/rpmsg_veth.c
+new file mode 100644
+index 00000000..71b311c7
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/veth/rpmsg_veth.c
+@@ -0,0 +1,73 @@
++#include <linux/rpmsg.h>
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++extern struct platform_device ambveth_device;
++extern void ambveth_enqueue(void *priv, void *data, int len);
++
++static struct rpmsg_channel *g_rpdev;
++
++int ambveth_do_send(void *data, int len)
++{
++	return rpmsg_trysend(g_rpdev, data, len);
++}
++
++static void rpmsg_veth_server_cb(struct rpmsg_channel *rpdev, void *data, int len,
++			void *priv, u32 src)
++{
++	ambveth_enqueue(priv, data, len);
++}
++
++static int rpmsg_veth_server_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++
++	platform_device_register(&ambveth_device);
++	rpdev->ept->priv = &ambveth_device;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	g_rpdev = rpdev;
++	rpmsg_send(rpdev, &nsm, sizeof(nsm));
++
++	return ret;
++}
++
++static void rpmsg_veth_server_remove(struct rpmsg_channel *rpdev)
++{
++}
++
++static struct rpmsg_device_id rpmsg_veth_server_id_table[] = {
++	{ .name	= "veth_ca9_b", },
++	{ .name	= "veth_arm11", },
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_veth_server_id_table);
++
++struct rpmsg_driver rpmsg_veth_server_driver = {
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_veth_server_id_table,
++	.probe		= rpmsg_veth_server_probe,
++	.callback	= rpmsg_veth_server_cb,
++	.remove		= rpmsg_veth_server_remove,
++};
++
++static int __init rpmsg_veth_server_init(void)
++{
++	return register_rpmsg_driver(&rpmsg_veth_server_driver);
++}
++
++static void __exit rpmsg_veth_server_fini(void)
++{
++	unregister_rpmsg_driver(&rpmsg_veth_server_driver);
++}
++
++module_init(rpmsg_veth_server_init);
++module_exit(rpmsg_veth_server_fini);
++
++MODULE_DESCRIPTION("RPMSG VETH");
+diff --git a/drivers/rpmsg/ambarella/host/vgpio/Kconfig b/drivers/rpmsg/ambarella/host/vgpio/Kconfig
+new file mode 100644
+index 00000000..3ec92c8d
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/vgpio/Kconfig
+@@ -0,0 +1,6 @@
++config RPMSG_VGPIO
++	tristate "Virtual GPIO"
++	depends on RPMSG
++	select AMBARELLA_VGPIO
++	help
++	  A virtualized GPIO device over RPMSG bus.
+diff --git a/drivers/rpmsg/ambarella/host/vgpio/Makefile b/drivers/rpmsg/ambarella/host/vgpio/Makefile
+new file mode 100644
+index 00000000..a1ca3eb2
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/vgpio/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_VGPIO)	+= rpmsg_vgpio.o
+diff --git a/drivers/rpmsg/ambarella/host/vgpio/rpmsg_vgpio.c b/drivers/rpmsg/ambarella/host/vgpio/rpmsg_vgpio.c
+new file mode 100644
+index 00000000..28706dfc
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/vgpio/rpmsg_vgpio.c
+@@ -0,0 +1,579 @@
++/*
++ * arch/arm/plat-ambarella/generic/gpio.c
++ *
++ * History:
++ *	2007/11/21 - [Grady Chen] created file
++ *	2008/01/08 - [Anthony Ginger] Add GENERIC_GPIO support.
++ *	2013/10/19 - [Tzu-Jung Lee] Port to vitrtual GPIO support.
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/device.h>
++#include <linux/seq_file.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/rpmsg.h>
++
++enum VGPIO_CMD {
++
++	VGPIO_REQUEST,
++	VGPIO_RELEASE,
++	VGPIO_QUERY,
++	VGPIO_CONFIG,
++	VGPIO_GET,
++	VGPIO_SET,
++};
++
++struct rpmsg_vgpio_msg {
++
++	int	cmd;
++	int	func;
++	u32	offset;
++	int	value;
++	int	result;
++};
++
++struct vgpio_chip
++{
++	struct gpio_chip	chip;
++	struct mutex		mtx;
++	struct rpmsg_vgpio_msg	msg;
++	struct completion	comp;
++	struct rpmsg_channel	*rpdev;
++};
++
++extern struct vgpio_chip vgpio_chip;
++
++#define to_vgpio_chip(c) \
++	container_of(c, struct vgpio_chip, chip)
++
++void rpmsg_vgpio_do_send(void *data)
++{
++	struct vgpio_chip *vchip = data;
++	struct rpmsg_vgpio_msg *msg = &vchip->msg;
++
++	rpmsg_trysend(vchip->rpdev, msg, sizeof(*msg));
++
++	switch (msg->cmd) {
++	case VGPIO_REQUEST:
++	case VGPIO_RELEASE:
++	case VGPIO_QUERY:
++	case VGPIO_CONFIG:
++	case VGPIO_GET:
++	case VGPIO_SET:
++		wait_for_completion(&vchip->comp);
++		break;
++	default:
++		pr_err("%s: invalid vgpio command %d.\n", __func__, msg->cmd);
++		break;
++	}
++}
++
++static void rpmsg_vgpio_cb(struct rpmsg_channel *rpdev, void *data, int len,
++			   void *priv, u32 src)
++{
++	struct vgpio_chip *vchip = priv;
++	struct rpmsg_vgpio_msg *msg = data;
++
++	vchip->msg = *msg;
++
++	complete(&vchip->comp);
++}
++
++static int rpmsg_vgpio_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++
++	vgpio_chip.rpdev = rpdev;
++	rpdev->ept->priv = &vgpio_chip;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	rpmsg_send(rpdev, &nsm, sizeof(nsm));
++
++	mutex_init(&vgpio_chip.mtx);
++	init_completion(&vgpio_chip.comp);
++
++	ret = gpiochip_add(&vgpio_chip.chip);
++	if (ret)
++		pr_err("%s: gpiochip_add(vgpio)fail %d.\n", __func__, ret);
++
++	return ret;
++}
++
++static void rpmsg_vgpio_remove(struct rpmsg_channel *rpdev)
++{
++}
++
++static struct rpmsg_device_id rpmsg_vgpio_id_table[] = {
++	{ .name	= "vgpio_ca9_a_and_arm11", },
++	{ .name	= "vgpio_ca9_b_and_arm11", },
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_vgpio_id_table);
++
++struct rpmsg_driver rpmsg_vgpio_driver = {
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_vgpio_id_table,
++	.probe		= rpmsg_vgpio_probe,
++	.callback	= rpmsg_vgpio_cb,
++	.remove		= rpmsg_vgpio_remove,
++};
++
++/* ==========================================================================*/
++
++static int __init rpmsg_vgpio_init(void)
++{
++	return register_rpmsg_driver(&rpmsg_vgpio_driver);
++}
++
++static void __exit rpmsg_vgpio_fini(void)
++{
++	unregister_rpmsg_driver(&rpmsg_vgpio_driver);
++}
++
++static int rpmsg_vgpio_request(struct gpio_chip *chip, unsigned offset,
++			       int request)
++{
++	struct vgpio_chip *vchip = to_vgpio_chip(chip);
++	struct rpmsg_vgpio_msg *msg = &vchip->msg;
++	int retval = 0;
++
++	mutex_lock(&vchip->mtx);
++
++	msg->cmd = request ? VGPIO_REQUEST : VGPIO_RELEASE;
++	msg->offset = offset;
++	rpmsg_vgpio_do_send(vchip);
++	retval = msg->result;
++
++	mutex_unlock(&vchip->mtx);
++
++	return retval;
++}
++
++static int rpmsg_vgpio_config(struct gpio_chip *chip, u32 offset, int func)
++{
++	struct vgpio_chip *vchip = to_vgpio_chip(chip);
++	struct rpmsg_vgpio_msg *msg = &vchip->msg;
++	int retval = 0;
++
++	mutex_lock(&vchip->mtx);
++
++	msg->cmd = VGPIO_CONFIG;
++	msg->offset = offset;
++	msg->func = func;
++	rpmsg_vgpio_do_send(vchip);
++	retval = msg->result;
++
++	mutex_unlock(&vchip->mtx);
++
++	return retval;
++}
++
++static int rpmsg_vgpio_query(struct gpio_chip *chip, u32 offset)
++{
++	struct vgpio_chip *vchip = to_vgpio_chip(chip);
++	struct rpmsg_vgpio_msg *msg = &vchip->msg;
++	int retval = 0;
++
++	mutex_lock(&vchip->mtx);
++
++	msg->cmd = VGPIO_QUERY;
++	msg->offset = offset;
++	rpmsg_vgpio_do_send(vchip);
++
++	if (msg->func == GPIO_FUNC_SW_INPUT)
++		retval = 1;
++	else if (msg->func == GPIO_FUNC_SW_OUTPUT)
++		retval = 0;
++	else
++		retval = -EINVAL;
++	mutex_unlock(&vchip->mtx);
++
++	return retval;
++}
++
++static int rpmsg_vgpio_set(struct gpio_chip *chip, u32 offset, int value)
++{
++	struct vgpio_chip *vchip = to_vgpio_chip(chip);
++	struct rpmsg_vgpio_msg *msg = &vchip->msg;
++	int retval = 0;
++
++	mutex_lock(&vchip->mtx);
++
++	msg->cmd = VGPIO_SET;
++	msg->offset = offset;
++	msg->value = value;
++	rpmsg_vgpio_do_send(vchip);
++	retval = msg->result;
++
++	mutex_unlock(&vchip->mtx);
++
++	return retval;
++}
++
++static int rpmsg_vgpio_get(struct gpio_chip *chip, u32 offset)
++{
++	struct vgpio_chip *vchip = to_vgpio_chip(chip);
++	struct rpmsg_vgpio_msg *msg = &vchip->msg;
++	int retval = 0;
++
++	mutex_lock(&vchip->mtx);
++
++	msg->cmd = VGPIO_GET;
++	msg->offset = offset;
++	rpmsg_vgpio_do_send(vchip);
++	retval = msg->value;
++
++	mutex_unlock(&vchip->mtx);
++
++	return retval;
++}
++
++/* ==========================================================================*/
++
++static int rpmsg_vgpio_chip_request(struct gpio_chip *chip, unsigned offset)
++{
++	return rpmsg_vgpio_request(chip, offset, 1);
++}
++
++static void rpmsg_vgpio_chip_free(struct gpio_chip *chip, unsigned offset)
++{
++	rpmsg_vgpio_request(chip, offset, 0);
++}
++
++static int rpmsg_vgpio_chip_get_direction(struct gpio_chip *chip,
++		                          unsigned offset)
++{
++	return rpmsg_vgpio_query(chip, offset);
++}
++
++static int rpmsg_vgpio_chip_direction_input(struct gpio_chip *chip,
++					    unsigned offset)
++{
++	return rpmsg_vgpio_config(chip, offset, GPIO_FUNC_SW_INPUT);
++}
++
++static int rpmsg_vgpio_chip_get(struct gpio_chip *chip, unsigned offset)
++{
++	return rpmsg_vgpio_get(chip, offset);
++}
++
++static int rpmsg_vgpio_chip_direction_output(struct gpio_chip *chip,
++					     unsigned offset, int value)
++{
++	if (rpmsg_vgpio_config(chip, offset, GPIO_FUNC_SW_OUTPUT) < 0)
++		return -1;
++
++	return rpmsg_vgpio_set(chip, offset, value);
++}
++
++static void rpmsg_vgpio_chip_set(struct gpio_chip *chip, unsigned offset,
++				 int value)
++{
++	rpmsg_vgpio_set(chip, offset, value);
++}
++
++static int rpmsg_vgpio_to_irq(struct gpio_chip *chip, unsigned offset)
++{
++	if ((chip->base + offset) < GPIO_MAX_LINES)
++		return GPIO_INT_VEC(chip->base + offset);
++
++	return -EINVAL;
++}
++
++static void rpmsg_vgpio_chip_dbg_show(struct seq_file *s,
++				      struct gpio_chip *chip)
++{
++	struct vgpio_chip *vchip = to_vgpio_chip(chip);
++
++	int value;
++	int dir;
++	int i = 0;
++
++	for (i = 0; i < GPIO_MAX_LINES; i++) {
++		dir = rpmsg_vgpio_query(chip, i);
++		value = rpmsg_vgpio_get(chip, i);
++		seq_printf(s, "%2d:", i);
++		if (dir > 0)
++			seq_printf(s, "  IN, %d\n", value);
++		else if (dir == 0)
++			seq_printf(s, " OUT, %d\n", value);
++		else
++			seq_printf(s, "  HW\n");
++	}
++}
++
++struct vgpio_chip vgpio_chip = {
++
++	.chip = {
++		.label			= "vgpio",
++		.owner			= THIS_MODULE,
++		.request		= rpmsg_vgpio_chip_request,
++		.free			= rpmsg_vgpio_chip_free,
++		.get_direction		= rpmsg_vgpio_chip_get_direction,
++		.direction_input	= rpmsg_vgpio_chip_direction_input,
++		.get			= rpmsg_vgpio_chip_get,
++		.direction_output	= rpmsg_vgpio_chip_direction_output,
++		.set			= rpmsg_vgpio_chip_set,
++		.to_irq			= rpmsg_vgpio_to_irq,
++		.dbg_show		= rpmsg_vgpio_chip_dbg_show,
++		.base			= 0,
++		.ngpio			= AMBGPIO_SIZE,
++		.can_sleep		= 0,
++		.exported		= 0,
++	},
++};
++
++/* ==========================================================================*/
++
++void ambarella_gpio_config(int id, int func)
++{
++	u32 offset = id & 0x1f;
++
++	rpmsg_vgpio_config(&vgpio_chip.chip, offset, func);
++}
++EXPORT_SYMBOL(ambarella_gpio_config);
++
++void ambarella_gpio_set(int id, int value)
++{
++	u32 offset = id & 0x1f;
++
++	rpmsg_vgpio_set(&vgpio_chip.chip, offset, value);
++}
++EXPORT_SYMBOL(ambarella_gpio_set);
++
++int ambarella_gpio_get(int id)
++{
++	u32 offset = id & 0x1f;
++
++	return rpmsg_vgpio_get(&vgpio_chip.chip, offset);
++}
++EXPORT_SYMBOL(ambarella_gpio_get);
++/* ==========================================================================*/
++u32 ambarella_gpio_suspend(u32 level) { return 0; }
++u32 ambarella_gpio_resume(u32 level) { return 0; }
++/* ==========================================================================*/
++
++static void ambarella_gpio_mwait(struct ambarella_gpio_io_info *pinfo,
++				 int can_sleep)
++{
++	if (can_sleep)
++		msleep(pinfo->active_delay);
++	else
++		mdelay(pinfo->active_delay);
++
++}
++int ambarella_set_gpio_output_can_sleep(
++	struct ambarella_gpio_io_info *pinfo, u32 on, int can_sleep)
++{
++	int					retval = 0;
++
++	if (pinfo == NULL) {
++		pr_err("%s: pinfo is NULL.\n", __func__);
++		retval = -1;
++		goto ambarella_set_gpio_output_can_sleep_exit;
++	}
++	if (pinfo->gpio_id < 0 ) {
++		pr_debug("%s: wrong gpio id %d.\n", __func__, pinfo->gpio_id);
++		retval = -1;
++		goto ambarella_set_gpio_output_can_sleep_exit;
++	}
++
++	pr_debug("%s: Gpio[%d] %s, level[%s], delay[%dms].\n", __func__,
++		pinfo->gpio_id, on ? "ON" : "OFF",
++		pinfo->active_level ? "HIGH" : "LOW",
++		pinfo->active_delay);
++	if (pinfo->gpio_id >= EXT_GPIO(0)) {
++		pr_debug("%s: try expander gpio id %d.\n",
++			__func__, pinfo->gpio_id);
++		if (on) {
++			gpio_direction_output(pinfo->gpio_id,
++				pinfo->active_level);
++		} else {
++			gpio_direction_output(pinfo->gpio_id,
++				!pinfo->active_level);
++		}
++	} else {
++		ambarella_gpio_config(pinfo->gpio_id, GPIO_FUNC_SW_OUTPUT);
++		if (on) {
++			ambarella_gpio_set(pinfo->gpio_id,
++				pinfo->active_level);
++		} else {
++			ambarella_gpio_set(pinfo->gpio_id,
++				!pinfo->active_level);
++		}
++	}
++	ambarella_gpio_mwait(pinfo, can_sleep);
++
++ambarella_set_gpio_output_can_sleep_exit:
++	return retval;
++}
++EXPORT_SYMBOL(ambarella_set_gpio_output_can_sleep);
++
++u32 ambarella_get_gpio_input_can_sleep(
++	struct ambarella_gpio_io_info *pinfo, int can_sleep)
++{
++	u32					gpio_value = 0;
++
++	if (pinfo == NULL) {
++		pr_err("%s: pinfo is NULL.\n", __func__);
++		goto ambarella_get_gpio_input_can_sleep_exit;
++	}
++	if (pinfo->gpio_id < 0 ) {
++		pr_debug("%s: wrong gpio id %d.\n", __func__, pinfo->gpio_id);
++		goto ambarella_get_gpio_input_can_sleep_exit;
++	}
++
++	if (pinfo->gpio_id >= EXT_GPIO(0)) {
++		pr_debug("%s: try expander gpio id %d.\n",
++			__func__, pinfo->gpio_id);
++		gpio_direction_input(pinfo->gpio_id);
++		ambarella_gpio_mwait(pinfo, can_sleep);
++		gpio_value = gpio_get_value(pinfo->gpio_id);
++	} else {
++		ambarella_gpio_config(pinfo->gpio_id, GPIO_FUNC_SW_INPUT);
++		ambarella_gpio_mwait(pinfo, can_sleep);
++		gpio_value = ambarella_gpio_get(pinfo->gpio_id);
++	}
++
++	pr_debug("%s: {gpio[%d], level[%s], delay[%dms]} get[%d].\n",
++		__func__, pinfo->gpio_id,
++		pinfo->active_level ? "HIGH" : "LOW",
++		pinfo->active_delay, gpio_value);
++
++ambarella_get_gpio_input_can_sleep_exit:
++	return (gpio_value == pinfo->active_level) ? 1 : 0;
++}
++EXPORT_SYMBOL(ambarella_get_gpio_input_can_sleep);
++
++int ambarella_set_gpio_reset_can_sleep(
++	struct ambarella_gpio_io_info *pinfo, int can_sleep)
++{
++	int					retval = 0;
++
++	if (pinfo == NULL) {
++		pr_err("%s: pinfo is NULL.\n", __func__);
++		retval = -1;
++		goto ambarella_set_gpio_reset_can_sleep_exit;
++	}
++	if (pinfo->gpio_id < 0 ) {
++		pr_debug("%s: wrong gpio id %d.\n", __func__, pinfo->gpio_id);
++		retval = -1;
++		goto ambarella_set_gpio_reset_can_sleep_exit;
++	}
++
++	pr_debug("%s: Reset gpio[%d], level[%s], delay[%dms].\n",
++		__func__, pinfo->gpio_id,
++		pinfo->active_level ? "HIGH" : "LOW",
++		pinfo->active_delay);
++	if (pinfo->gpio_id >= EXT_GPIO(0)) {
++		pr_debug("%s: try expander gpio id %d.\n",
++			__func__, pinfo->gpio_id);
++		gpio_direction_output(pinfo->gpio_id, pinfo->active_level);
++		ambarella_gpio_mwait(pinfo, can_sleep);
++
++		gpio_direction_output(pinfo->gpio_id, !pinfo->active_level);
++		ambarella_gpio_mwait(pinfo, can_sleep);
++	} else {
++		ambarella_gpio_config(pinfo->gpio_id, GPIO_FUNC_SW_OUTPUT);
++		ambarella_gpio_set(pinfo->gpio_id, pinfo->active_level);
++		ambarella_gpio_mwait(pinfo, can_sleep);
++
++		ambarella_gpio_set(pinfo->gpio_id, !pinfo->active_level);
++		ambarella_gpio_mwait(pinfo, can_sleep);
++	}
++
++ambarella_set_gpio_reset_can_sleep_exit:
++	return retval;
++}
++EXPORT_SYMBOL(ambarella_set_gpio_reset_can_sleep);
++
++/* ==========================================================================*/
++int ambarella_set_gpio_output(struct ambarella_gpio_io_info *pinfo, u32 on)
++{
++	return ambarella_set_gpio_output_can_sleep(pinfo, on, 0);
++}
++EXPORT_SYMBOL(ambarella_set_gpio_output);
++
++u32 ambarella_get_gpio_input(struct ambarella_gpio_io_info *pinfo)
++{
++	return ambarella_get_gpio_input_can_sleep(pinfo, 0);
++}
++EXPORT_SYMBOL(ambarella_get_gpio_input);
++
++int ambarella_set_gpio_reset(struct ambarella_gpio_io_info *pinfo)
++{
++	return ambarella_set_gpio_reset_can_sleep(pinfo, 0);
++}
++EXPORT_SYMBOL(ambarella_set_gpio_reset);
++
++int ambarella_is_valid_gpio_irq(struct ambarella_gpio_irq_info *pinfo)
++{
++	int bvalid = 0;
++
++	if (pinfo == NULL) {
++		pr_err("%s: pinfo is NULL.\n", __func__);
++		goto ambarella_is_valid_gpio_irq_exit;
++	}
++
++	if ((pinfo->irq_gpio < 0 ) || (pinfo->irq_gpio >= ARCH_NR_GPIOS))
++		goto ambarella_is_valid_gpio_irq_exit;
++
++	if ((pinfo->irq_type != IRQ_TYPE_EDGE_RISING) &&
++		(pinfo->irq_type != IRQ_TYPE_EDGE_FALLING) &&
++		(pinfo->irq_type != IRQ_TYPE_EDGE_BOTH) &&
++		(pinfo->irq_type != IRQ_TYPE_LEVEL_HIGH) &&
++		(pinfo->irq_type != IRQ_TYPE_LEVEL_LOW))
++		goto ambarella_is_valid_gpio_irq_exit;
++
++	if ((pinfo->irq_gpio_val != GPIO_HIGH) &&
++		(pinfo->irq_gpio_val != GPIO_LOW))
++		goto ambarella_is_valid_gpio_irq_exit;
++
++	if ((pinfo->irq_gpio_mode != GPIO_FUNC_SW_INPUT) &&
++		(pinfo->irq_gpio_mode != GPIO_FUNC_SW_OUTPUT) &&
++		(pinfo->irq_gpio_mode != GPIO_FUNC_HW))
++		goto ambarella_is_valid_gpio_irq_exit;
++
++	if ((pinfo->irq_gpio_mode != GPIO_FUNC_HW) &&
++		((pinfo->irq_line < GPIO_INT_VEC(0)) ||
++		(pinfo->irq_line >= NR_IRQS)))
++		goto ambarella_is_valid_gpio_irq_exit;
++
++	bvalid = 1;
++
++ambarella_is_valid_gpio_irq_exit:
++	return bvalid;
++}
++EXPORT_SYMBOL(ambarella_is_valid_gpio_irq);
++
++module_init(rpmsg_vgpio_init);
++module_exit(rpmsg_vgpio_fini);
++
++MODULE_DESCRIPTION("RPMSG VGPIO");
+diff --git a/drivers/rpmsg/ambarella/host/wnfs/Kconfig b/drivers/rpmsg/ambarella/host/wnfs/Kconfig
+new file mode 100644
+index 00000000..0dd1884e
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/wnfs/Kconfig
+@@ -0,0 +1,6 @@
++config RPMSG_WNFS
++	tristate "Write to NFS Server"
++	depends on RPMSG
++	depends on !RPMSG_AMBXC
++	help
++	  A sample of rpmsg program which implement an echo server
+diff --git a/drivers/rpmsg/ambarella/host/wnfs/Makefile b/drivers/rpmsg/ambarella/host/wnfs/Makefile
+new file mode 100644
+index 00000000..3b132131
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/wnfs/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RPMSG_WNFS)	+= rpmsg_wnfs.o
+diff --git a/drivers/rpmsg/ambarella/host/wnfs/rpmsg_wnfs.c b/drivers/rpmsg/ambarella/host/wnfs/rpmsg_wnfs.c
+new file mode 100644
+index 00000000..35ccb819
+--- /dev/null
++++ b/drivers/rpmsg/ambarella/host/wnfs/rpmsg_wnfs.c
+@@ -0,0 +1,266 @@
++/*
++ * rpmsg write to nfs server driver
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/rpmsg.h>
++#include <linux/err.h>
++#include <linux/remoteproc.h>
++
++#include <linux/poll.h>
++#include <linux/uaccess.h>
++#include <linux/miscdevice.h>
++#include <linux/kfifo.h>
++
++#include <linux/virtio_ring.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++
++#define DEVICE_NAME "wnfs"
++
++
++typedef int redev_nfs_FILE;
++typedef struct nfs_fwrite_info_s
++{
++	int* addr;
++	int size;
++	int count;
++	redev_nfs_FILE *file;
++}
++nfs_fwrite_info_t;
++
++struct wnfs_struct {
++	struct kfifo		fifo;
++	spinlock_t		lock;
++	struct rpmsg_channel	*rpdev;
++	struct miscdevice fdev;
++        nfs_fwrite_info_t unfinished;
++};
++
++static struct wnfs_struct g_wnfs;
++
++static int device_open(struct inode *inode, struct file *filp)
++{
++	filp->private_data = &g_wnfs;
++
++	return 0;
++}
++
++static ssize_t device_write(struct file *filp, const char *buf,
++			    size_t count, loff_t * off)
++{
++	struct wnfs_struct *wnfs = filp->private_data;
++	struct rpmsg_channel *rpdev = wnfs->rpdev;
++
++	rpmsg_sendto(rpdev, (void *)buf, count, rpdev->dst);
++
++	return count;
++}
++
++int wnfs_test_counter = 0;
++static ssize_t device_read(struct file *filp, char *buf,
++			   size_t len, loff_t * offset)
++{
++	struct wnfs_struct *wnfs = filp->private_data;
++	int bytes_read = 0;
++	// char c;
++	char *vaddr;
++	nfs_fwrite_info_t nfs_fwrite_info;
++	int copy_size;
++	int unfinished_size;
++	int ret;
++	int len_remain = len;
++
++	//printk(" ====================== device_read %d ======================\n", wnfs_test_counter);
++
++//wnfs_test_counter ++;
++if(wnfs_test_counter > 2000)
++{
++	printk("device_read: force 0\n");
++	wnfs_test_counter = 0;
++	return 0;
++}
++
++// 	while (kfifo_out_locked(&wnfs->fifo, &c, sizeof(c), &wnfs->lock)) {
++//
++// 		*buf++ = c;
++// 		bytes_read++;
++// 	}
++
++//         blocking = filp->??
++
++	while(len_remain > 0) {
++		switch (wnfs->unfinished.count) {
++			case 0:
++	                //reload
++// 	                        while(1) {
++				ret = kfifo_out_locked(&wnfs->fifo, &nfs_fwrite_info, sizeof(nfs_fwrite_info_t), &wnfs->lock);
++				//printk("reload: info %d/%d\n", ret, sizeof(nfs_fwrite_info_t));
++// 					//if ret==not ready, sleep
++// 					if(ret < sizeof(nfs_fwrite_info_t))
++// 						if(blocking)
++// 							sleep();
++// 						else return -EAGAIN;
++// 					else
++// 						break;
++// 				}
++                                if(ret < sizeof(nfs_fwrite_info_t)) {
++					msleep(5);
++                                        //printk("reload: not ready %d\n", ret);
++					break;
++				} else {
++                                        if(nfs_fwrite_info.size == 0xdeadbeef) {
++						printk("nfs_fwrite_info.size == 0xdeadbeef");
++						wnfs_test_counter = 2000000;
++						rpmsg_sendto(wnfs->rpdev, &bytes_read, sizeof(int), wnfs->rpdev->dst); //ack to release fread of iTRON side
++						return 0;
++					}
++					memcpy(&(wnfs->unfinished), &nfs_fwrite_info, sizeof(nfs_fwrite_info_t));
++					//printk("reload: x%x %d %d\n", wnfs->unfinished.addr, wnfs->unfinished.size, wnfs->unfinished.count);
++				}
++
++			default:
++			//fill-up buf
++				unfinished_size = wnfs->unfinished.size * wnfs->unfinished.count;
++				copy_size = (len_remain > unfinished_size) ? unfinished_size : len_remain;
++				if(copy_size>0)
++				{
++					vaddr = (void*)ambarella_phys_to_virt((unsigned long)wnfs->unfinished.addr);
++					memcpy(buf, vaddr, copy_size);
++					bytes_read += copy_size;
++					buf += copy_size;
++					unfinished_size -= copy_size;
++
++					if(unfinished_size > 0) {
++						wnfs->unfinished.count = unfinished_size / wnfs->unfinished.size;
++						wnfs->unfinished.addr = (int*)((unsigned int)wnfs->unfinished.addr + copy_size);
++					} else {
++						memset(&(wnfs->unfinished), 0, sizeof(nfs_fwrite_info_t));
++						rpmsg_sendto(wnfs->rpdev, &bytes_read, sizeof(int), wnfs->rpdev->dst); //ack to release fread of iTRON side
++						//printk("ack\n");
++					}
++					len_remain -= copy_size;
++				}
++                                //printk("fillup: %d/%d \n", bytes_read, len);
++		}
++	}
++
++// 	while (kfifo_out_locked(&wnfs->fifo, &nfs_fwrite_info, sizeof(nfs_fwrite_info_t), &wnfs->lock)) {
++// // 		vaddr = ambarella_phys_to_virt(nfs_fwrite_info.addr);
++// //                 bytes_read += nfs_fwrite_info.size*nfs_fwrite_info.count;
++// //                 memcpy(buf, vaddr, nfs_fwrite_info.size*nfs_fwrite_info.count);
++// //                 buf += bytes_read;
++// 		//printk("device_read: x%x x%x\n", vaddr, bytes_read);
++// 		bytes_read = len;
++// 	}
++
++        //rpmsg_sendto(g_wnfs.rpdev, &bytes_read, sizeof(int), g_wnfs.rpdev->dst);
++        //printk("device_read: final bytes_read %d/%d \n", bytes_read, len);
++
++	return bytes_read;
++}
++
++static int device_release(struct inode *inode, struct file *file)
++{
++	return 0;
++}
++
++static struct file_operations fops = {
++	.read = device_read,
++	.write = device_write,
++	.open = device_open,
++	.release = device_release
++};
++
++static int wnfs_init(struct wnfs_struct *wnfs)
++{
++	int ret;
++
++	spin_lock_init(&wnfs->lock);
++
++        ret = kfifo_alloc(&wnfs->fifo, 4096*16, GFP_KERNEL);
++        if (ret)
++                return ret;
++
++	printk("RPMSG Write to NFS Server [ARM11] now is ready at /dev/%s\n", DEVICE_NAME);
++
++	wnfs->fdev.name = DEVICE_NAME;
++	wnfs->fdev.fops = &fops;
++        memset(&(wnfs->unfinished), 0, sizeof(nfs_fwrite_info_t));
++	misc_register(&wnfs->fdev);
++
++	return 0;
++}
++
++static void rpmsg_wnfs_cb(struct rpmsg_channel *rpdev, void *data,
++				int len, void *priv, u32 src)
++{
++	struct wnfs_struct *wnfs = priv;
++	int n;
++        //printk("rpmsg_wnfs_cb +\n");
++
++	n = kfifo_in_locked(&wnfs->fifo, (char *)data, len, &wnfs->lock);
++	//printk("rpmsg_wnfs_cb -:%d\n", n);
++//rpmsg_sendto(rpdev, &len, sizeof(int), rpdev->dst);
++}
++
++static int rpmsg_wnfs_probe(struct rpmsg_channel *rpdev)
++{
++	int ret = 0;
++	struct rpmsg_ns_msg nsm;
++	struct wnfs_struct *wnfs = &g_wnfs;
++
++	nsm.addr = rpdev->dst;
++	memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
++	nsm.flags = 0;
++
++	wnfs_init(wnfs);
++	wnfs->rpdev = rpdev;
++
++	rpdev->ept->priv = wnfs;
++
++	rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
++
++	return ret;
++}
++
++static void rpmsg_wnfs_remove(struct rpmsg_channel *rpdev)
++{
++	struct wnfs_struct *wnfs = &g_wnfs;
++	misc_deregister(&wnfs->fdev);
++}
++
++static struct rpmsg_device_id rpmsg_wnfs_id_table[] = {
++	{ .name	= "wnfs_arm11", },
++	{ },
++};
++MODULE_DEVICE_TABLE(rpmsg, rpmsg_wnfs_id_table);
++
++static struct rpmsg_driver rpmsg_wnfs_driver = {
++	.drv.name	= KBUILD_MODNAME,
++	.drv.owner	= THIS_MODULE,
++	.id_table	= rpmsg_wnfs_id_table,
++	.probe		= rpmsg_wnfs_probe,
++	.callback	= rpmsg_wnfs_cb,
++	.remove		= rpmsg_wnfs_remove,
++};
++
++static int __init rpmsg_wnfs_init(void)
++{
++	return register_rpmsg_driver(&rpmsg_wnfs_driver);
++}
++
++static void __exit rpmsg_wnfs_fini(void)
++{
++	unregister_rpmsg_driver(&rpmsg_wnfs_driver);
++}
++
++module_init(rpmsg_wnfs_init);
++module_exit(rpmsg_wnfs_fini);
++
++MODULE_DESCRIPTION("RPMSG Write to NFS Server");
+diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
+index b6135d4d..403d0f30 100644
+--- a/drivers/rpmsg/virtio_rpmsg_bus.c
++++ b/drivers/rpmsg/virtio_rpmsg_bus.c
+@@ -33,6 +33,8 @@
+ #include <linux/wait.h>
+ #include <linux/rpmsg.h>
+ #include <linux/mutex.h>
++#include <linux/remoteproc.h>
++#include <plat/remoteproc.h>
+ 
+ /**
+  * struct virtproc_info - virtual remote processor state
+@@ -62,7 +64,11 @@ struct virtproc_info {
+ 	void *rbufs, *sbufs;
+ 	int last_sbuf;
+ 	dma_addr_t bufs_dma;
++#if defined(CONFIG_RPMSG_TX_SPINLOCK)
++	spinlock_t tx_lock;
++#else
+ 	struct mutex tx_lock;
++#endif
+ 	struct idr endpoints;
+ 	struct mutex endpoints_lock;
+ 	wait_queue_head_t sendq;
+@@ -82,6 +88,13 @@ struct rpmsg_channel_info {
+ 	u32 dst;
+ };
+ 
++#if defined(CONFIG_RPMSG_TX_SPINLOCK)
++#define rpmsg_tx_lock(x)	spin_lock_irq(x)
++#define rpmsg_tx_unlock(x)	spin_unlock_irq(x)
++#else
++#define rpmsg_tx_lock(x)	mutex_lock(x)
++#define rpmsg_tx_unlock(x)	mutex_unlock(x)
++#endif
+ #define to_rpmsg_channel(d) container_of(d, struct rpmsg_channel, dev)
+ #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
+ 
+@@ -102,8 +115,14 @@ struct rpmsg_channel_info {
+  * can change this without changing anything in the firmware of the remote
+  * processor.
+  */
+-#define RPMSG_NUM_BUFS		(512)
+-#define RPMSG_BUF_SIZE		(512)
++
++/*
++ * Keep the following sync'ed to the copy which shared between processors
++ *     arch/arm/plat-ambarella/include/plat/remoteproc_cfg.h
++ */
++#define RPMSG_NUM_BUFS		(CONFIG_RPMSG_NUM_BUFS)
++#define RPMSG_BUF_SIZE		(CONFIG_RPMSG_BUF_SIZE)
++
+ #define RPMSG_TOTAL_BUF_SPACE	(RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+ 
+ /*
+@@ -573,7 +592,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
+ 	void *ret;
+ 
+ 	/* support multiple concurrent senders */
+-	mutex_lock(&vrp->tx_lock);
++	rpmsg_tx_lock(&vrp->tx_lock);
+ 
+ 	/*
+ 	 * either pick the next unused tx buffer
+@@ -585,7 +604,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
+ 	else
+ 		ret = virtqueue_get_buf(vrp->svq, &len);
+ 
+-	mutex_unlock(&vrp->tx_lock);
++	rpmsg_tx_unlock(&vrp->tx_lock);
+ 
+ 	return ret;
+ }
+@@ -609,14 +628,14 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
+ static void rpmsg_upref_sleepers(struct virtproc_info *vrp)
+ {
+ 	/* support multiple concurrent senders */
+-	mutex_lock(&vrp->tx_lock);
++	rpmsg_tx_lock(&vrp->tx_lock);
+ 
+ 	/* are we the first sleeping context waiting for tx buffers ? */
+ 	if (atomic_inc_return(&vrp->sleepers) == 1)
+ 		/* enable "tx-complete" interrupts before dozing off */
+ 		virtqueue_enable_cb(vrp->svq);
+ 
+-	mutex_unlock(&vrp->tx_lock);
++	rpmsg_tx_unlock(&vrp->tx_lock);
+ }
+ 
+ /**
+@@ -636,14 +655,14 @@ static void rpmsg_upref_sleepers(struct virtproc_info *vrp)
+ static void rpmsg_downref_sleepers(struct virtproc_info *vrp)
+ {
+ 	/* support multiple concurrent senders */
+-	mutex_lock(&vrp->tx_lock);
++	rpmsg_tx_lock(&vrp->tx_lock);
+ 
+ 	/* are we the last sleeping context waiting for tx buffers ? */
+ 	if (atomic_dec_and_test(&vrp->sleepers))
+ 		/* disable "tx-complete" interrupts */
+ 		virtqueue_disable_cb(vrp->svq);
+ 
+-	mutex_unlock(&vrp->tx_lock);
++	rpmsg_tx_unlock(&vrp->tx_lock);
+ }
+ 
+ /**
+@@ -749,12 +768,14 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+ 	dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n",
+ 					msg->src, msg->dst, msg->len,
+ 					msg->flags, msg->reserved);
++#if 0
+ 	print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1,
+ 					msg, sizeof(*msg) + msg->len, true);
++#endif
+ 
+ 	sg_init_one(&sg, msg, sizeof(*msg) + len);
+ 
+-	mutex_lock(&vrp->tx_lock);
++	rpmsg_tx_lock(&vrp->tx_lock);
+ 
+ 	/* add message to the remote processor's virtqueue */
+ 	err = virtqueue_add_outbuf(vrp->svq, &sg, 1, msg, GFP_KERNEL);
+@@ -771,7 +792,7 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+ 	/* tell the remote processor it has a pending message to read */
+ 	virtqueue_kick(vrp->svq);
+ out:
+-	mutex_unlock(&vrp->tx_lock);
++	rpmsg_tx_unlock(&vrp->tx_lock);
+ 	return err;
+ }
+ EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
+@@ -786,8 +807,10 @@ static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
+ 	dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
+ 					msg->src, msg->dst, msg->len,
+ 					msg->flags, msg->reserved);
++#if 0
+ 	print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
+ 					msg, sizeof(*msg) + msg->len, true);
++#endif
+ 
+ 	/*
+ 	 * We currently use fixed-sized buffers, so trivially sanitize
+@@ -942,6 +965,9 @@ static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len,
+ 
+ static int rpmsg_probe(struct virtio_device *vdev)
+ {
++	struct rproc *rproc = vdev_to_rproc(vdev);
++	struct ambarella_rproc_pdata *pdata;
++
+ 	vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done };
+ 	const char *names[] = { "input", "output" };
+ 	struct virtqueue *vqs[2];
+@@ -957,7 +983,11 @@ static int rpmsg_probe(struct virtio_device *vdev)
+ 
+ 	idr_init(&vrp->endpoints);
+ 	mutex_init(&vrp->endpoints_lock);
++#if defined(CONFIG_RPMSG_TX_SPINLOCK)
++	spin_lock_init(&vrp->tx_lock);
++#else
+ 	mutex_init(&vrp->tx_lock);
++#endif
+ 	init_waitqueue_head(&vrp->sendq);
+ 
+ 	/* We expect two virtqueues, rx and tx (and in this order) */
+@@ -968,10 +998,15 @@ static int rpmsg_probe(struct virtio_device *vdev)
+ 	vrp->rvq = vqs[0];
+ 	vrp->svq = vqs[1];
+ 
++#if 0
+ 	/* allocate coherent memory for the buffers */
+ 	bufs_va = dma_alloc_coherent(vdev->dev.parent->parent,
+ 				RPMSG_TOTAL_BUF_SPACE,
+ 				&vrp->bufs_dma, GFP_KERNEL);
++#else
++	pdata = rproc->priv;
++	bufs_va = (void *)ambarella_phys_to_virt((unsigned long)pdata->buf_addr_pa);
++#endif
+ 	if (!bufs_va) {
+ 		err = -ENOMEM;
+ 		goto vqs_del;
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index b9838130..2e49c5ee 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1092,6 +1092,12 @@ config RTC_DRV_MV
+ 	  This driver can also be built as a module. If so, the module
+ 	  will be called rtc-mv.
+ 
++config RTC_DRV_AMBARELLA
++	tristate "Ambarella SoC RTC"
++	depends on PLAT_AMBARELLA
++	help
++	  RTC (Realtime Clock) driver for Ambarella SoC.
++
+ config RTC_DRV_PS3
+ 	tristate "PS3 RTC"
+ 	depends on PPC_PS3
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index c33f86f1..fefba95d 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -20,6 +20,7 @@ obj-$(CONFIG_RTC_DRV_88PM860X)  += rtc-88pm860x.o
+ obj-$(CONFIG_RTC_DRV_88PM80X)	+= rtc-88pm80x.o
+ obj-$(CONFIG_RTC_DRV_AB3100)	+= rtc-ab3100.o
+ obj-$(CONFIG_RTC_DRV_AB8500)	+= rtc-ab8500.o
++obj-$(CONFIG_RTC_DRV_AMBARELLA)	+= rtc-ambarella.o
+ obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
+ obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
+ obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
+diff --git a/drivers/rtc/rtc-ambarella.c b/drivers/rtc/rtc-ambarella.c
+new file mode 100644
+index 00000000..c8203ae5
+--- /dev/null
++++ b/drivers/rtc/rtc-ambarella.c
+@@ -0,0 +1,375 @@
++/*
++ * drivers/rtc/ambarella_rtc.c
++ *
++ * History:
++ *	2008/04/01 - [Cao Rongrong] Support pause and resume
++ *	2009/01/22 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/rtc.h>
++#include <linux/bcd.h>
++#include <linux/clk.h>
++#include <asm/uaccess.h>
++#include <mach/hardware.h>
++#include <plat/rtc.h>
++
++#define AMBRTC_TIME		0
++#define AMBRTC_ALARM		1
++
++struct ambarella_rtc {
++	struct rtc_device 	*rtc;
++	void __iomem		*reg;
++	struct device		*dev;
++
++	/* limitation for old rtc:
++	 * 1. cannot detect power lost
++	 * 2. the msb 2bits are reserved. */
++	bool			is_limited;
++	int			irq;
++};
++
++
++static inline void ambrtc_reset_rtc(struct ambarella_rtc *ambrtc)
++{
++	u32 delay = ambrtc->is_limited ? 3 : 1;
++
++	amba_writel(ambrtc->reg + RTC_RESET_OFFSET, 0x01);
++	msleep(delay);
++	amba_writel(ambrtc->reg + RTC_RESET_OFFSET, 0x00);
++	msleep(delay);
++}
++
++static int ambrtc_get_alarm_or_time(struct ambarella_rtc *ambrtc,
++		int time_alarm)
++{
++	u32 reg_offs, val_sec;
++
++	if (time_alarm == AMBRTC_TIME)
++		reg_offs = RTC_CURT_OFFSET;
++	else
++		reg_offs = RTC_ALAT_OFFSET;
++
++	val_sec = amba_readl(ambrtc->reg + reg_offs);
++	/* because old rtc cannot use the msb 2bits, we add 0x40000000
++	 * here, this is a pure software workaround. And the result is that
++	 * the time must be started at least from 2004.01.10 13:38:00 */
++	if (ambrtc->is_limited)
++		val_sec |= 0x40000000;
++
++	return val_sec;
++}
++
++static int ambrtc_set_alarm_or_time(struct ambarella_rtc *ambrtc,
++		int time_alarm, unsigned long secs)
++{
++	u32 time_val, alarm_val;
++
++	if (ambrtc->is_limited && secs < 0x40000000) {
++		dev_err(ambrtc->dev,
++			"Invalid date[0x%lx](2004.01.10 13:38:00 ~ )\n", secs);
++		return -EINVAL;
++	}
++
++	if (time_alarm == AMBRTC_TIME) {
++		time_val = secs;
++		alarm_val = amba_readl(ambrtc->reg + RTC_ALAT_OFFSET);
++	} else {
++		alarm_val = secs;
++		time_val = amba_readl(ambrtc->reg + RTC_CURT_OFFSET);
++                // only for wakeup ambarella internal PWC
++                amba_writel(ambrtc->reg + RTC_PWC_SET_STATUS_OFFSET, 0x28);
++	}
++
++	if (ambrtc->is_limited) {
++		time_val &= 0x3fffffff;
++		alarm_val &= 0x3fffffff;
++	}
++
++	amba_writel(ambrtc->reg + RTC_POS0_OFFSET, 0x80);
++	amba_writel(ambrtc->reg + RTC_POS1_OFFSET, 0x80);
++	amba_writel(ambrtc->reg + RTC_POS2_OFFSET, 0x80);
++
++	/* reset time and alarm to 0 first */
++	amba_writel(ambrtc->reg + RTC_PWC_ALAT_OFFSET, 0x0);
++	amba_writel(ambrtc->reg + RTC_PWC_CURT_OFFSET, 0x0);
++	ambrtc_reset_rtc(ambrtc);
++
++	/* now write the required value to time or alarm */
++	amba_writel(ambrtc->reg + RTC_PWC_CURT_OFFSET, time_val);
++	amba_writel(ambrtc->reg + RTC_PWC_ALAT_OFFSET, alarm_val);
++	ambrtc_reset_rtc(ambrtc);
++
++	return 0;
++}
++
++static int ambrtc_read_time(struct device *dev, struct rtc_time *tm)
++{
++	struct ambarella_rtc *ambrtc;
++	u32 time_sec;
++
++	ambrtc = dev_get_drvdata(dev);
++
++	time_sec = ambrtc_get_alarm_or_time(ambrtc, AMBRTC_TIME);
++
++	rtc_time_to_tm(time_sec, tm);
++
++	return 0;
++}
++
++static int ambrtc_set_mmss(struct device *dev, unsigned long secs)
++{
++	struct ambarella_rtc *ambrtc;
++
++	ambrtc = dev_get_drvdata(dev);
++
++	return ambrtc_set_alarm_or_time(ambrtc, AMBRTC_TIME, secs);
++}
++
++
++static int ambrtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++	struct ambarella_rtc *ambrtc;
++	u32 alarm_sec, time_sec;
++	u32 rtc_status;
++
++	ambrtc = dev_get_drvdata(dev);
++
++	alarm_sec = ambrtc_get_alarm_or_time(ambrtc, AMBRTC_ALARM);
++	rtc_time_to_tm(alarm_sec, &alrm->time);
++
++	time_sec = ambrtc_get_alarm_or_time(ambrtc, AMBRTC_TIME);
++	alrm->enabled = alarm_sec > time_sec;
++
++	rtc_status = amba_readl(ambrtc->reg + RTC_STATUS_OFFSET);
++	alrm->pending = !!(rtc_status & RTC_STATUS_ALA_WK);
++
++	return 0;
++}
++
++static int ambrtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++	struct ambarella_rtc *ambrtc;
++	unsigned long alarm_sec;
++
++	ambrtc = dev_get_drvdata(dev);
++
++	rtc_tm_to_time(&alrm->time, &alarm_sec);
++
++	return ambrtc_set_alarm_or_time(ambrtc, AMBRTC_ALARM, alarm_sec);
++}
++
++static int ambrtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++	return 0;
++}
++
++static irqreturn_t ambrtc_alarm_irq(int irq, void *dev_id)
++{
++	struct ambarella_rtc *ambrtc = (struct ambarella_rtc *)dev_id;
++
++	if(ambrtc->rtc)
++		rtc_update_irq(ambrtc->rtc, 1, RTC_IRQF | RTC_AF);
++
++	return IRQ_HANDLED;
++}
++
++static int ambrtc_ioctl(struct device *dev, unsigned int cmd,
++			     unsigned long arg)
++{
++	struct ambarella_rtc *ambrtc;
++	int lbat, rval = 0;
++
++	ambrtc = dev_get_drvdata(dev);
++
++	if (ambrtc->is_limited)
++		return -ENOIOCTLCMD;
++
++	switch (cmd) {
++	case RTC_VL_READ:
++		lbat = !!amba_readl(ambrtc->reg + RTC_PWC_LBAT_OFFSET);
++		rval = put_user(lbat, (int __user *)arg);
++		break;
++	default:
++		rval = -ENOIOCTLCMD;
++		break;
++	}
++
++	return rval;
++}
++
++static const struct rtc_class_ops ambarella_rtc_ops = {
++	.ioctl		= ambrtc_ioctl,
++	.read_time	= ambrtc_read_time,
++	.set_mmss	= ambrtc_set_mmss,
++	.read_alarm	= ambrtc_read_alarm,
++	.set_alarm	= ambrtc_set_alarm,
++	.alarm_irq_enable = ambrtc_alarm_irq_enable,
++};
++
++static void ambrtc_check_power_lost(struct ambarella_rtc *ambrtc)
++{
++	u32 status, need_rst, time_sec;
++
++	if (ambrtc->is_limited) {
++		status = amba_readl(ambrtc->reg + RTC_STATUS_OFFSET);
++		need_rst = !(status & RTC_STATUS_PC_RST);
++	} else {
++		status = amba_readl(ambrtc->reg + RTC_PWC_REG_STA_OFFSET);
++		need_rst = !(status & RTC_PWC_LOSS_MASK);
++		amba_setbitsl(ambrtc->reg + RTC_PWC_SET_STATUS_OFFSET,
++							RTC_PWC_LOSS_MASK);
++	}
++
++	if (need_rst) {
++		dev_warn(ambrtc->dev, "=====RTC ever lost power=====\n");
++		time_sec = ambrtc->is_limited ? 0x40000000 : 0;
++		ambrtc_set_alarm_or_time(ambrtc, AMBRTC_TIME, time_sec);
++	}
++}
++
++
++static int ambrtc_probe(struct platform_device *pdev)
++{
++	struct ambarella_rtc *ambrtc;
++	struct resource *mem;
++	void __iomem *reg;
++	int ret;
++	unsigned int wakeup_support;
++	struct device_node *np = pdev->dev.of_node;
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	reg = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
++	if (!reg) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	ambrtc = devm_kzalloc(&pdev->dev, sizeof(*ambrtc), GFP_KERNEL);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "no memory!\n");
++		return -ENOMEM;
++	}
++
++	ambrtc->irq = platform_get_irq(pdev, 0);
++	if (ambrtc->irq < 0) {
++		ambrtc->irq = -1;
++	} else {
++		ret = devm_request_irq(&pdev->dev, ambrtc->irq, ambrtc_alarm_irq, IRQF_SHARED,
++					"rtc alarm", ambrtc);
++		if (ret) {
++			dev_err(&pdev->dev, "could not request irq %d for rtc alarm\n", ambrtc->irq);
++			return ret;
++		}
++	}
++
++	ambrtc->reg = reg;
++	ambrtc->dev = &pdev->dev;
++	ambrtc->is_limited = !!of_find_property(pdev->dev.of_node,
++				"amb,is-limited", NULL);
++	platform_set_drvdata(pdev, ambrtc);
++	ambrtc_check_power_lost(ambrtc);
++
++	wakeup_support = !!of_get_property(np, "rtc,wakeup", NULL);
++	if (wakeup_support)
++		device_set_wakeup_capable(&pdev->dev, 1);
++
++	ambrtc->rtc = devm_rtc_device_register(&pdev->dev, "rtc-ambarella",
++				     &ambarella_rtc_ops, THIS_MODULE);
++	if (IS_ERR(ambrtc->rtc)) {
++		dev_err(&pdev->dev, "devm_rtc_device_register fail.\n");
++		return PTR_ERR(ambrtc->rtc);
++	}
++
++	ambrtc->rtc->uie_unsupported = 1;
++
++	return 0;
++}
++
++static int ambrtc_remove(struct platform_device *pdev)
++{
++	platform_set_drvdata(pdev, NULL);
++
++	return 0;
++}
++
++static const struct of_device_id ambarella_rtc_dt_ids[] = {
++	{.compatible = "ambarella,rtc", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_rtc_dt_ids);
++
++#ifdef CONFIG_PM_SLEEP
++static int ambarella_rtc_suspend(struct device *dev)
++{
++	struct ambarella_rtc *ambrtc = dev_get_drvdata(dev);
++
++	if (device_may_wakeup(dev)){
++		if (ambrtc->irq != -1)
++			enable_irq_wake(ambrtc->irq);
++	}
++
++	return 0;
++}
++
++static int ambarella_rtc_resume(struct device *dev)
++{
++	struct ambarella_rtc *ambrtc = dev_get_drvdata(dev);
++
++	if (device_may_wakeup(dev)) {
++		if (ambrtc->irq != -1)
++			disable_irq_wake(ambrtc->irq);
++	}
++	return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(ambarella_rtc_pm_ops, ambarella_rtc_suspend, ambarella_rtc_resume);
++
++static struct platform_driver ambarella_rtc_driver = {
++	.probe		= ambrtc_probe,
++	.remove		= ambrtc_remove,
++	.driver		= {
++		.name	= "ambarella-rtc",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_rtc_dt_ids,
++		.pm	= &ambarella_rtc_pm_ops,
++	},
++};
++
++module_platform_driver(ambarella_rtc_driver);
++
++MODULE_DESCRIPTION("Ambarella Onchip RTC Driver");
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 92a9345d..f6b1f019 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -49,6 +49,15 @@ config SPI_MASTER
+ 	  controller and the protocol drivers for the SPI slave chips
+ 	  that are connected.
+ 
++config SPI_SLAVE
++#       boolean "SPI Slave Support"
++        boolean
++        default SPI
++        help
++          If your system has an slave-capable SPI controller (which
++          takes the clock and chipselect), you can enable that
++          controller for the SPI master chips that are connected.
++
+ if SPI_MASTER
+ 
+ comment "SPI Master Controller Drivers"
+@@ -60,6 +69,12 @@ config SPI_ALTERA
+ 	help
+ 	  This is the driver for the Altera SPI Controller.
+ 
++config SPI_AMBARELLA
++        tristate "Ambarella SPI Controller"
++        depends on PLAT_AMBARELLA
++        help
++          This selects a driver for the Ambarella SPI Controller.
++
+ config SPI_ATH79
+ 	tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
+ 	depends on ATH79 && GPIOLIB
+@@ -539,4 +554,16 @@ endif # SPI_MASTER
+ 
+ # (slave support would go here)
+ 
++if SPI_SLAVE
++
++comment "SPI Slave Controller Drivers"
++
++config SPI_SLAVE_AMBARELLA
++        tristate "Ambarella SPI Slave Controller"
++        depends on PLAT_AMBARELLA
++        help
++	  This selects a driver for the Ambarella SPI Slave Controller.
++
++endif # SPI_SLAVE
++
+ endif # SPI
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 33f9c095..cd4e3c6e 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_SPI_SPIDEV)		+= spidev.o
+ 
+ # SPI master controller drivers (bus)
+ obj-$(CONFIG_SPI_ALTERA)		+= spi-altera.o
++obj-$(CONFIG_SPI_AMBARELLA)             += spi-ambarella.o
+ obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o
+ obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
+ obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
+@@ -74,3 +75,4 @@ obj-$(CONFIG_SPI_TOPCLIFF_PCH)		+= spi-topcliff-pch.o
+ obj-$(CONFIG_SPI_TXX9)			+= spi-txx9.o
+ obj-$(CONFIG_SPI_XCOMM)		+= spi-xcomm.o
+ obj-$(CONFIG_SPI_XILINX)		+= spi-xilinx.o
++obj-$(CONFIG_SPI_SLAVE_AMBARELLA)       += spi_slave_ambarella.o
+diff --git a/drivers/spi/spi-ambarella.c b/drivers/spi/spi-ambarella.c
+new file mode 100644
+index 00000000..1f444b70
+--- /dev/null
++++ b/drivers/spi/spi-ambarella.c
+@@ -0,0 +1,951 @@
++/*
++ * linux/drivers/spi/spi-ambarella.c
++ *
++ * History:
++ *	2014/08/29 - [Zhenwu Xue]
++
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/gpio.h>
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spidev.h>
++#include <linux/dmaengine.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <asm/io.h>
++#include <mach/io.h>
++#include <plat/spi.h>
++#include <plat/dma.h>
++#include <plat/rct.h>
++
++#define	AMBARELLA_SPI_BUF_MAX_LEN			(1024 * 20) //4096
++#define	AMBARELLA_SPI_MAX_XFER_PER_MSG		32
++#define	AMBARELLA_SPI_MAX_CS_NUM			8
++
++struct ambarella_spi {
++	struct device			*dev;
++	struct dma_chan		*tx_dma_chan;
++	struct dma_chan		*rx_dma_chan;
++	struct spi_message	*msg;
++	struct spi_transfer		*transfers[AMBARELLA_SPI_MAX_XFER_PER_MSG];
++	struct clk			*clk;
++	struct tasklet_struct	tasklet;
++	void __iomem			*virt;
++
++	u8 					*tx_dma_buf;
++	u8 					*rx_dma_buf;
++	dma_addr_t 			tx_dma_phys;
++	dma_addr_t 			rx_dma_phys;
++
++	u32					dma_buf_size;
++	u32					phys;
++	u32					clk_freq;
++	u32					dma_used:1;
++	u32					msb_first_only:1;
++	u32					ridx, widx;
++	u32					cspol;
++	int					cs_pins[AMBARELLA_SPI_MAX_CS_NUM];
++	int					xfer_id, n_xfer;
++	int					cs_active;
++	int					rw;
++	int					irq;
++};
++
++static void ambarella_spi_next_transfer(void *args);
++
++static int ambarella_spi_of_parse(struct platform_device *pdev,
++			struct spi_master *master)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct ambarella_spi *ambspi = spi_master_get_devdata(master);
++	int rval;
++
++	ambspi->clk = clk_get(NULL, "gclk_ssi");
++	if (IS_ERR(ambspi->clk)) {
++		dev_err(&pdev->dev, "Get PLL failed!\n");
++		return PTR_ERR(ambspi->clk);
++	}
++
++	rval = of_property_read_u32(np, "amb,clk-freq", &ambspi->clk_freq);
++	if (rval < 0) {
++		dev_err(&pdev->dev, "invalid clk-freq! %d\n", rval);
++		return rval;
++	}
++
++	return 0;
++}
++
++static void ambarella_spi_setup(struct ambarella_spi *bus, struct spi_device *spi)
++{
++	spi_ctrl0_reg_t		cr0;
++	u32 			ssi_clk, sckdv;
++
++	cr0.w		= 0;
++	cr0.s.dfs	= spi->bits_per_word - 1;
++	if (spi->mode & SPI_CPHA) {
++		cr0.s.scph	= 1;
++	} else {
++		cr0.s.scph	= 0;
++	}
++	if (spi->mode & SPI_CPOL) {
++		cr0.s.scpol	= 1;
++	} else {
++		cr0.s.scpol	= 0;
++	}
++	if (spi->mode & SPI_LOOP) {
++		cr0.s.srl = 1;
++	} else {
++		cr0.s.srl = 0;
++	}
++	if (spi->mode & SPI_LSB_FIRST) {
++		cr0.s.tx_lsb = 1;
++		cr0.s.rx_lsb = 1;
++	} else {
++		cr0.s.tx_lsb = 0;
++		cr0.s.rx_lsb = 0;
++	}
++
++	cr0.s.hold		= 0;
++	cr0.s.byte_ws		= 0;
++	cr0.s.fc_en		= 0;
++	cr0.s.residue		= 1;
++	amba_writel(bus->virt + SPI_CTRLR0_OFFSET, cr0.w);
++
++	ssi_clk = bus->clk_freq;
++	if(spi->max_speed_hz > ssi_clk / 2) {
++	    spi->max_speed_hz = ssi_clk / 2;
++	}
++	sckdv = (ssi_clk / spi->max_speed_hz + 1) & 0xfffe;
++	amba_writel(bus->virt + SPI_BAUDR_OFFSET, sckdv);
++
++	bus->cspol = (spi->mode & SPI_CS_HIGH) ? 1 : 0;
++	gpio_set_value(spi->cs_gpio, bus->cspol);
++	bus->cs_active = 1;
++}
++
++static void ambarella_spi_stop(struct ambarella_spi *bus)
++{
++	amba_readl(bus->virt + SPI_ICR_OFFSET);
++	amba_readl(bus->virt + SPI_ISR_OFFSET);
++
++	amba_writel(bus->virt + SPI_SSIENR_OFFSET, 0);
++	amba_writel(bus->virt + SPI_SER_OFFSET, 0);
++
++	if (bus->dma_used)
++		amba_writel(bus->virt + SPI_DMAC_OFFSET, 0);
++}
++
++static void ambarella_spi_prepare_transfer(struct ambarella_spi *bus)
++{
++	struct spi_message		*msg;
++	struct spi_transfer			*xfer;
++	const void				*wbuf, *rbuf;
++	spi_ctrl0_reg_t			cr0;
++
++	bus->widx = 0;
++	bus->ridx = 0;
++
++	msg		= bus->msg;
++	xfer		= bus->transfers[bus->xfer_id];
++
++	wbuf		= xfer->tx_buf;
++	rbuf		= xfer->rx_buf;
++	if (wbuf && !rbuf) {
++		bus->rw	= SPI_WRITE_ONLY;
++	}
++	if (!wbuf && rbuf) {
++		bus->rw	= SPI_READ_ONLY;
++	}
++	if (wbuf && rbuf) {
++		bus->rw	= SPI_WRITE_READ;
++	}
++	msg->actual_length += xfer->len;
++
++	cr0.w		= amba_readl(bus->virt + SPI_CTRLR0_OFFSET);
++	cr0.s.tmod	= SPI_WRITE_READ;
++	amba_writel(bus->virt + SPI_CTRLR0_OFFSET, cr0.w);
++
++	if (!bus->cs_active) {
++		gpio_set_value(msg->spi->cs_gpio, bus->cspol);
++		bus->cs_active = 1;
++	}
++
++	amba_writel(bus->virt + SPI_SSIENR_OFFSET, 0);
++	amba_writel(bus->virt + SPI_SER_OFFSET, 0);
++	if (bus->dma_used) {
++		if (bus->msg->spi->bits_per_word <= 8) {
++			amba_writel(bus->virt + SPI_RXFTLR_OFFSET, 8 - 1);
++		} else {
++			amba_writel(bus->virt + SPI_RXFTLR_OFFSET, 4 - 1);
++		}
++		amba_writel(bus->virt + SPI_DMAC_OFFSET, 0x3);
++	} else {
++		disable_irq_nosync(bus->irq);
++		amba_writel(bus->virt + SPI_IMR_OFFSET, SPI_TXEIS_MASK);
++		amba_writel(bus->virt + SPI_TXFTLR_OFFSET, 0);
++		amba_writel(bus->virt + SPI_RXFTLR_OFFSET, 1);
++	}
++	amba_writel(bus->virt + SPI_SSIENR_OFFSET, 1);
++}
++
++static void ambarella_spi_start_transfer(struct ambarella_spi *bus)
++{
++	struct spi_device *spi;
++	struct spi_transfer *xfer;
++	struct dma_slave_config tx_cfg, rx_cfg;
++	struct dma_async_tx_descriptor *txd, *rxd;
++	u32 len, widx, ridx, xfer_len, i;
++	void *wbuf, *rbuf;
++	u16 tmp;
++
++	xfer = bus->transfers[bus->xfer_id];
++	spi = bus->msg->spi;
++
++	wbuf = (void *)xfer->tx_buf;
++	rbuf = (void *)xfer->rx_buf;
++	widx	= bus->widx;
++	ridx	= bus->ridx;
++
++	len	= xfer->len;
++	if (!bus->dma_used) {
++		if (bus->msg->spi->bits_per_word > 8)
++			len >>= 1;
++	}
++
++	dma_sync_single_for_cpu(bus->dev, bus->tx_dma_phys, len, DMA_TO_DEVICE);
++
++	switch (bus->rw) {
++	case SPI_WRITE_ONLY:
++	case SPI_WRITE_READ:
++		if (!bus->dma_used) {
++			xfer_len = min_t(int, len - widx, SPI_DATA_FIFO_SIZE_16);
++			for(i = 0; i < xfer_len; i++) {
++				if (bus->msg->spi->bits_per_word <= 8)
++					tmp = ((u8 *)wbuf)[widx++];
++				else
++					tmp = ((u16 *)wbuf)[widx++];
++				amba_writel(bus->virt + SPI_DR_OFFSET, tmp);
++			}
++		} else {
++			memcpy(bus->tx_dma_buf, xfer->tx_buf, len);
++		}
++		break;
++	case SPI_READ_ONLY:
++		if (!bus->dma_used) {
++			xfer_len = min_t(int, len - ridx, SPI_DATA_FIFO_SIZE_16);
++			for(i = 0; i < xfer_len; i++)
++				amba_writel(bus->virt + SPI_DR_OFFSET, SPI_DUMMY_DATA);
++		} else {
++			memset(bus->tx_dma_buf, 0xFF, len);
++		}
++
++		break;
++	default:
++		break;
++	}
++
++	if (bus->dma_used) {
++		/* TX DMA */
++		tx_cfg.dst_addr			= bus->phys + SPI_DR_OFFSET;
++		if (spi->bits_per_word <= 8) {
++			tx_cfg.dst_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE;
++		} else {
++			tx_cfg.dst_addr_width	= DMA_SLAVE_BUSWIDTH_2_BYTES;
++		}
++		tx_cfg.dst_maxburst		= 8;
++		tx_cfg.direction		= DMA_MEM_TO_DEV;
++
++		BUG_ON(dmaengine_slave_config(bus->tx_dma_chan, &tx_cfg) < 0);
++
++		dma_sync_single_for_device(bus->dev, bus->tx_dma_phys, len, DMA_TO_DEVICE);
++
++		txd = dmaengine_prep_slave_single(bus->tx_dma_chan, bus->tx_dma_phys, len,
++			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT |
++			DMA_COMPL_SKIP_SRC_UNMAP | DMA_COMPL_SKIP_DEST_UNMAP | DMA_CTRL_ACK);
++		BUG_ON (!txd);
++
++		txd->callback		= NULL;
++		txd->callback_param	= NULL;
++		dmaengine_submit(txd);
++
++		dma_async_issue_pending(bus->tx_dma_chan);
++
++		/* RX DMA */
++		rx_cfg.src_addr			= bus->phys + SPI_DR_OFFSET;
++		if (spi->bits_per_word <= 8) {
++			rx_cfg.src_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE;
++		} else {
++			rx_cfg.src_addr_width	= DMA_SLAVE_BUSWIDTH_2_BYTES;
++		}
++		rx_cfg.src_maxburst		= 8;
++		rx_cfg.direction		= DMA_DEV_TO_MEM;
++
++		BUG_ON(dmaengine_slave_config(bus->rx_dma_chan, &rx_cfg) < 0);
++
++		rxd = dmaengine_prep_slave_single(bus->rx_dma_chan, bus->rx_dma_phys, len,
++			DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK |
++			DMA_COMPL_SKIP_SRC_UNMAP | DMA_COMPL_SKIP_DEST_UNMAP);
++		BUG_ON(!rxd);
++
++		rxd->callback		= ambarella_spi_next_transfer;
++		rxd->callback_param	= bus;
++
++		dma_sync_single_for_device(bus->dev, bus->rx_dma_phys, len, DMA_FROM_DEVICE);
++
++		dmaengine_submit(rxd);
++		dma_async_issue_pending(bus->rx_dma_chan);
++	} else {
++		bus->widx = widx;
++		enable_irq(bus->irq);
++	}
++
++	amba_writel(bus->virt + SPI_SER_OFFSET, 1 << spi->chip_select);
++}
++
++static void ambarella_spi_next_transfer(void *args)
++{
++	struct ambarella_spi	*bus = args;
++	struct spi_transfer	*xfer;
++
++	xfer = bus->transfers[bus->xfer_id++];
++
++	if (bus->dma_used) {
++		switch (bus->rw) {
++		case SPI_WRITE_READ:
++		case SPI_READ_ONLY:
++			dma_sync_single_for_cpu(bus->dev, bus->rx_dma_phys, xfer->len, DMA_FROM_DEVICE);
++			memcpy(xfer->rx_buf, bus->rx_dma_buf, xfer->len);
++			break;
++		default:
++			break;
++		}
++	}
++
++	if (xfer->cs_change) {
++		gpio_set_value(bus->msg->spi->cs_gpio, bus->cspol^1);
++		bus->cs_active = 0;
++	}
++
++	if (bus->xfer_id >= bus->n_xfer) {
++		gpio_set_value(bus->msg->spi->cs_gpio, bus->cspol^1);
++		bus->cs_active = 0;
++
++		ambarella_spi_stop(bus);
++		spi_finalize_current_message(bus->msg->spi->master);
++	} else {
++		ambarella_spi_prepare_transfer(bus);
++		ambarella_spi_start_transfer(bus);
++	}
++}
++
++static void ambarella_spi_tasklet(unsigned long data)
++{
++	struct ambarella_spi *bus = (struct ambarella_spi *)data;
++	struct spi_transfer *xfer;
++	void *rbuf;
++	u32 widx, ridx, len, rxflr, xfer_len;
++	u32 status, finish_transfer = 0;
++	u16 i, tmp;
++
++	xfer = bus->transfers[bus->xfer_id];
++
++	/* Wait until SPI idle */
++	status = amba_readl(bus->virt + SPI_SR_OFFSET);
++	if (status & 0x1) {
++		/* Transfer is still in progress */
++		for (i = 0; i < MAX_QUERY_TIMES; i++) {
++			status = amba_readl(bus->virt + SPI_SR_OFFSET);
++			if (!(status & 0x1))
++				break;
++		}
++		if (status & 0x1) {
++			tasklet_schedule(&bus->tasklet);
++			return;
++		}
++	}
++
++	rbuf	= (void *)xfer->rx_buf;
++	widx	= bus->widx;
++	ridx	= bus->ridx;
++	len	= xfer->len;
++
++	if (bus->msg->spi->bits_per_word > 8)
++		len >>= 1;
++
++	/* Fetch data from FIFO */
++	switch (bus->rw) {
++	case SPI_READ_ONLY:
++	case SPI_WRITE_READ:
++		xfer_len = len - ridx;
++		rxflr = amba_readl(bus->virt + SPI_RXFLR_OFFSET);
++		if (xfer_len > rxflr)
++			xfer_len = rxflr;
++		for(i = 0; i < xfer_len; i++) {
++			tmp	= amba_readl(bus->virt + SPI_DR_OFFSET);
++			if (bus->msg->spi->bits_per_word <= 8)
++				((u8 *)rbuf)[ridx++] = tmp & 0xff;
++			else
++				((u16 *)rbuf)[ridx++] = tmp;
++		}
++		bus->ridx = ridx;
++		break;
++	default:
++		break;
++	}
++
++	/* Check whether the current transfer ends */
++	switch (bus->rw) {
++	case SPI_WRITE_ONLY:
++		if (widx == len)
++			finish_transfer = 1;
++		break;
++	case SPI_READ_ONLY:
++		if (ridx == len)
++			finish_transfer = 1;
++		break;
++	case SPI_WRITE_READ:
++		if (ridx == len && widx == len)
++			finish_transfer = 1;
++		break;
++	default:
++		break;
++	}
++
++	/* End transfer or continue filling FIFO */
++	if (finish_transfer) {
++		ambarella_spi_next_transfer((void *) bus);
++		enable_irq(bus->irq);
++	} else {
++		ambarella_spi_start_transfer(bus);
++	}
++}
++
++static int ambarella_spi_one_message(struct spi_master *master, struct spi_message *msg)
++{
++	int				err = 0;
++	struct spi_device		*spi;
++	struct ambarella_spi		*bus;
++	struct spi_transfer		*xfer;
++
++	spi = msg->spi;
++	bus = spi_master_get_devdata(master);
++
++	msg->status		= 0;
++	msg->actual_length	= 0;
++	bus->msg		= msg;
++
++	if (list_empty(&msg->transfers)) {
++		spi_finalize_current_message(master);
++		goto ambarella_spi_transfer_exit;
++	}
++
++	if (!gpio_is_valid(spi->cs_gpio)) {
++		dev_err(&master->dev, "cs %d is invalid!\n", spi->cs_gpio);
++		err = -EINVAL;
++		goto ambarella_spi_transfer_exit;
++	}
++
++	if (spi->bits_per_word < 4 || spi->bits_per_word > 16) {
++		err = -EINVAL;
++		goto ambarella_spi_transfer_exit;
++	}
++
++	if (!spi->max_speed_hz) {
++		err = -EINVAL;
++		goto ambarella_spi_transfer_exit;
++	}
++
++	if (spi->bits_per_word > 8) {
++		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++			if (xfer->len & 0x1) {
++				err = -EINVAL;
++				goto ambarella_spi_transfer_exit;
++			}
++		}
++	}
++
++	if ((spi->mode & SPI_LSB_FIRST) && bus->msb_first_only) {
++		dev_err(&master->dev, "SPI[%d] only supports msb first tx-rx", master->bus_num);
++		err = -EINVAL;
++		goto ambarella_spi_transfer_exit;
++	}
++
++	bus->n_xfer	= 0;
++	bus->xfer_id	= 0;
++	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++		if (xfer->len > AMBARELLA_SPI_BUF_MAX_LEN) {
++			err = -EINVAL;
++			goto ambarella_spi_transfer_exit;
++		}
++		bus->transfers[bus->n_xfer++] = xfer;
++	}
++
++	ambarella_spi_setup(bus, spi);
++	ambarella_spi_prepare_transfer(bus);
++	ambarella_spi_start_transfer(bus);
++
++ambarella_spi_transfer_exit:
++	return err;
++}
++
++static irqreturn_t ambarella_spi_isr(int irq, void *dev_data)
++{
++	struct ambarella_spi *bus = dev_data;
++
++	if (amba_readl(bus->virt + SPI_ISR_OFFSET)) {
++		disable_irq_nosync(bus->irq);
++		amba_writel(bus->virt + SPI_ISR_OFFSET, 0);
++
++		ambarella_spi_tasklet((unsigned long)bus);
++	}
++
++	return IRQ_HANDLED;
++}
++
++static int ambarella_spi_dma_channel_allocate(struct ambarella_spi *bus,
++			bool dma_to_memory)
++{
++	struct dma_chan *dma_chan;
++	dma_addr_t dma_phys;
++	u8 *dma_buf;
++	int ret = 0;
++
++	dma_chan = dma_request_slave_channel(bus->dev,
++					dma_to_memory ? "rx" : "tx");
++	if (IS_ERR(dma_chan)) {
++		ret = PTR_ERR(dma_chan);
++		if (ret != -EPROBE_DEFER)
++			dev_err(bus->dev,
++				"Dma channel is not available: %d\n", ret);
++		return ret;
++	}
++
++	dma_buf = dma_alloc_coherent(bus->dev, bus->dma_buf_size,
++				&dma_phys, GFP_KERNEL);
++	if (!dma_buf) {
++		dev_err(bus->dev, " Not able to allocate the dma buffer\n");
++		dma_release_channel(dma_chan);
++		return -ENOMEM;
++	}
++
++	if (dma_to_memory) {
++		bus->rx_dma_chan = dma_chan;
++		bus->rx_dma_buf = dma_buf;
++		bus->rx_dma_phys = dma_phys;
++	} else {
++		bus->tx_dma_chan = dma_chan;
++		bus->tx_dma_buf = dma_buf;
++		bus->tx_dma_phys = dma_phys;
++	}
++
++	return ret;
++}
++
++static void ambarella_spi_dma_channel_free(struct ambarella_spi *bus,
++	bool dma_to_memory)
++{
++	u8 *dma_buf;
++	dma_addr_t dma_phys;
++	struct dma_chan *dma_chan;
++
++	if (dma_to_memory) {
++		dma_buf = bus->rx_dma_buf;
++		dma_chan = bus->rx_dma_chan;
++		dma_phys = bus->rx_dma_phys;
++		bus->rx_dma_chan = NULL;
++		bus->rx_dma_buf = NULL;
++	} else {
++		dma_buf = bus->tx_dma_buf;
++		dma_chan = bus->tx_dma_chan;
++		dma_phys = bus->tx_dma_phys;
++		bus->tx_dma_buf = NULL;
++		bus->tx_dma_chan = NULL;
++	}
++	if (!dma_chan)
++		return;
++
++	dma_free_coherent(bus->dev, bus->dma_buf_size, dma_buf, dma_phys);
++	dma_release_channel(dma_chan);
++}
++
++static int ambarella_spi_hw_setup(struct spi_device *spi)
++{
++	struct ambarella_spi *bus = spi_master_get_devdata(spi->master);
++	int err = 0;
++
++	if (gpio_is_valid(spi->cs_gpio) &&
++		(bus->cs_pins[spi->chip_select] != spi->cs_gpio)) {
++		err = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
++		if (err < 0) {
++			dev_err(&spi->dev, "can't get CS: %d\n", err);
++			return -EINVAL;
++		}
++		gpio_direction_output(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
++		bus->cs_pins[spi->chip_select] = spi->cs_gpio;
++	}
++
++	return 0;
++}
++
++static int ambarella_spi_probe(struct platform_device *pdev)
++{
++	struct resource 			*res;
++	void __iomem				*reg;
++	struct ambarella_spi			*bus;
++	struct spi_master			*master;
++	int					i;
++	int					err = 0;
++	int					irq;
++	u32					val;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		err = -EINVAL;
++		goto exit_spi_probe;
++	}
++
++	reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (!reg) {
++		err = -ENOMEM;
++		goto exit_spi_probe;
++	}
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "no irq resource!\n");
++		err = -ENODEV;
++		goto exit_spi_probe;
++	}
++
++	master = spi_alloc_master(&pdev->dev, sizeof(*bus));
++	if (!master) {
++		err = -ENOMEM;
++		goto exit_spi_probe;
++	}
++
++	bus = spi_master_get_devdata(master);
++	bus->phys = res->start;
++	bus->virt = reg;
++	bus->irq = irq;
++	bus->dev = &pdev->dev;
++
++	for (i = 0; i < AMBARELLA_SPI_MAX_CS_NUM; i++)
++		bus->cs_pins[i] = -1;
++
++	err = ambarella_spi_of_parse(pdev, master);
++	if (err < 0) {
++		goto exit_free_master;
++	}
++
++	clk_set_rate(bus->clk, bus->clk_freq);
++	amba_writel(reg + SPI_SSIENR_OFFSET, 0);
++	amba_writel(reg + SPI_IMR_OFFSET, 0);
++
++	master->dev.of_node		= pdev->dev.of_node;
++	master->mode_bits		= SPI_CPHA | SPI_CPOL | SPI_CS_HIGH;
++	master->transfer_one_message	= ambarella_spi_one_message;
++	master->setup = ambarella_spi_hw_setup;
++	platform_set_drvdata(pdev, master);
++
++	/* check if hw only supports msb first tx/rx */
++	if (of_find_property(pdev->dev.of_node, "amb,msb-first-only", NULL)) {
++		bus->msb_first_only = 1;
++		dev_info(&pdev->dev,"Only supports msb first tx-rx\n");
++	} else {
++		bus->msb_first_only = 0;
++		master->mode_bits |= SPI_LSB_FIRST;
++	}
++
++	/* check if using dma */
++	if (of_find_property(pdev->dev.of_node, "amb,dma-used", NULL)) {
++		bus->dma_used = 1;
++		dev_info(&pdev->dev,"DMA is used\n");
++
++		/* Enable DMA Channel 0/1 as SSI0 Tx and Rx */
++		val	 = amba_readl(AHB_SCRATCHPAD_REG(0x0c));
++		val	&= 0xff9fffff;
++		val	|= 0x00200000;
++		amba_writel(AHB_SCRATCHPAD_REG(0x0c), val);
++
++		bus->dma_buf_size = AMBARELLA_SPI_BUF_MAX_LEN;
++		err = ambarella_spi_dma_channel_allocate(bus, false);
++		if (err < 0)
++			goto exit_free_master;
++		err = ambarella_spi_dma_channel_allocate(bus, true);
++		if (err < 0)
++			goto exit_tx_dma_irq_free;
++	} else {
++		bus->dma_used = 0;
++		/* request IRQ */
++		err = devm_request_irq(&pdev->dev, irq, ambarella_spi_isr,
++				IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), bus);
++		if (err)
++			goto exit_free_master;
++
++		tasklet_init(&bus->tasklet, ambarella_spi_tasklet, (unsigned long)bus);
++	}
++
++	err = spi_register_master(master);
++	if (err)
++		goto exit_rx_dma_free;
++
++	dev_info(&pdev->dev, "Ambarella spi controller %d created.\r\n", master->bus_num);
++
++	return err;
++
++exit_rx_dma_free:
++	if (bus->dma_used)
++		ambarella_spi_dma_channel_free(bus, true);
++exit_tx_dma_irq_free:
++	if (bus->dma_used)
++		ambarella_spi_dma_channel_free(bus, false);
++	else
++		free_irq(irq, bus);
++exit_free_master:
++	spi_master_put(master);
++exit_spi_probe:
++	return err;
++}
++
++static int ambarella_spi_remove(struct platform_device *pdev)
++{
++	struct spi_master		*master;
++	struct ambarella_spi		*bus;
++	int i;
++
++	master	= platform_get_drvdata(pdev);
++	bus	= spi_master_get_devdata(master);
++
++	if (!bus->dma_used)
++		tasklet_kill(&bus->tasklet);
++	else {
++		if (bus->tx_dma_chan)
++			ambarella_spi_dma_channel_free(bus, false);
++
++		if (bus->rx_dma_chan)
++			ambarella_spi_dma_channel_free(bus, true);
++	}
++
++	ambarella_spi_stop(bus);
++
++	for (i = 0; i < AMBARELLA_SPI_MAX_CS_NUM; i++) {
++		if (gpio_is_valid(bus->cs_pins[i]))
++			gpio_free(bus->cs_pins[i]);
++	}
++
++	spi_unregister_master(master);
++
++	return 0;
++}
++
++int ambarella_spi_write(amba_spi_cfg_t *spi_cfg, amba_spi_write_t *spi_w)
++{
++	int					err = 0;
++	struct spi_master			*master;
++	struct spi_device			spi;
++	struct ambarella_spi			*bus;
++
++	master = spi_busnum_to_master(spi_w->bus_id);
++	if (!master) {
++		err = -EINVAL;
++		goto ambarella_spi_write_exit;
++	}
++
++	bus = spi_master_get_devdata(master);
++
++	spi.master		= master;
++	spi.bits_per_word	= spi_cfg->cfs_dfs;
++	spi.mode		= spi_cfg->spi_mode;
++	spi.max_speed_hz	= spi_cfg->baud_rate;
++	spi.chip_select		= spi_w->cs_id;
++	spi.cs_gpio		= bus->cs_pins[spi.chip_select];
++
++	err = spi_write_then_read(&spi, spi_w->buffer, spi_w->n_size, NULL, 0);
++
++ambarella_spi_write_exit:
++	return err;
++}
++EXPORT_SYMBOL(ambarella_spi_write);
++
++int ambarella_spi_read(amba_spi_cfg_t *spi_cfg, amba_spi_read_t *spi_r)
++{
++	int					err = 0;
++	struct spi_master			*master;
++	struct spi_device			spi;
++	struct ambarella_spi			*bus;
++
++	master = spi_busnum_to_master(spi_r->bus_id);
++	if (!master) {
++		err = -EINVAL;
++		goto ambarella_spi_read_exit;
++	}
++
++	bus = spi_master_get_devdata(master);
++
++	spi.master		= master;
++	spi.bits_per_word	= spi_cfg->cfs_dfs;
++	spi.mode		= spi_cfg->spi_mode;
++	spi.max_speed_hz	= spi_cfg->baud_rate;
++	spi.chip_select		= spi_r->cs_id;
++	spi.cs_gpio		= bus->cs_pins[spi.chip_select];
++
++	err = spi_write_then_read(&spi, NULL, 0, spi_r->buffer, spi_r->n_size);
++
++ambarella_spi_read_exit:
++	return err;
++}
++EXPORT_SYMBOL(ambarella_spi_read);
++
++int ambarella_spi_write_then_read(amba_spi_cfg_t *spi_cfg,
++	amba_spi_write_then_read_t *spi_wtr)
++{
++	int					err = 0;
++	struct spi_master			*master;
++	struct spi_device			spi;
++	struct ambarella_spi			*bus;
++
++	master = spi_busnum_to_master(spi_wtr->bus_id);
++	if (!master) {
++		err = -EINVAL;
++		goto ambarella_spi_write_then_read_exit;
++	}
++
++	bus = spi_master_get_devdata(master);
++
++	spi.master		= master;
++	spi.bits_per_word	= spi_cfg->cfs_dfs;
++	spi.mode		= spi_cfg->spi_mode;
++	spi.max_speed_hz	= spi_cfg->baud_rate;
++	spi.chip_select		= spi_wtr->cs_id;
++	spi.cs_gpio		= bus->cs_pins[spi.chip_select];
++
++	err = spi_write_then_read(&spi,
++		spi_wtr->w_buffer, spi_wtr->w_size,
++		spi_wtr->r_buffer, spi_wtr->r_size);
++
++ambarella_spi_write_then_read_exit:
++	return err;
++}
++EXPORT_SYMBOL(ambarella_spi_write_then_read);
++
++int ambarella_spi_write_and_read(amba_spi_cfg_t *spi_cfg,
++	amba_spi_write_and_read_t *spi_war)
++{
++	int					err = 0;
++	struct spi_master			*master;
++	struct spi_device			spi;
++	struct ambarella_spi			*bus;
++	struct spi_message			msg;
++	struct spi_transfer			x[1];
++
++	master = spi_busnum_to_master(spi_war->bus_id);
++	if (!master) {
++		err = -EINVAL;
++		goto ambarella_spi_write_and_read_exit;
++	}
++
++	bus = spi_master_get_devdata(master);
++
++	spi.master		= master;
++	spi.bits_per_word	= spi_cfg->cfs_dfs;
++	spi.mode		= spi_cfg->spi_mode;
++	spi.max_speed_hz	= spi_cfg->baud_rate;
++	spi.chip_select		= spi_war->cs_id;
++	spi.cs_gpio		= bus->cs_pins[spi.chip_select];
++
++	spi_message_init(&msg);
++	memset(x, 0, sizeof x);
++	x->tx_buf	= spi_war->w_buffer;
++	x->rx_buf	= spi_war->r_buffer;
++	x->len		= spi_war->n_size;
++	spi_message_add_tail(x, &msg);
++
++	err = spi_sync(&spi, &msg);
++
++ambarella_spi_write_and_read_exit:
++	return err;
++}
++EXPORT_SYMBOL(ambarella_spi_write_and_read);
++
++#ifdef CONFIG_PM
++static int ambarella_spi_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	dev_dbg(&pdev->dev, "%s exit with 0 @ %d\n", __func__, state.event);
++
++	return 0;
++}
++
++static int ambarella_spi_resume(struct platform_device *pdev)
++{
++	struct spi_master *master = platform_get_drvdata(pdev);
++	struct ambarella_spi *bus = spi_master_get_devdata(master);
++
++	clk_set_rate(bus->clk, bus->clk_freq);
++
++	dev_dbg(&pdev->dev, "%s exit with 0\n", __func__);
++
++	return 0;
++}
++#endif
++
++static const struct of_device_id ambarella_spi_dt_ids[] = {
++	{.compatible = "ambarella,spi", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_spi_dt_ids);
++
++static struct platform_driver ambarella_spi_driver = {
++	.probe		= ambarella_spi_probe,
++	.remove		= ambarella_spi_remove,
++#ifdef CONFIG_PM
++	.suspend		= ambarella_spi_suspend,
++	.resume		= ambarella_spi_resume,
++#endif
++	.driver		= {
++		.name	= "ambarella-spi",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_spi_dt_ids,
++	},
++};
++
++static int ambarella_spi_init(void)
++{
++	return platform_driver_register(&ambarella_spi_driver);
++}
++
++static void ambarella_spi_exit(void)
++{
++	platform_driver_unregister(&ambarella_spi_driver);
++}
++
++module_init(ambarella_spi_init);
++module_exit(ambarella_spi_exit);
++
++MODULE_DESCRIPTION("Ambarella Media Processor SPI Bus Controller");
++MODULE_AUTHOR("Zhenwu Xue, <zwxue@ambarella.com>");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/spi/spi_slave_ambarella.c b/drivers/spi/spi_slave_ambarella.c
+new file mode 100644
+index 00000000..439d2bac
+--- /dev/null
++++ b/drivers/spi/spi_slave_ambarella.c
+@@ -0,0 +1,638 @@
++/*
++ * linux/drivers/spi/spi_slave_ambarella.c
++ *
++ * History:
++ *	2012/02/21 - [Zhenwu Xue]  created file
++ *
++ * Copyright (C) 2004-2012, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/interrupt.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spidev.h>
++#include <linux/fs.h>
++#include <linux/of.h>
++#include <linux/ioctl.h>
++#include <asm/uaccess.h>
++#include <plat/spi.h>
++
++#define MAX_SPI_SLAVES		8
++
++#define SPI_RXFIS_MASK 		0x00000010
++#define SPI_RXOIS_MASK 		0x00000008
++#define SPI_RXUIS_MASK 		0x00000004
++
++#define BUFFER_LEN		4096
++
++#define DUMMY_DATA		0xffff
++
++static int rx_ftlr = 8;
++module_param(rx_ftlr, int, 0644);
++
++struct ambarella_spi_slave {
++	void __iomem				*regbase;
++
++	int					major;
++	char					dev_name[32];
++	struct class				*psClass;
++	struct device				*psDev;
++
++	u16					mode;
++	u16					bpw;
++
++	int					count;
++	struct mutex				um_mtx;
++
++	u16					r_buf[BUFFER_LEN];
++	u16					r_buf_start;
++	u16					r_buf_end;
++	u16					r_buf_empty;
++	u16					r_buf_full;
++	u16					r_buf_round;
++	spinlock_t				r_buf_lock;
++
++	u16					w_buf[BUFFER_LEN];
++	u16					w_buf_start;
++	u16					w_buf_end;
++	u16					w_buf_empty;
++	u16					w_buf_full;
++	u16					w_buf_round;
++	spinlock_t				w_buf_lock;
++};
++
++DEFINE_MUTEX(g_mtx);
++static int amb_slave_id = 0;
++static struct ambarella_spi_slave	*priv_array[MAX_SPI_SLAVES] =
++	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
++
++static int ambarella_spi_slave_inithw(struct ambarella_spi_slave *priv)
++{
++	struct clk *clk;
++	u32 ctrlr0;
++
++	clk = clk_get(NULL, "gclk_ssi2");
++	if (!IS_ERR_OR_NULL(clk))
++		clk_set_rate(clk, 13500000);
++
++	/* Initial Register Settings */
++	ctrlr0 = (SPI_CFS << 12) | (SPI_WRITE_READ << 8) | (priv->mode << 6) |
++				(SPI_FRF << 4) | (priv->bpw - 1);
++	amba_writel(priv->regbase + SPI_CTRLR0_OFFSET, ctrlr0);
++
++	amba_writel(priv->regbase + SPI_TXFTLR_OFFSET, 0);
++	amba_writel(priv->regbase + SPI_RXFTLR_OFFSET, rx_ftlr - 1);
++	amba_writel(priv->regbase + SPI_IMR_OFFSET, SPI_RXFIS_MASK);
++
++	return 0;
++}
++
++static irqreturn_t ambarella_spi_slave_isr(int irq, void *dev_data)
++{
++	struct ambarella_spi_slave	*priv	= dev_data;
++	u32				i, rxflr, txflr;
++
++	if (amba_readl(priv->regbase + SPI_ISR_OFFSET)) {
++		txflr = 16 - amba_readl(priv->regbase + SPI_TXFLR_OFFSET);
++		spin_lock(&priv->w_buf_lock);
++		if (priv->w_buf_empty) {
++			for (i = 0; i < txflr; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
++			}
++		} else {
++			priv->w_buf_full = 0;
++			if (priv->w_buf_round & 0x01) {
++				if (BUFFER_LEN - priv->w_buf_start > txflr) {
++					for (i = 0; i < txflr; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++					}
++				} else if (BUFFER_LEN - priv->w_buf_start + priv->w_buf_end > txflr) {
++					for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++					}
++					for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
++					}
++					priv->w_buf_start = i + 1;
++					priv->w_buf_round++;
++				} else {
++					for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++					}
++					for (i = 0; i < priv->w_buf_end; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
++					}
++					for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN - priv->w_buf_end; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
++					}
++					priv->w_buf_empty = 1;
++				}
++			} else {
++				if (priv->w_buf_end - priv->w_buf_start > txflr) {
++					for (i = 0; i < txflr; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++					}
++				} else {
++					for (i = 0; i < priv->w_buf_end - priv->w_buf_start; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++					}
++					for (i = 0; i < txflr - priv->w_buf_end + priv->w_buf_start; i++) {
++						amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
++					}
++					priv->w_buf_empty = 1;
++				}
++			}
++		}
++		spin_unlock(&priv->w_buf_lock);
++
++		rxflr = amba_readl(priv->regbase + SPI_RXFLR_OFFSET);
++		spin_lock(&priv->r_buf_lock);
++		if (priv->r_buf_empty) {
++			priv->r_buf_start	= 0;
++			priv->r_buf_end		= 0;
++			priv->r_buf_empty	= 0;
++		}
++
++		for (i = 0; i < rxflr; i++) {
++			if (priv->r_buf_full) {
++				printk("%s: Rx buffer overflow!!\n", __FILE__);
++				priv->r_buf_start++;
++				if (priv->r_buf_start >= BUFFER_LEN) {
++					priv->r_buf_start = 0;
++					priv->r_buf_round++;
++				}
++			}
++
++			priv->r_buf[priv->r_buf_end++] = amba_readl(priv->regbase + SPI_DR_OFFSET);
++			if (priv->r_buf_end >= BUFFER_LEN) {
++				priv->r_buf_end = 0;
++				priv->r_buf_round++;
++			}
++
++			if (priv->r_buf_round & 0x01) {
++				if (priv->r_buf_end >= priv->r_buf_start) {
++					priv->r_buf_full = 1;
++				}
++			}
++		}
++		spin_unlock(&priv->r_buf_lock);
++
++		amba_writel(priv->regbase + SPI_ISR_OFFSET, 0);
++	}
++
++	return IRQ_HANDLED;
++}
++
++static int spi_slave_open(struct inode *inode, struct file *filp)
++{
++	int				i, ret = 0;
++	struct ambarella_spi_slave	*priv = NULL;
++
++	mutex_lock(&g_mtx);
++
++	for (i = 0; i < MAX_SPI_SLAVES; i++) {
++		if (priv_array[i] && MKDEV(priv_array[i]->major, 0) == inode->i_rdev) {
++			priv = priv_array[i];
++			break;
++		}
++	}
++	mutex_lock(&priv->um_mtx);
++	if (!priv->count) {
++		priv->count++;
++		filp->private_data = priv;
++	} else {
++		ret = -ENXIO;
++	}
++	mutex_unlock(&priv->um_mtx);
++
++	mutex_unlock(&g_mtx);
++
++	return ret;
++}
++
++static ssize_t
++spi_slave_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
++{
++	ssize_t				 ret = 0;
++	struct ambarella_spi_slave	*priv;
++	int				result;
++
++	priv = (struct ambarella_spi_slave *)filp->private_data;
++
++	spin_lock(&priv->r_buf_lock);
++
++	if (!priv->r_buf_empty) {
++		if (priv->r_buf_round & 0x01) {
++			if ((BUFFER_LEN - priv->r_buf_start) * 2 >= count) {
++				result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], count);
++				priv->r_buf_start += count / 2;
++				ret = count;
++			} else if ((BUFFER_LEN - priv->r_buf_start + priv->r_buf_end) * 2 >= count) {
++				result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], (BUFFER_LEN - priv->r_buf_start) * 2);
++				result = copy_to_user(buf + (BUFFER_LEN - priv->r_buf_start) * 2, (void *)priv->r_buf, count - (BUFFER_LEN - priv->r_buf_start) * 2);
++				priv->r_buf_start = BUFFER_LEN - priv->r_buf_start + priv->r_buf_end - count / 2;
++				priv->r_buf_round++;
++				ret = count;
++			} else {
++				result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], (BUFFER_LEN - priv->r_buf_start) * 2);
++				result = copy_to_user(buf + (BUFFER_LEN - priv->r_buf_start) * 2, (void *)priv->r_buf, priv->r_buf_end * 2);
++				priv->r_buf_start = priv->r_buf_end;
++				priv->r_buf_round++;
++				ret = (BUFFER_LEN - priv->r_buf_start + priv->r_buf_end) * 2;
++			}
++		} else {
++			if ((priv->r_buf_end - priv->r_buf_start) * 2 > count) {
++				ret = count;
++			} else {
++				ret = (priv->r_buf_end - priv->r_buf_start) * 2;
++			}
++			result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], ret);
++			priv->r_buf_start += ret / 2;
++		}
++
++		if (priv->r_buf_start >= BUFFER_LEN) {
++			priv->r_buf_start = 0;
++			priv->r_buf_round++;
++		}
++	}
++
++	spin_unlock(&priv->r_buf_lock);
++
++	return ret;
++}
++
++static ssize_t
++spi_slave_write(struct file *filp, const char __user *buf,
++		size_t count, loff_t *f_pos)
++{
++	ssize_t				 ret = 0;
++	struct ambarella_spi_slave	*priv;
++	int				txflr, i, result;
++
++	priv = (struct ambarella_spi_slave *)filp->private_data;
++
++	spin_lock(&priv->w_buf_lock);
++
++	if (!priv->w_buf_full) {
++		if (priv->w_buf_empty) {
++			priv->w_buf_empty = 0;
++
++			if (count < 2 * BUFFER_LEN) {
++				ret = count;
++				priv->w_buf_start = 0;
++				priv->w_buf_end = count / 2;
++				priv->w_buf_round = 0;
++				result = copy_from_user(priv->w_buf, buf, ret);
++			} else {
++				ret = 2 * BUFFER_LEN;
++				priv->w_buf_full = 1;
++				priv->w_buf_start = 0;
++				priv->w_buf_end = 0;
++				priv->w_buf_round = 1;
++				result = copy_from_user(priv->w_buf, buf, ret);
++			}
++		} else {
++			if (priv->w_buf_round & 0x01) {
++				if (count < (priv->w_buf_start - priv->w_buf_end) * 2) {
++					ret = count;
++					result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, ret);
++					priv->w_buf_end += ret / 2;
++				} else {
++					ret = (priv->w_buf_start - priv->w_buf_end) * 2;
++					result = copy_from_user(&priv->w_buf[priv->w_buf_end], buf, ret);
++					priv->w_buf_end = priv->w_buf_start;
++					priv->w_buf_full = 1;
++				}
++			} else {
++				if (count <= (BUFFER_LEN - priv->w_buf_end) * 2) {
++					ret = count;
++					result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, ret);
++					priv->w_buf_end += ret / 2;
++				} else if (count < (BUFFER_LEN + priv->w_buf_start - priv->w_buf_end) * 2) {
++					ret = count;
++					result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, (BUFFER_LEN - priv->w_buf_end) * 2);
++					result = copy_from_user((void *)priv->w_buf, buf + (BUFFER_LEN - priv->w_buf_end) * 2, ret - (BUFFER_LEN - priv->w_buf_end) * 2);
++					priv->w_buf_end = priv->w_buf_end + ret / 2 - BUFFER_LEN;
++					priv->w_buf_round++;
++				} else {
++					ret = (BUFFER_LEN + priv->w_buf_start - priv->w_buf_end) * 2;
++					result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, (BUFFER_LEN - priv->w_buf_end) * 2);
++					result = copy_from_user((void *)priv->w_buf, buf + (BUFFER_LEN - priv->w_buf_end) * 2, ret - (BUFFER_LEN - priv->w_buf_end) * 2);
++					priv->w_buf_end = priv->w_buf_start;
++					priv->w_buf_round++;
++					priv->w_buf_full = 1;
++				}
++			}
++		}
++
++		if (priv->w_buf_end >= BUFFER_LEN) {
++			priv->w_buf_end = 0;
++			priv->w_buf_round++;
++		}
++	}
++
++	txflr = 16 - amba_readl(priv->regbase + SPI_TXFLR_OFFSET);
++	priv->w_buf_full = 0;
++	if (priv->w_buf_round & 0x01) {
++		if (BUFFER_LEN - priv->w_buf_start > txflr) {
++			for (i = 0; i < txflr; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++			}
++		} else if (BUFFER_LEN - priv->w_buf_start + priv->w_buf_end > txflr) {
++			for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++			}
++			for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
++			}
++			priv->w_buf_start = i + 1;
++			priv->w_buf_round++;
++		} else {
++			for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++			}
++			for (i = 0; i < priv->w_buf_end; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
++			}
++			for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN - priv->w_buf_end; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
++			}
++			priv->w_buf_empty = 1;
++		}
++	} else {
++		if (priv->w_buf_end - priv->w_buf_start > txflr) {
++			for (i = 0; i < txflr; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++			}
++		} else {
++			for (i = 0; i < priv->w_buf_end - priv->w_buf_start; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
++			}
++			for (i = 0; i < txflr - priv->w_buf_end + priv->w_buf_start; i++) {
++				amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
++			}
++			priv->w_buf_empty = 1;
++		}
++	}
++
++	spin_unlock(&priv->w_buf_lock);
++
++	return ret;
++}
++
++long spi_slave_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++	int			err = -ENOIOCTLCMD;
++
++	switch(cmd)
++	{
++	default:
++		break;
++	}
++
++	return err;
++}
++
++static int spi_slave_release(struct inode *inode, struct file *filp)
++{
++	int				ret = 0;
++	struct ambarella_spi_slave	*priv;
++
++	priv = (struct ambarella_spi_slave *)filp->private_data;
++
++	mutex_lock(&priv->um_mtx);
++	if (priv->count) {
++		priv->count--;
++	}
++	mutex_unlock(&priv->um_mtx);
++
++	return ret;
++}
++
++static struct file_operations spi_slave_fops = {
++	.open		= spi_slave_open,
++	.read		= spi_slave_read,
++	.write		= spi_slave_write,
++	.unlocked_ioctl	= spi_slave_ioctl,
++	.release	= spi_slave_release,
++};
++
++static int ambarella_spi_slave_probe(struct platform_device *pdev)
++{
++	struct ambarella_spi_slave		*priv = NULL;
++	struct resource 			*res;
++	int					irq, i, rval = 0;
++	int					major_id = 0;
++	void __iomem				*reg;
++
++	/* Get Base Address */
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "get mem resource failed\n");
++		return -ENOENT;
++	}
++
++	reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (!reg) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	/* Get IRQ NO. */
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "get irq failed\n");
++		return -ENOENT;
++	}
++
++	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv) {
++		dev_err(&pdev->dev, "no memory\n");
++		return -ENOMEM;
++	}
++
++	priv->regbase = reg;
++
++	priv->mode = 3;
++	priv->bpw = 16;
++
++	priv->r_buf_empty = 1;
++	priv->r_buf_full = 0;
++	priv->w_buf_empty = 1;
++	priv->w_buf_full = 0;
++
++	spin_lock_init(&priv->r_buf_lock);
++	spin_lock_init(&priv->w_buf_lock);
++	mutex_init(&priv->um_mtx);
++
++	ambarella_spi_slave_inithw(priv);
++
++	/* Request IRQ */
++	rval = devm_request_irq(&pdev->dev, irq, ambarella_spi_slave_isr,
++				IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), priv);
++	if (rval) {
++		rval = -EIO;
++		goto ambarella_spi_slave_probe_exit;
++	}
++
++	pdev->id = amb_slave_id++;
++	sprintf(priv->dev_name, "slave_spi%d", pdev->id);
++	major_id = register_chrdev(0, priv->dev_name, &spi_slave_fops);
++	if (major_id <= 0) {
++		rval = -EIO;
++		printk("Error: %s: Unable to get major number\n", __FILE__);
++		goto ambarella_spi_slave_probe_exit;
++	}
++
++	priv->major = major_id;
++
++	priv->psClass = class_create(THIS_MODULE, priv->dev_name);
++	if (IS_ERR(priv->psClass)) {
++		rval = -EIO;
++		printk("Error: %s: Unable to create class\n", __FILE__);
++		goto ambarella_spi_slave_probe_exit;
++	}
++
++	priv->psDev = device_create(priv->psClass, NULL, MKDEV(major_id, 0),
++					priv, priv->dev_name);
++	if (IS_ERR(priv->psDev)) {
++		rval = -EIO;
++		printk("Error: %s: Unable to create device\n", __FILE__);
++		goto ambarella_spi_slave_probe_exit;
++	}
++
++	platform_set_drvdata(pdev, priv);
++
++	if (pdev->id < MAX_SPI_SLAVES) {
++		mutex_lock(&g_mtx);
++		priv_array[pdev->id] = priv;
++		mutex_unlock(&g_mtx);
++	} else {
++		rval = -EIO;
++		printk("Error: %s: platform device id %d is greater than %d\n",
++			__FILE__, pdev->id, MAX_SPI_SLAVES - 1);
++		goto ambarella_spi_slave_probe_exit;
++	}
++
++	dev_info(&pdev->dev, "Ambarella SPI Slave Controller %d created!\n", pdev->id);
++
++	amba_writel(priv->regbase + SPI_SSIENR_OFFSET, 1);
++	for (i = 0; i < 16; i++) {
++		amba_writel(priv->regbase + SPI_DR_OFFSET, i);
++	}
++
++	return 0;
++
++ambarella_spi_slave_probe_exit:
++	if (rval < 0) {
++		if (priv->psDev) {
++			device_destroy(priv->psClass, MKDEV(major_id, 0));
++		}
++		if (priv->psClass) {
++			class_destroy(priv->psClass);
++		}
++		if (major_id > 0) {
++			unregister_chrdev(major_id, priv->dev_name);
++		}
++	}
++
++	return rval;
++}
++
++static int ambarella_spi_slave_remove(struct platform_device *pdev)
++{
++	struct ambarella_spi_slave	*priv;
++
++	priv = platform_get_drvdata(pdev);
++
++	mutex_lock(&g_mtx);
++	priv_array[pdev->id] = NULL;
++	mutex_unlock(&g_mtx);
++
++	mutex_lock(&priv->um_mtx);
++
++	if (priv->psDev) {
++		device_destroy(priv->psClass, MKDEV(priv->major, 0));
++	}
++	if (priv->psClass) {
++		class_destroy(priv->psClass);
++	}
++	if (priv->major > 0) {
++		unregister_chrdev(priv->major, priv->dev_name);
++	}
++
++	mutex_unlock(&priv->um_mtx);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_spi_slave_suspend_noirq(struct device *dev)
++{
++	return 0;
++}
++
++static int ambarella_spi_slave_resume_noirq(struct device *dev)
++{
++	return 0;
++}
++
++static const struct dev_pm_ops ambarella_spi_slave_dev_pm_ops = {
++	.suspend_noirq = ambarella_spi_slave_suspend_noirq,
++	.resume_noirq = ambarella_spi_slave_resume_noirq,
++};
++#endif
++
++static const struct of_device_id ambarella_spi_slave_dt_ids[] = {
++	{.compatible = "ambarella,spi-slave", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_spi_slave_dt_ids);
++
++static struct platform_driver ambarella_spi_slave_driver = {
++	.probe		= ambarella_spi_slave_probe,
++	.remove		= ambarella_spi_slave_remove,
++	.driver		= {
++		.name	= "ambarella-spi-slave",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_spi_slave_dt_ids,
++#ifdef CONFIG_PM
++		.pm	= &ambarella_spi_slave_dev_pm_ops,
++#endif
++	},
++};
++
++static int __init ambarella_spi_slave_init(void)
++{
++	return platform_driver_register(&ambarella_spi_slave_driver);
++}
++
++static void __exit ambarella_spi_slave_exit(void)
++{
++	platform_driver_unregister(&ambarella_spi_slave_driver);
++}
++
++subsys_initcall(ambarella_spi_slave_init);
++module_exit(ambarella_spi_slave_exit);
++
++MODULE_DESCRIPTION("Ambarella Media Processor SPI Slave Controller");
++MODULE_AUTHOR("Zhenwu Xue, <zwxue@ambarella.com>");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
+index 7e7006fd..72a14c9f 100644
+--- a/drivers/tty/serial/Kconfig
++++ b/drivers/tty/serial/Kconfig
+@@ -11,6 +11,22 @@ source "drivers/tty/serial/8250/Kconfig"
+ 
+ comment "Non-8250 serial port support"
+ 
++config SERIAL_AMBARELLA
++	tristate "Ambarella Media Soc serial port support"
++	depends on PLAT_AMBARELLA
++	select SERIAL_CORE
++	help
++	  If you have a machine based on an Ambarella Media SoC you
++	  can enable its onboard serial ports by enabling this option.
++
++config SERIAL_AMBARELLA_CONSOLE
++	bool "Console on Ambarella Media SoC serial port"
++	depends on SERIAL_AMBARELLA=y
++	select SERIAL_CORE_CONSOLE
++	help
++	  If you have enabled the serial port on the Ambarella Media SoC
++	  you can make it the console by answering Y to this option.
++
+ config SERIAL_AMBA_PL010
+ 	tristate "ARM AMBA PL010 serial port support"
+ 	depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
+diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
+index eedfec40..bf6588d3 100644
+--- a/drivers/tty/serial/Makefile
++++ b/drivers/tty/serial/Makefile
+@@ -2,6 +2,8 @@
+ # Makefile for the kernel serial device drivers.
+ #
+ 
++obj-$(CONFIG_SERIAL_AMBARELLA) += ambarella_uart.o
++
+ obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+ obj-$(CONFIG_SERIAL_21285) += 21285.o
+ 
+diff --git a/drivers/tty/serial/ambarella_uart.c b/drivers/tty/serial/ambarella_uart.c
+new file mode 100644
+index 00000000..768a7e68
+--- /dev/null
++++ b/drivers/tty/serial/ambarella_uart.c
+@@ -0,0 +1,1529 @@
++/*
++ * drivers/tty/serial/ambarella_uart.c
++ *
++ * Author: Anthony Ginger <hfjiang@ambarella.com>
++ *
++ * Copyright (C) 2004-2011, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#if defined(CONFIG_SERIAL_AMBARELLA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#endif
++
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/of_address.h>
++#include <linux/clk.h>
++#include <linux/syscore_ops.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++#include <linux/serial_reg.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/delay.h>
++#include <mach/hardware.h>
++#include <plat/clk.h>
++#include <plat/uart.h>
++#include <linux/dmaengine.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <plat/dma.h>
++#include <linux/slab.h>
++
++#define AMBA_UART_RX_DMA_BUFFER_SIZE 4096
++#define AMBA_UART_MIN_DMA			16
++#define AMBA_UART_LSR_ANY			(UART_LSR_OE | UART_LSR_BI |UART_LSR_PE | UART_LSR_FE)
++
++#define AMBARELLA_UART_RESET_FLAG		0 /* bit 0 */
++
++struct ambarella_uart_port {
++	struct uart_port port;
++	struct clk *uart_pll;
++	unsigned long flags;
++	u32 msr_used : 1;
++	u32 tx_fifo_fix : 1;
++	u32 less_reg : 1;
++	u32 txdma_used:1;
++	u32 rxdma_used:1;
++	u32 mcr;
++	u32 c_cflag;
++	/* following are for dma transfer */
++	struct dma_chan *rx_dma_chan;
++	struct dma_chan *tx_dma_chan;
++	unsigned char *rx_dma_buf_virt;
++	unsigned char *tx_dma_buf_virt;
++	dma_addr_t rx_dma_buf_phys;
++	dma_addr_t tx_dma_buf_phys;
++	dma_addr_t buf_phys_a;
++	dma_addr_t buf_phys_b;
++	unsigned char *buf_virt_a;
++	unsigned char *buf_virt_b;
++	bool use_buf_b;
++	struct dma_async_tx_descriptor *tx_dma_desc;
++	struct dma_async_tx_descriptor *rx_dma_desc;
++	dma_cookie_t tx_cookie;
++	dma_cookie_t rx_cookie;
++	int tx_bytes_requested;
++	int rx_bytes_requested;
++	int tx_in_progress;
++};
++
++static struct ambarella_uart_port ambarella_port[UART_INSTANCES];
++
++static void __serial_ambarella_stop_tx(struct uart_port *port, u32 tx_fifo_fix)
++{
++	u32 ier, iir;
++
++	if (tx_fifo_fix) {
++		ier = amba_readl(port->membase + UART_IE_OFFSET);
++		if ((ier & UART_IE_PTIME) != UART_IE_PTIME)
++			amba_writel(port->membase + UART_IE_OFFSET,
++					ier | (UART_IE_PTIME | UART_IE_ETBEI));
++
++		iir = amba_readl(port->membase + UART_II_OFFSET);
++		amba_writel(port->membase + UART_IE_OFFSET,
++			ier & ~(UART_IE_PTIME | UART_IE_ETBEI));
++		(void)(iir);
++	} else {
++		amba_clrbitsl(port->membase + UART_IE_OFFSET, UART_IE_ETBEI);
++	}
++}
++
++static u32 __serial_ambarella_read_ms(struct uart_port *port, u32 tx_fifo_fix)
++{
++	u32 ier, ms;
++
++	if (tx_fifo_fix) {
++		ier = amba_readl(port->membase + UART_IE_OFFSET);
++		if ((ier & UART_IE_EDSSI) != UART_IE_EDSSI)
++			amba_writel(port->membase + UART_IE_OFFSET,
++					ier | UART_IE_EDSSI);
++
++		ms = amba_readl(port->membase + UART_MS_OFFSET);
++		if ((ier & UART_IE_EDSSI) != UART_IE_EDSSI)
++			amba_writel(port->membase + UART_IE_OFFSET, ier);
++	} else {
++		ms = amba_readl(port->membase + UART_MS_OFFSET);
++	}
++
++	return ms;
++}
++
++static void __serial_ambarella_enable_ms(struct uart_port *port)
++{
++	amba_setbitsl(port->membase + UART_IE_OFFSET, UART_IE_EDSSI);
++}
++
++static void __serial_ambarella_disable_ms(struct uart_port *port)
++{
++	amba_clrbitsl(port->membase + UART_IE_OFFSET, UART_IE_EDSSI);
++}
++
++static inline void wait_for_tx(struct uart_port *port)
++{
++	u32 ls;
++
++	ls = amba_readl(port->membase + UART_LS_OFFSET);
++	while ((ls & UART_LS_TEMT) != UART_LS_TEMT) {
++		cpu_relax();
++		ls = amba_readl(port->membase + UART_LS_OFFSET);
++	}
++}
++
++static inline void wait_for_rx(struct uart_port *port)
++{
++	u32 ls;
++
++	ls = amba_readl(port->membase + UART_LS_OFFSET);
++	while ((ls & UART_LS_DR) != UART_LS_DR) {
++		cpu_relax();
++		ls = amba_readl(port->membase + UART_LS_OFFSET);
++	}
++}
++
++static inline int tx_fifo_is_full(struct uart_port *port)
++{
++	return !(amba_readl(port->membase + UART_US_OFFSET) & UART_US_TFNF);
++}
++
++/* ==========================================================================*/
++static void serial_ambarella_hw_setup(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	if (!test_and_set_bit(AMBARELLA_UART_RESET_FLAG, &amb_port->flags)) {
++		clk_set_rate(amb_port->uart_pll, ambarella_clk_get_ref_freq());
++		port->uartclk = clk_get_rate(amb_port->uart_pll);
++		/* reset the whole UART only once */
++		amba_writel(port->membase + UART_SRR_OFFSET, 0x01);
++		mdelay(1);
++		amba_writel(port->membase + UART_SRR_OFFSET, 0x00);
++	}
++
++	amba_writel(port->membase + UART_IE_OFFSET,
++		DEFAULT_AMBARELLA_UART_IER | UART_IE_PTIME);
++	amba_writel(port->membase + UART_FC_OFFSET,
++		UART_FC_FIFOE | UART_FC_RX_2_TO_FULL |
++		UART_FC_TX_EMPTY | UART_FC_XMITR | UART_FC_RCVRR);
++	amba_writel(port->membase + UART_IE_OFFSET,
++		DEFAULT_AMBARELLA_UART_IER);
++
++	if (amb_port->txdma_used || amb_port->rxdma_used) {
++		/* we must use 14bytes as trigger, because if we use 8bytes, FIFO may
++		* be empty due to dma burst size is also set to 8bytes before dma complete,
++		* in this case, if FIFO is empty, but no more data is received, timeout irq
++		* can't be trigged after, we don't have chance to push the data that dma has
++		* transfered any more.
++		*/
++		amba_writel(port->membase + UART_FC_OFFSET,
++			UART_FC_FIFOE | UART_FC_RX_2_TO_FULL |
++			UART_FC_TX_EMPTY | UART_FC_XMITR |
++			UART_FC_RCVRR |UART_FCR_DMA_SELECT);
++		amba_writel(port->membase + UART_DMAE_OFFSET,
++			(amb_port->txdma_used << 1) | amb_port->rxdma_used);
++	}
++}
++
++static inline void serial_ambarella_receive_chars(struct uart_port *port,
++	u32 tmo)
++{
++	u32 ch, flag, ls;
++	int max_count;
++
++	ls = amba_readl(port->membase + UART_LS_OFFSET);
++	max_count = port->fifosize;
++
++	do {
++		flag = TTY_NORMAL;
++		if (unlikely(ls & (UART_LS_BI | UART_LS_PE |
++					UART_LS_FE | UART_LS_OE))) {
++			if (ls & UART_LS_BI) {
++				ls &= ~(UART_LS_FE | UART_LS_PE);
++				port->icount.brk++;
++
++				if (uart_handle_break(port))
++					goto ignore_char;
++			}
++			if (ls & UART_LS_FE)
++				port->icount.frame++;
++			if (ls & UART_LS_PE)
++				port->icount.parity++;
++			if (ls & UART_LS_OE)
++				port->icount.overrun++;
++
++			ls &= port->read_status_mask;
++
++			if (ls & UART_LS_BI)
++				flag = TTY_BREAK;
++			else if (ls & UART_LS_FE)
++				flag = TTY_FRAME;
++			else if (ls & UART_LS_PE)
++				flag = TTY_PARITY;
++			else if (ls & UART_LS_OE)
++				flag = TTY_OVERRUN;
++
++			if (ls & UART_LS_OE) {
++				printk(KERN_DEBUG "%s: OVERFLOW\n", __func__);
++			}
++		}
++
++		if (likely(ls & UART_LS_DR)) {
++			ch = amba_readl(port->membase + UART_RB_OFFSET);
++			port->icount.rx++;
++			tmo = 0;
++
++			if (uart_handle_sysrq_char(port, ch))
++				goto ignore_char;
++
++			uart_insert_char(port, ls, UART_LS_OE, ch, flag);
++		} else {
++			if (tmo) {
++				ch = amba_readl(port->membase + UART_RB_OFFSET);
++				/* printk(KERN_DEBUG "False TMO get %d\n", ch); */
++			}
++		}
++
++ignore_char:
++		ls = amba_readl(port->membase + UART_LS_OFFSET);
++	} while ((ls & UART_LS_DR) && (max_count-- > 0));
++
++	spin_unlock(&port->lock);
++	tty_flip_buffer_push(&port->state->port);
++	spin_lock(&port->lock);
++}
++
++static void serial_ambarella_transmit_chars(struct uart_port *port)
++{
++	struct circ_buf *xmit = &port->state->xmit;
++	struct ambarella_uart_port *amb_port;
++	int count;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	if (port->x_char) {
++		amba_writel(port->membase + UART_TH_OFFSET, port->x_char);
++		port->icount.tx++;
++		port->x_char = 0;
++		return;
++	}
++
++	if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
++		__serial_ambarella_stop_tx(port, amb_port->tx_fifo_fix);
++		return;
++	}
++
++	count = port->fifosize;
++	while (count-- > 0) {
++		if (!amb_port->less_reg && tx_fifo_is_full(port))
++			break;
++		amba_writel(port->membase + UART_TH_OFFSET, xmit->buf[xmit->tail]);
++		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++		port->icount.tx++;
++		if (uart_circ_empty(xmit))
++			break;
++	}
++
++	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++		uart_write_wakeup(port);
++	if (uart_circ_empty(xmit))
++		__serial_ambarella_stop_tx(port, amb_port->tx_fifo_fix);
++}
++
++static inline void serial_ambarella_check_modem_status(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++	u32 ms;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	if (amb_port->msr_used) {
++		ms = __serial_ambarella_read_ms(port, amb_port->tx_fifo_fix);
++
++		if (ms & UART_MS_RI)
++			port->icount.rng++;
++		if (ms & UART_MS_DSR)
++			port->icount.dsr++;
++		if (ms & UART_MS_DCTS)
++			uart_handle_cts_change(port, (ms & UART_MS_CTS));
++		if (ms & UART_MS_DDCD)
++			uart_handle_dcd_change(port, (ms & UART_MS_DCD));
++
++		wake_up_interruptible(&port->state->port.delta_msr_wait);
++	}
++}
++
++static char serial_ambarella_decode_rx_error(struct ambarella_uart_port *amb_port,
++			unsigned long lsr)
++{
++	char flag = TTY_NORMAL;
++
++	if (unlikely(lsr & AMBA_UART_LSR_ANY)) {
++		if (lsr & UART_LSR_OE) {
++			/* Overrrun error */
++			flag |= TTY_OVERRUN;
++			amb_port->port.icount.overrun++;
++			dev_err(amb_port->port.dev, "Got overrun errors\n");
++		} else if (lsr & UART_LSR_PE) {
++			/* Parity error */
++			flag |= TTY_PARITY;
++			amb_port->port.icount.parity++;
++			dev_err(amb_port->port.dev, "Got Parity errors\n");
++		} else if (lsr & UART_LSR_FE) {
++			flag |= TTY_FRAME;
++			amb_port->port.icount.frame++;
++			dev_err(amb_port->port.dev, "Got frame errors\n");
++		} else if (lsr & UART_LSR_BI) {
++			dev_err(amb_port->port.dev, "Got Break\n");
++			amb_port->port.icount.brk++;
++			/* If FIFO read error without any data, reset Rx FIFO */
++			if (!(lsr & UART_LSR_DR) && (lsr & UART_LSR_FIFOE))
++				amba_writel(amb_port->port.membase + UART_SRR_OFFSET,
++					UART_FCR_CLEAR_RCVR);
++		}
++	}
++	return flag;
++}
++
++static void serial_ambarella_handle_rx_pio(struct ambarella_uart_port *amb_port,
++		struct tty_port *tty)
++{
++	do {
++		char flag = TTY_NORMAL;
++		unsigned long lsr = 0;
++		unsigned char ch;
++
++		lsr = amba_readl(amb_port->port.membase + UART_LS_OFFSET);
++		if (!(lsr & UART_LS_DR))
++			break;
++
++		flag = serial_ambarella_decode_rx_error(amb_port, lsr);
++		ch = (unsigned char) amba_readl(amb_port->port.membase + UART_RB_OFFSET);
++		amb_port->port.icount.rx++;
++
++		if (!uart_handle_sysrq_char(&amb_port->port, ch) && tty)
++			tty_insert_flip_char(tty, ch, flag);
++	} while (1);
++
++	return;
++}
++
++static void serial_ambarella_copy_rx_to_tty(struct ambarella_uart_port *amb_port,
++		struct tty_port *tty, int count);
++static int serial_ambarella_start_rx_dma(struct ambarella_uart_port *amb_port);
++
++static void serial_ambarella_dma_rx_irq(struct ambarella_uart_port *amb_port)
++{
++	struct tty_port *port = &amb_port->port.state->port;
++	struct tty_struct *tty = tty_port_tty_get(&amb_port->port.state->port);
++	struct dma_tx_state state;
++	size_t pending;
++
++	dmaengine_tx_status(amb_port->rx_dma_chan, amb_port->rx_cookie, &state);
++	dmaengine_terminate_all(amb_port->rx_dma_chan);
++
++	pending = amb_port->rx_bytes_requested - state.residue;
++	BUG_ON(pending > AMBA_UART_RX_DMA_BUFFER_SIZE);
++
++	/* switch the rx buffer */
++	amb_port->use_buf_b = !amb_port->use_buf_b;
++
++	serial_ambarella_start_rx_dma(amb_port);
++
++	serial_ambarella_copy_rx_to_tty(amb_port, port, pending);
++
++	serial_ambarella_handle_rx_pio(amb_port, port);
++
++	if (tty) {
++		tty_flip_buffer_push(port);
++		tty_kref_put(tty);
++	}
++}
++
++static void serial_ambarella_start_tx(struct uart_port *port);
++
++static irqreturn_t serial_ambarella_irq(int irq, void *dev_id)
++{
++	struct uart_port *port = dev_id;
++	int rval = IRQ_HANDLED;
++	u32 ii;
++	unsigned long flags;
++
++	struct ambarella_uart_port *amb_port;
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	spin_lock_irqsave(&port->lock, flags);
++
++	ii = amba_readl(port->membase + UART_II_OFFSET);
++	switch (ii & 0x0F) {
++	case UART_II_MODEM_STATUS_CHANGED:
++		serial_ambarella_check_modem_status(port);
++		break;
++
++	case UART_II_THR_EMPTY:
++		if (amb_port->txdma_used)
++			serial_ambarella_start_tx(port);
++		else
++			serial_ambarella_transmit_chars(port);
++		break;
++
++	case UART_II_RCV_STATUS:
++	case UART_II_RCV_DATA_AVAIL:
++		serial_ambarella_receive_chars(port, 0);
++		break;
++	case UART_II_CHAR_TIMEOUT:
++		if (amb_port->rxdma_used){
++			struct ambarella_uart_port *amb_port;
++			amb_port = (struct ambarella_uart_port *)(port->private_data);
++			serial_ambarella_dma_rx_irq(amb_port);
++		} else {
++			serial_ambarella_receive_chars(port, 1);
++		}
++		break;
++
++	case UART_II_NO_INT_PENDING:
++		break;
++	default:
++		printk(KERN_DEBUG "%s: 0x%x\n", __func__, ii);
++		break;
++	}
++
++	spin_unlock_irqrestore(&port->lock, flags);
++
++	return rval;
++}
++
++/* ==========================================================================*/
++static void serial_ambarella_enable_ms(struct uart_port *port)
++{
++	__serial_ambarella_enable_ms(port);
++}
++
++static void serial_ambarella_start_next_tx(struct ambarella_uart_port *amb_port);
++
++static void serial_ambarella_tx_dma_complete(void *args)
++{
++	struct ambarella_uart_port *amb_port = args;
++	struct circ_buf *xmit = &amb_port->port.state->xmit;
++	struct dma_tx_state state;
++	unsigned long flags;
++	int count;
++
++	dmaengine_tx_status(amb_port->tx_dma_chan, amb_port->tx_cookie, &state);
++	count = amb_port->tx_bytes_requested - state.residue;
++	spin_lock_irqsave(&amb_port->port.lock, flags);
++	xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
++	amb_port->tx_in_progress = 0;
++	amb_port->port.icount.tx += count;
++	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++		uart_write_wakeup(&amb_port->port);
++	serial_ambarella_start_next_tx(amb_port);
++	spin_unlock_irqrestore(&amb_port->port.lock, flags);
++}
++
++static int serial_ambarella_start_tx_dma(struct ambarella_uart_port *amb_port,
++		unsigned long count)
++{
++	struct circ_buf *xmit = &amb_port->port.state->xmit;
++	dma_addr_t tx_phys_addr;
++	int tx_bytes;
++
++	dma_sync_single_for_device(amb_port->port.dev, amb_port->tx_dma_buf_phys,
++				UART_XMIT_SIZE, DMA_TO_DEVICE);
++
++	tx_bytes = count & ~(0xF);
++	tx_phys_addr = amb_port->tx_dma_buf_phys + xmit->tail;
++	amb_port->tx_dma_desc = dmaengine_prep_slave_single(amb_port->tx_dma_chan,
++				tx_phys_addr, tx_bytes, DMA_MEM_TO_DEV,
++				DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP |
++				DMA_COMPL_SKIP_DEST_UNMAP | DMA_CTRL_ACK);
++	if (!amb_port->tx_dma_desc) {
++		dev_err(amb_port->port.dev, "Not able to get desc for Tx\n");
++		return -EIO;
++	}
++
++	amb_port->tx_dma_desc->callback = serial_ambarella_tx_dma_complete;
++	amb_port->tx_dma_desc->callback_param = amb_port;
++	amb_port->tx_bytes_requested = tx_bytes;
++	amb_port->tx_in_progress = 1;
++	amb_port->tx_cookie = dmaengine_submit(amb_port->tx_dma_desc);
++	dma_async_issue_pending(amb_port->tx_dma_chan);
++
++	return 0;
++}
++
++static void serial_ambarella_start_next_tx(struct ambarella_uart_port *amb_port)
++{
++	struct circ_buf *xmit = &amb_port->port.state->xmit;
++	struct uart_port *port;
++	unsigned long tail, count;
++
++	port = &amb_port->port;
++
++	tail = (unsigned long)&xmit->buf[xmit->tail];
++	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
++	if (!count)
++		return;
++
++	wait_for_tx(port);
++	if (count < AMBA_UART_MIN_DMA)
++		serial_ambarella_transmit_chars(port);
++	else
++		serial_ambarella_start_tx_dma(amb_port, count);
++}
++
++static void serial_ambarella_start_tx(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++	struct tty_struct *tty;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++	tty = tty_port_tty_get(&amb_port->port.state->port);
++
++	amba_setbitsl(port->membase + UART_IE_OFFSET, UART_IE_ETBEI);
++
++	if (amb_port->txdma_used) {
++		if (tty->hw_stopped ||amb_port->tx_in_progress)
++			return;
++		serial_ambarella_start_next_tx(amb_port);
++	} else {
++		/* if FIFO status register is not provided, we have no idea about
++	 	* the Tx FIFO is full or not, so we need to wait for the Tx Empty
++		 * Interrupt comming, then we can start to transfer data. */
++		if (amb_port->less_reg)
++			return;
++
++		serial_ambarella_transmit_chars(port);
++	}
++}
++
++static void serial_ambarella_copy_rx_to_tty(struct ambarella_uart_port *amb_port,
++		struct tty_port *tty, int count)
++{
++	dma_addr_t old_buf_phys;
++	unsigned char *old_buf_virt;
++
++	amb_port->port.icount.rx += count;
++	if (!tty) {
++		dev_err(amb_port->port.dev, "No tty port\n");
++		return;
++	}
++
++	/* use old buffer to copy data to tty, and use new buffer to receive */
++	if (amb_port->use_buf_b) {
++		old_buf_phys = amb_port->buf_phys_a;
++		old_buf_virt = amb_port->buf_virt_a;
++	} else {
++		old_buf_phys = amb_port->buf_phys_b;
++		old_buf_virt = amb_port->buf_virt_b;
++	}
++
++	dma_sync_single_for_cpu(amb_port->port.dev, old_buf_phys,
++		AMBA_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
++
++	tty_insert_flip_string(tty, old_buf_virt, count);
++}
++
++static void serial_ambarella_rx_dma_complete(void *args)
++{
++	struct ambarella_uart_port *amb_port = args;
++	struct tty_struct *tty = tty_port_tty_get(&amb_port->port.state->port);
++	struct uart_port *u = &amb_port->port;
++	struct tty_port *port = &u->state->port;
++	int count = amb_port->rx_bytes_requested;
++	unsigned long flags;
++
++	/* switch the rx buffer */
++	amb_port->use_buf_b = !amb_port->use_buf_b;
++	serial_ambarella_start_rx_dma(amb_port);
++
++	serial_ambarella_copy_rx_to_tty(amb_port, port, count);
++
++	spin_lock_irqsave(&u->lock, flags);
++	if (tty) {
++		tty_flip_buffer_push(port);
++		tty_kref_put(tty);
++	}
++	spin_unlock_irqrestore(&u->lock, flags);
++}
++
++static int serial_ambarella_start_rx_dma(struct ambarella_uart_port *amb_port)
++{
++	unsigned int count = AMBA_UART_RX_DMA_BUFFER_SIZE;
++
++	if (amb_port->use_buf_b) {
++		amb_port->rx_dma_buf_virt = amb_port->buf_virt_b;
++		amb_port->rx_dma_buf_phys = amb_port->buf_phys_b;
++	} else {
++		amb_port->rx_dma_buf_virt = amb_port->buf_virt_a;
++		amb_port->rx_dma_buf_phys = amb_port->buf_phys_a;
++	}
++
++	amb_port->rx_dma_desc = dmaengine_prep_slave_single(amb_port->rx_dma_chan,
++				amb_port->rx_dma_buf_phys, count, DMA_DEV_TO_MEM,
++				DMA_PREP_INTERRUPT | DMA_CTRL_ACK| DMA_COMPL_SKIP_SRC_UNMAP |
++				DMA_COMPL_SKIP_DEST_UNMAP);
++
++	if (!amb_port->rx_dma_desc) {
++		dev_err(amb_port->port.dev, "Not able to get desc for Rx\n");
++		return -EIO;
++	}
++
++	amb_port->rx_dma_desc->callback = serial_ambarella_rx_dma_complete;
++	amb_port->rx_dma_desc->callback_param = amb_port;
++	dma_sync_single_for_device(amb_port->port.dev, amb_port->rx_dma_buf_phys,
++				count, DMA_TO_DEVICE);
++	amb_port->rx_bytes_requested = count;
++	amb_port->rx_cookie = dmaengine_submit(amb_port->rx_dma_desc);
++	dma_async_issue_pending(amb_port->rx_dma_chan);
++
++	return 0;
++}
++
++static void serial_ambarella_stop_tx(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	__serial_ambarella_stop_tx(port, amb_port->tx_fifo_fix);
++}
++
++static void serial_ambarella_stop_rx(struct uart_port *port)
++{
++	amba_clrbitsl(port->membase + UART_IE_OFFSET, UART_IE_ERBFI);
++}
++
++static unsigned int serial_ambarella_tx_empty(struct uart_port *port)
++{
++	unsigned int lsr;
++	unsigned long flags;
++
++	spin_lock_irqsave(&port->lock, flags);
++	lsr = amba_readl(port->membase + UART_LS_OFFSET);
++	spin_unlock_irqrestore(&port->lock, flags);
++
++	return ((lsr & (UART_LS_TEMT | UART_LS_THRE)) ==
++		(UART_LS_TEMT | UART_LS_THRE)) ? TIOCSER_TEMT : 0;
++}
++
++static unsigned int serial_ambarella_get_mctrl(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++	u32 ms, mctrl = 0;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	if (amb_port->msr_used) {
++		ms = __serial_ambarella_read_ms(port, amb_port->tx_fifo_fix);
++
++		if (ms & UART_MS_CTS)
++			mctrl |= TIOCM_CTS;
++		if (ms & UART_MS_DSR)
++			mctrl |= TIOCM_DSR;
++		if (ms & UART_MS_RI)
++			mctrl |= TIOCM_RI;
++		if (ms & UART_MS_DCD)
++			mctrl |= TIOCM_CD;
++	}
++
++	return mctrl;
++}
++
++static void serial_ambarella_set_mctrl(struct uart_port *port,
++	unsigned int mctrl)
++{
++	struct ambarella_uart_port *amb_port;
++	u32 mcr, mcr_new = 0;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	if (amb_port->msr_used) {
++		mcr = amba_readl(port->membase + UART_MC_OFFSET);
++
++		if (mctrl & TIOCM_DTR)
++			mcr_new |= UART_MC_DTR;
++		if (mctrl & TIOCM_RTS)
++			mcr_new |= UART_MC_RTS;
++		if (mctrl & TIOCM_OUT1)
++			mcr_new |= UART_MC_OUT1;
++		if (mctrl & TIOCM_OUT2)
++			mcr_new |= UART_MC_OUT2;
++		if (mctrl & TIOCM_LOOP)
++			mcr_new |= UART_MC_LB;
++
++		mcr_new |= amb_port->mcr;
++		if (mcr_new != mcr) {
++			if ((mcr & UART_MC_AFCE) == UART_MC_AFCE) {
++				mcr &= ~UART_MC_AFCE;
++				amba_writel(port->membase + UART_MC_OFFSET,
++					mcr);
++			}
++			amba_writel(port->membase + UART_MC_OFFSET, mcr_new);
++		}
++	}
++}
++
++static void serial_ambarella_break_ctl(struct uart_port *port, int break_state)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&port->lock, flags);
++	if (break_state != 0)
++		amba_setbitsl(port->membase + UART_LC_OFFSET, UART_LC_BRK);
++	else
++		amba_clrbitsl(port->membase + UART_LC_OFFSET, UART_LC_BRK);
++	spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static bool serial_ambarella_dma_filter(struct dma_chan *chan, void *fparam)
++{
++	int chan_id;
++	bool ret = false;
++
++	chan_id = *(int *)fparam;
++
++	if (ambarella_dma_channel_id(chan) == chan_id)
++		ret = true;
++
++	return ret;
++}
++
++static int serial_ambarella_dma_channel_allocate(struct ambarella_uart_port *amb_port,
++			bool dma_to_memory)
++{
++	struct dma_chan *dma_chan;
++	struct dma_slave_config dma_sconfig;
++	dma_addr_t dma_phys;
++	dma_cap_mask_t mask;
++	unsigned char *dma_buf;
++	int ret, chan_id;
++
++	if (dma_to_memory)
++		chan_id = UART_RX_DMA_CHAN;
++	else
++		chan_id = UART_TX_DMA_CHAN;
++
++	dma_cap_zero(mask);
++	dma_cap_set(DMA_SLAVE, mask);
++	dma_chan = dma_request_channel(mask, serial_ambarella_dma_filter, &chan_id);
++	if (!dma_chan) {
++		dev_err(amb_port->port.dev,
++			"Dma channel is not available, will try later\n");
++		return -EPROBE_DEFER;
++	}
++
++	if (dma_to_memory) {
++		/* use double buffer to handle rx */
++		dma_buf = kmalloc(AMBA_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL);
++		dma_phys = virt_to_phys(dma_buf);
++		if (!dma_buf) {
++			dev_err(amb_port->port.dev,
++				"Not able to allocate the dma buffer a\n");
++			dma_release_channel(dma_chan);
++			return -ENOMEM;
++		}
++
++		amb_port->buf_virt_a = dma_buf;
++		amb_port->buf_phys_a = dma_phys;
++
++		/* buffer b */
++		dma_buf = kmalloc(AMBA_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL);
++		dma_phys = virt_to_phys(dma_buf);
++		if (!dma_buf) {
++			dev_err(amb_port->port.dev,
++				"Not able to allocate the dma buffer b\n");
++			dma_release_channel(dma_chan);
++			return -ENOMEM;
++		}
++
++		amb_port->buf_virt_b = dma_buf;
++		amb_port->buf_phys_b = dma_phys;
++
++	} else {
++		dma_phys = dma_map_single(amb_port->port.dev,
++			amb_port->port.state->xmit.buf, UART_XMIT_SIZE,
++			DMA_TO_DEVICE);
++		dma_buf = amb_port->port.state->xmit.buf;
++	}
++
++	if (dma_to_memory) {
++		dma_sconfig.src_addr = amb_port->port.mapbase + UART_DMAF_OFFSET;
++		dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
++		dma_sconfig.src_maxburst = 8;
++		dma_sconfig.direction = DMA_DEV_TO_MEM;
++	} else {
++		dma_sconfig.dst_addr = amb_port->port.mapbase + UART_DMAF_OFFSET;
++		dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
++		dma_sconfig.dst_maxburst = 16;
++		dma_sconfig.direction = DMA_MEM_TO_DEV;
++	}
++
++	ret = dmaengine_slave_config(dma_chan, &dma_sconfig);
++	if (ret < 0) {
++		dev_err(amb_port->port.dev,
++			"Dma slave config failed, err = %d\n", ret);
++		goto scrub;
++	}
++
++	if (dma_to_memory) {
++		amb_port->rx_dma_chan = dma_chan;
++		amb_port->rx_dma_buf_virt = amb_port->buf_virt_a;
++		amb_port->rx_dma_buf_phys = amb_port->buf_phys_a;
++	} else {
++		amb_port->tx_dma_chan = dma_chan;
++		amb_port->tx_dma_buf_virt = dma_buf;
++		amb_port->tx_dma_buf_phys = dma_phys;
++	}
++	return 0;
++
++scrub:
++	dma_release_channel(dma_chan);
++	return ret;
++}
++
++static int serial_ambarella_startup(struct uart_port *port)
++{
++	int rval = 0;
++	struct ambarella_uart_port *amb_port;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	serial_ambarella_hw_setup(port);
++
++	rval = request_irq(port->irq, serial_ambarella_irq,
++		IRQF_TRIGGER_HIGH, dev_name(port->dev), port);
++
++	if (amb_port->txdma_used) {
++		rval = serial_ambarella_dma_channel_allocate(amb_port, false);
++		if (rval < 0) {
++			dev_err(amb_port->port.dev, "Tx Dma allocation failed, err = %d\n", rval);
++			return -EBUSY;
++		}
++	}
++
++	if (amb_port->rxdma_used) {
++		amb_port->use_buf_b = false;
++
++		rval = serial_ambarella_dma_channel_allocate(amb_port, true);
++		if (rval < 0) {
++			dev_err(amb_port->port.dev, "Rx Dma allocation failed, err = %d\n", rval);
++			return -EBUSY;
++		}
++
++		rval = serial_ambarella_start_rx_dma(amb_port);
++		if (rval < 0) {
++			dev_err(amb_port->port.dev, "Not able to start Rx DMA\n");
++			return rval;
++		}
++	}
++
++	return rval;
++}
++
++static void serial_ambarella_hw_deinit(struct ambarella_uart_port *amb_port)
++{
++	struct uart_port *port = &amb_port->port;
++
++	/* Disable interrupts */
++	amba_writel(port->membase + UART_IE_OFFSET, 0);
++	/* Reset the Rx and Tx FIFOs */
++	amba_writel(port->membase + UART_SRR_OFFSET,
++		UART_FCR_CLEAR_XMIT| UART_FCR_CLEAR_RCVR);
++}
++
++static void serial_ambarella_dma_channel_free(struct ambarella_uart_port *amb_port,
++		bool dma_to_memory)
++{
++	struct dma_chan *dma_chan;
++
++	if (dma_to_memory) {
++		kfree(amb_port->buf_virt_a);
++		kfree(amb_port->buf_virt_b);
++
++		dma_chan = amb_port->rx_dma_chan;
++		amb_port->rx_dma_chan = NULL;
++		amb_port->rx_dma_buf_phys = 0;
++		amb_port->rx_dma_buf_virt = NULL;
++		amb_port->buf_phys_a = 0;
++		amb_port->buf_virt_a = NULL;
++		amb_port->buf_phys_b = 0;
++		amb_port->buf_virt_b = NULL;
++	} else {
++		dma_unmap_single(amb_port->port.dev, amb_port->tx_dma_buf_phys,
++			UART_XMIT_SIZE, DMA_TO_DEVICE);
++		dma_chan = amb_port->tx_dma_chan;
++		amb_port->tx_dma_chan = NULL;
++		amb_port->tx_dma_buf_phys = 0;
++		amb_port->tx_dma_buf_virt = NULL;
++	}
++	dma_release_channel(dma_chan);
++}
++
++static void serial_ambarella_shutdown(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++	unsigned long flags;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++
++	spin_lock_irqsave(&port->lock, flags);
++
++	if (amb_port->txdma_used || amb_port->rxdma_used) {
++		serial_ambarella_hw_deinit(amb_port);
++		spin_unlock_irqrestore(&port->lock, flags);
++
++		if (amb_port->txdma_used) {
++			dmaengine_terminate_all(amb_port->tx_dma_chan);
++			serial_ambarella_dma_channel_free(amb_port, false);
++			amb_port->tx_in_progress = 0;
++		}
++		if (amb_port->rxdma_used) {
++			dmaengine_terminate_all(amb_port->rx_dma_chan);
++			serial_ambarella_dma_channel_free(amb_port, true);
++		}
++
++		spin_lock_irqsave(&port->lock, flags);
++	}
++
++	amba_clrbitsl(port->membase + UART_LC_OFFSET, UART_LC_BRK);
++	spin_unlock_irqrestore(&port->lock, flags);
++
++	free_irq(port->irq, port);
++}
++
++static void serial_ambarella_set_termios(struct uart_port *port,
++	struct ktermios *termios, struct ktermios *old)
++{
++	struct ambarella_uart_port *amb_port;
++	unsigned int baud, quot;
++	u32 lc = 0x0;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++	amb_port->c_cflag = termios->c_cflag;
++
++	port->uartclk = clk_get_rate(amb_port->uart_pll);
++	switch (termios->c_cflag & CSIZE) {
++	case CS5:
++		lc |= UART_LC_CLS_5_BITS;
++		break;
++	case CS6:
++		lc |= UART_LC_CLS_6_BITS;
++		break;
++	case CS7:
++		lc |= UART_LC_CLS_7_BITS;
++		break;
++	case CS8:
++	default:
++		lc |= UART_LC_CLS_8_BITS;
++		break;
++	}
++
++	if (termios->c_cflag & CSTOPB)
++		lc |= UART_LC_STOP_2BIT;
++	else
++		lc |= UART_LC_STOP_1BIT;
++
++	if (termios->c_cflag & PARENB) {
++		if (termios->c_cflag & PARODD)
++			lc |= (UART_LC_PEN | UART_LC_ODD_PARITY);
++		else
++			lc |= (UART_LC_PEN | UART_LC_EVEN_PARITY);
++	}
++
++	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
++	quot = uart_get_divisor(port, baud);
++
++	disable_irq(port->irq);
++	uart_update_timeout(port, termios->c_cflag, baud);
++
++	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
++	if (termios->c_iflag & INPCK)
++		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++	if (termios->c_iflag & (BRKINT | PARMRK))
++		port->read_status_mask |= UART_LSR_BI;
++
++	port->ignore_status_mask = 0;
++	if (termios->c_iflag & IGNPAR)
++		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
++	if (termios->c_iflag & IGNBRK) {
++		port->ignore_status_mask |= UART_LSR_BI;
++		if (termios->c_iflag & IGNPAR)
++			port->ignore_status_mask |= UART_LSR_OE;
++	}
++	if ((termios->c_cflag & CREAD) == 0)
++		port->ignore_status_mask |= UART_LSR_DR;
++
++	if ((termios->c_cflag & CRTSCTS) == 0)
++		amb_port->mcr &= ~UART_MC_AFCE;
++	else
++		amb_port->mcr |= UART_MC_AFCE;
++
++	amba_writel(port->membase + UART_LC_OFFSET, UART_LC_DLAB);
++	amba_writel(port->membase + UART_DLL_OFFSET, quot & 0xff);
++	amba_writel(port->membase + UART_DLH_OFFSET, (quot >> 8) & 0xff);
++	amba_writel(port->membase + UART_LC_OFFSET, lc);
++	if (UART_ENABLE_MS(port, termios->c_cflag))
++		__serial_ambarella_enable_ms(port);
++	else
++		__serial_ambarella_disable_ms(port);
++	serial_ambarella_set_mctrl(port, port->mctrl);
++
++	enable_irq(port->irq);
++}
++
++static void serial_ambarella_pm(struct uart_port *port,
++	unsigned int state, unsigned int oldstate)
++{
++}
++
++static void serial_ambarella_release_port(struct uart_port *port)
++{
++}
++
++static int serial_ambarella_request_port(struct uart_port *port)
++{
++	return 0;
++}
++
++static void serial_ambarella_config_port(struct uart_port *port, int flags)
++{
++}
++
++static int serial_ambarella_verify_port(struct uart_port *port,
++					struct serial_struct *ser)
++{
++	int rval = 0;
++
++	if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
++		rval = -EINVAL;
++	if (port->irq != ser->irq)
++		rval = -EINVAL;
++	if (ser->io_type != SERIAL_IO_MEM)
++		rval = -EINVAL;
++
++	return rval;
++}
++
++static const char *serial_ambarella_type(struct uart_port *port)
++{
++	return "ambuart";
++}
++
++#ifdef CONFIG_CONSOLE_POLL
++static void serial_ambarella_poll_put_char(struct uart_port *port,
++	unsigned char chr)
++{
++	struct ambarella_uart_port *amb_port;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++	if (!port->suspended) {
++		wait_for_tx(port);
++		amba_writel(port->membase + UART_TH_OFFSET, chr);
++	}
++}
++
++static int serial_ambarella_poll_get_char(struct uart_port *port)
++{
++	struct ambarella_uart_port *amb_port;
++
++	amb_port = (struct ambarella_uart_port *)(port->private_data);
++	if (!port->suspended) {
++		wait_for_rx(port);
++		return amba_readl(port->membase + UART_RB_OFFSET);
++	}
++	return 0;
++}
++#endif
++
++struct uart_ops serial_ambarella_pops = {
++	.tx_empty	= serial_ambarella_tx_empty,
++	.set_mctrl	= serial_ambarella_set_mctrl,
++	.get_mctrl	= serial_ambarella_get_mctrl,
++	.stop_tx	= serial_ambarella_stop_tx,
++	.start_tx	= serial_ambarella_start_tx,
++	.stop_rx	= serial_ambarella_stop_rx,
++	.enable_ms	= serial_ambarella_enable_ms,
++	.break_ctl	= serial_ambarella_break_ctl,
++	.startup	= serial_ambarella_startup,
++	.shutdown	= serial_ambarella_shutdown,
++	.set_termios	= serial_ambarella_set_termios,
++	.pm		= serial_ambarella_pm,
++	.type		= serial_ambarella_type,
++	.release_port	= serial_ambarella_release_port,
++	.request_port	= serial_ambarella_request_port,
++	.config_port	= serial_ambarella_config_port,
++	.verify_port	= serial_ambarella_verify_port,
++#ifdef CONFIG_CONSOLE_POLL
++	.poll_put_char	= serial_ambarella_poll_put_char,
++	.poll_get_char	= serial_ambarella_poll_get_char,
++#endif
++};
++
++/* ==========================================================================*/
++#if defined(CONFIG_SERIAL_AMBARELLA_CONSOLE)
++
++static struct uart_driver serial_ambarella_reg;
++static void ambarella_uart_of_enumerate(void);
++
++static void serial_ambarella_console_putchar(struct uart_port *port, int ch)
++{
++	wait_for_tx(port);
++	amba_writel(port->membase + UART_TH_OFFSET, ch);
++}
++
++static void serial_ambarella_console_write(struct console *co,
++	const char *s, unsigned int count)
++{
++	struct uart_port *port;
++	int locked = 1;
++	unsigned long flags;
++
++	port = &ambarella_port[co->index].port;
++
++	if (!port->suspended) {
++		local_irq_save(flags);
++		if (port->sysrq) {
++			locked = 0;
++		} else if (oops_in_progress) {
++			locked = spin_trylock(&port->lock);
++		} else {
++			spin_lock(&port->lock);
++			locked = 1;
++		}
++
++		uart_console_write(port, s, count,
++			serial_ambarella_console_putchar);
++		wait_for_tx(port);
++
++		if (locked)
++			spin_unlock(&port->lock);
++		local_irq_restore(flags);
++	}
++}
++
++static int __init serial_ambarella_console_setup(struct console *co,
++	char *options)
++{
++	struct ambarella_uart_port *amb_port;
++	struct uart_port *port;
++	int baud = 115200, bits = 8, parity = 'n', flow = 'n';
++
++	if (co->index < 0 || co->index >= serial_ambarella_reg.nr)
++		co->index = 0;
++
++	amb_port = &ambarella_port[co->index];
++	amb_port->uart_pll = clk_get(NULL, "gclk_uart");
++
++	port = &ambarella_port[co->index].port;
++	if (!port->membase) {
++		pr_err("No device available for console\n");
++		return -ENODEV;
++	}
++
++	port->ops = &serial_ambarella_pops;
++	port->private_data = &ambarella_port[co->index];
++	port->line = co->index;
++
++	serial_ambarella_hw_setup(port);
++
++	if (options)
++		uart_parse_options(options, &baud, &parity, &bits, &flow);
++
++	return uart_set_options(port, co, baud, parity, bits, flow);
++}
++
++static struct console serial_ambarella_console = {
++	.name		= "ttyS",
++	.write		= serial_ambarella_console_write,
++	.device		= uart_console_device,
++	.setup		= serial_ambarella_console_setup,
++	.flags		= CON_PRINTBUFFER | CON_ANYTIME,
++	.index		= -1,
++	.data		= &serial_ambarella_reg,
++};
++
++#ifdef CONFIG_PM
++/* when no_console_suspend is specified in cmdline, Linux thought the console
++ * would never suspend. But actually we may put system into STR and power off
++ * the SoC, so the console must be initialized when system exit STR.
++ *
++ * NOTE: We MUST ensure that no information will be output via UART until
++ * syscore_resume() is completed, otherwise the UART may be in deadloop.
++ */
++static void serial_ambarella_console_resume(void)
++{
++	struct console *co = &serial_ambarella_console;
++	struct ambarella_uart_port *amb_port;
++	struct uart_port *port;
++	struct ktermios termios;
++
++	if (console_suspend_enabled)
++		return;
++
++	if (co->index < 0 || co->index >= serial_ambarella_reg.nr)
++		return;
++
++	amb_port = &ambarella_port[co->index];
++
++	port = &ambarella_port[co->index].port;
++	if (!port->membase)
++		return;
++
++	clear_bit(AMBARELLA_UART_RESET_FLAG, &amb_port->flags);
++	serial_ambarella_hw_setup(port);
++
++	memset(&termios, 0, sizeof(struct ktermios));
++	termios.c_cflag = amb_port->c_cflag;
++	port->ops->set_termios(port, &termios, NULL);
++}
++
++static struct syscore_ops ambarella_console_syscore_ops = {
++	.resume	 = serial_ambarella_console_resume,
++};
++#endif
++
++static int __init serial_ambarella_console_init(void)
++{
++	struct device_node *np;
++	const char *name;
++	int id;
++
++	ambarella_uart_of_enumerate();
++
++	name = of_get_property(of_chosen, "linux,stdout-path", NULL);
++	if (name == NULL)
++		return -ENODEV;
++
++	np = of_find_node_by_path(name);
++	if (!np)
++		return -ENODEV;
++
++	id = of_alias_get_id(np, "serial");
++	if (id < 0 || id >= serial_ambarella_reg.nr)
++		return -ENODEV;
++
++	ambarella_port[id].port.membase = of_iomap(np, 0);
++
++	register_console(&serial_ambarella_console);
++
++#ifdef CONFIG_PM
++	register_syscore_ops(&ambarella_console_syscore_ops);
++#endif
++
++	return 0;
++}
++
++console_initcall(serial_ambarella_console_init);
++
++#define AMBARELLA_CONSOLE	&serial_ambarella_console
++#else
++#define AMBARELLA_CONSOLE	NULL
++#endif
++
++/* ==========================================================================*/
++static struct uart_driver serial_ambarella_reg = {
++	.owner		= THIS_MODULE,
++	.driver_name	= "ambarella-uart",
++	.dev_name	= "ttyS",
++	.major		= TTY_MAJOR,
++	.minor		= 64,
++	.nr		= 0,
++	.cons		= AMBARELLA_CONSOLE,
++};
++
++static int serial_ambarella_probe(struct platform_device *pdev)
++{
++	struct ambarella_uart_port *amb_port;
++	struct resource *mem;
++	struct pinctrl *pinctrl;
++	int irq, id, rval = 0;
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!mem) {
++		dev_err(&pdev->dev, "no mem resource!\n");
++		return -ENODEV;
++	}
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "no irq resource!\n");
++		return -ENODEV;
++	}
++
++	id = of_alias_get_id(pdev->dev.of_node, "serial");
++	if (id < 0 || id >= serial_ambarella_reg.nr) {
++		dev_err(&pdev->dev, "Invalid uart ID %d!\n", id);
++		return -ENXIO;
++	}
++
++	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++	if (IS_ERR(pinctrl)) {
++		dev_err(&pdev->dev, "Failed to request pinctrl\n");
++		return PTR_ERR(pinctrl);
++	}
++
++	amb_port = &ambarella_port[id];
++
++	amb_port->uart_pll = clk_get(NULL, "gclk_uart");
++	if (IS_ERR(amb_port->uart_pll)) {
++		dev_err(&pdev->dev, "Get uart clk failed!\n");
++		return PTR_ERR(amb_port->uart_pll);
++	}
++
++	amb_port->mcr = DEFAULT_AMBARELLA_UART_MCR;
++	/* check if using modem status register,  available for non-uart0. */
++	if (of_find_property(pdev->dev.of_node, "amb,msr-used", NULL))
++		amb_port->msr_used = 1;
++	else
++		amb_port->msr_used = 0;
++	/* check if workaround for tx fifo is needed */
++	if (of_find_property(pdev->dev.of_node, "amb,tx-fifo-fix", NULL))
++		amb_port->tx_fifo_fix = 1;
++	else
++		amb_port->tx_fifo_fix = 0;
++	/* check if registers like FIFO status register are NOT provided. */
++	if (of_find_property(pdev->dev.of_node, "amb,less-reg", NULL))
++		amb_port->less_reg = 1;
++	else
++		amb_port->less_reg = 0;
++	/* check if using tx dma */
++	if (of_find_property(pdev->dev.of_node, "amb,txdma-used", NULL)) {
++		amb_port->txdma_used = 1;
++		dev_info(&pdev->dev,"Serial[%d] use txdma\n", id);
++	}
++	else
++		amb_port->txdma_used = 0;
++	/* check if using rx dma */
++	if (of_find_property(pdev->dev.of_node, "amb,rxdma-used", NULL)) {
++		amb_port->rxdma_used = 1;
++		dev_info(&pdev->dev,"Serial[%d] use rxdma\n", id);
++	} else {
++		amb_port->rxdma_used = 0;
++	}
++
++	amb_port->port.dev = &pdev->dev;
++	amb_port->port.type = PORT_UART00;
++	amb_port->port.iotype = UPIO_MEM;
++	amb_port->port.fifosize = UART_FIFO_SIZE;
++	amb_port->port.uartclk = clk_get_rate(amb_port->uart_pll);
++	amb_port->port.ops = &serial_ambarella_pops;
++	amb_port->port.private_data = amb_port;
++	amb_port->port.irq = irq;
++	amb_port->port.line = id;
++	amb_port->port.mapbase = mem->start;
++	amb_port->port.membase =
++		devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
++	if (!amb_port->port.membase) {
++		dev_err(&pdev->dev, "can't ioremap UART\n");
++		return -ENOMEM;
++	}
++
++	rval = uart_add_one_port(&serial_ambarella_reg, &amb_port->port);
++	if (rval < 0) {
++		dev_err(&pdev->dev, "failed to add port: %d, %d!\n", id, rval);
++	}
++
++	platform_set_drvdata(pdev, amb_port);
++
++	return rval;
++}
++
++static int serial_ambarella_remove(struct platform_device *pdev)
++{
++	struct ambarella_uart_port *amb_port;
++	int rval = 0;
++
++	amb_port = platform_get_drvdata(pdev);
++	rval = uart_remove_one_port(&serial_ambarella_reg, &amb_port->port);
++	if (rval < 0)
++		dev_err(&pdev->dev, "uart_remove_one_port fail %d!\n",	rval);
++
++	dev_notice(&pdev->dev,
++		"Remove Ambarella Media Processor UART.\n");
++
++	return rval;
++}
++
++#ifdef CONFIG_PM
++static int serial_ambarella_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	struct ambarella_uart_port *amb_port;
++	int rval = 0;
++
++	amb_port = platform_get_drvdata(pdev);
++	rval = uart_suspend_port(&serial_ambarella_reg, &amb_port->port);
++
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++		__func__, rval, state.event);
++
++	return rval;
++}
++
++static int serial_ambarella_resume(struct platform_device *pdev)
++{
++	struct ambarella_uart_port *amb_port;
++	int rval = 0;
++
++	amb_port = platform_get_drvdata(pdev);
++
++	clear_bit(AMBARELLA_UART_RESET_FLAG, &amb_port->flags);
++	serial_ambarella_hw_setup(&amb_port->port);
++
++	rval = uart_resume_port(&serial_ambarella_reg, &amb_port->port);
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, rval);
++
++	return rval;
++}
++#endif
++
++static const struct of_device_id ambarella_serial_of_match[] = {
++	{ .compatible = "ambarella,uart" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_serial_of_match);
++
++static void ambarella_uart_of_enumerate(void)
++{
++	struct device_node *np;
++	int nr = 0;
++
++	if (serial_ambarella_reg.nr <= 0) {
++		for_each_matching_node(np, ambarella_serial_of_match) {
++			nr++;
++		}
++
++		if (nr > UART_INSTANCES)
++			nr = UART_INSTANCES;
++
++		serial_ambarella_reg.nr = nr;
++	}
++}
++
++
++static struct platform_driver serial_ambarella_driver = {
++	.probe		= serial_ambarella_probe,
++	.remove		= serial_ambarella_remove,
++#ifdef CONFIG_PM
++	.suspend	= serial_ambarella_suspend,
++	.resume		= serial_ambarella_resume,
++#endif
++	.driver		= {
++		.name	= "ambarella-uart",
++		.of_match_table = ambarella_serial_of_match,
++	},
++};
++
++int __init serial_ambarella_init(void)
++{
++	int rval;
++
++	ambarella_uart_of_enumerate();
++
++	rval = uart_register_driver(&serial_ambarella_reg);
++	if (rval < 0)
++		return rval;
++
++	rval = platform_driver_register(&serial_ambarella_driver);
++	if (rval < 0)
++		uart_unregister_driver(&serial_ambarella_reg);
++
++	return rval;
++}
++
++void __exit serial_ambarella_exit(void)
++{
++	platform_driver_unregister(&serial_ambarella_driver);
++	uart_unregister_driver(&serial_ambarella_reg);
++}
++
++module_init(serial_ambarella_init);
++module_exit(serial_ambarella_exit);
++
++MODULE_AUTHOR("Anthony Ginger");
++MODULE_DESCRIPTION("Ambarella Media Processor UART driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:ambarella-uart");
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index 92e1dc94..3c62bf2c 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -96,7 +96,7 @@ config USB
+ 	  traditional PC serial port.  The bus supplies power to peripherals
+ 	  and allows for hot swapping.  Up to 127 USB peripherals can be
+ 	  connected to a single USB host in a tree structure.
+-	  
++
+ 	  The USB host is the root of the tree, the peripherals are the
+ 	  leaves and the inner nodes are special USB devices called hubs.
+ 	  Most PCs now have USB host ports, used to connect peripherals
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index f41aa0d0..1fdee11a 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -435,6 +435,18 @@ config USB_GOKU
+ 	   dynamically linked module called "goku_udc" and to force all
+ 	   gadget drivers to also be dynamically linked.
+ 
++#config USB_GADGET_AMBARELLA
++config USB_AMBARELLA
++	tristate "Ambarella USB Device Controller"
++	depends on PLAT_AMBARELLA
++	help
++	   Many AMBARLLA processors (such as the A2/A5S/iONE/S2...) have a
++	   full/high speed USB Device Controller.
++
++	   Say "y" to link the driver statically, or "m" to build a
++	   dynamically linked module called "ambarella_udc" and force all
++	   gadget drivers to also be dynamically linked.
++
+ config USB_EG20T
+ 	tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"
+ 	depends on PCI && GENERIC_HARDIRQS
+@@ -818,6 +830,20 @@ config USB_G_PRINTER
+ 	  For more information, see Documentation/usb/gadget_printer.txt
+ 	  which includes sample code for accessing the device file.
+ 
++config USB_AMB_STREAM
++	tristate "Gadget Ambarella Data Streaming"
++	depends on USB_AMBARELLA
++	select USB_LIBCOMPOSITE
++	help
++	  Gadget Ambarella Data Streaming is a single-configuration
++	  single-interface device.
++	  The driver needs two bulk-capable endpoints, and one interrupt-capable
++	  endpoint is optional. It may need special protocol that can be
++	  designed at top layer to transfer data with host.
++
++	  Say "y" to link the driver statically, or "m" to build a
++	  dynamically linked module called "g_amb_stream".
++
+ if TTY
+ 
+ config USB_CDC_COMPOSITE
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 6afd1665..fff150cd 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
+ obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
+ obj-$(CONFIG_USB_S3C_HSUDC)	+= s3c-hsudc.o
+ obj-$(CONFIG_USB_LPC32XX)	+= lpc32xx_udc.o
++obj-$(CONFIG_USB_AMBARELLA)	+= ambarella_udc.o
+ obj-$(CONFIG_USB_EG20T)		+= pch_udc.o
+ obj-$(CONFIG_USB_MV_UDC)	+= mv_udc.o
+ mv_udc-y			:= mv_udc_core.o
+@@ -58,6 +59,7 @@ gadgetfs-y			:= inode.o
+ g_mass_storage-y		:= mass_storage.o
+ g_printer-y			:= printer.o
+ g_cdc-y				:= cdc2.o
++g_amb_stream-y			:= amb_stream.o
+ g_multi-y			:= multi.o
+ g_hid-y				:= hid.o
+ g_dbgp-y			:= dbgp.o
+@@ -77,6 +79,7 @@ obj-$(CONFIG_USB_G_SERIAL)	+= g_serial.o
+ obj-$(CONFIG_USB_G_PRINTER)	+= g_printer.o
+ obj-$(CONFIG_USB_MIDI_GADGET)	+= g_midi.o
+ obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
++obj-$(CONFIG_USB_AMB_STREAM)	+= g_amb_stream.o
+ obj-$(CONFIG_USB_G_HID)		+= g_hid.o
+ obj-$(CONFIG_USB_G_DBGP)	+= g_dbgp.o
+ obj-$(CONFIG_USB_G_MULTI)	+= g_multi.o
+diff --git a/drivers/usb/gadget/amb_stream.c b/drivers/usb/gadget/amb_stream.c
+new file mode 100644
+index 00000000..ae69b4f7
+--- /dev/null
++++ b/drivers/usb/gadget/amb_stream.c
+@@ -0,0 +1,1344 @@
++/*
++* amb_stream.c -- Ambarella Data Streaming Gadget
++*
++* History:
++*	2009/01/01 - [Cao Rongrong] created file
++*
++* Copyright (C) 2008 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or
++* (at your option) any later version.
++*/
++
++
++/*
++ * Ambarella Data Streaming Gadget only needs two bulk endpoints, and it
++ * supports single configurations.
++ *
++ * Module options include:
++ *   buflen=N	default N=4096, buffer size used
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++
++#include <linux/usb/composite.h>
++#include <linux/device.h>
++#include <linux/cdev.h>
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <asm/uaccess.h>
++
++#include "gadget_chips.h"
++
++#include <mach/hardware.h>
++
++USB_GADGET_COMPOSITE_OPTIONS();
++
++#define DRIVER_VERSION		"15 July 2016"
++
++static const char shortname[] = "g_amb_stream";
++static const char longname[] = "Ambarella Data Streaming Gadget";
++
++/* ==========================================================================*/
++#define	AMBA_DEV_MAJOR			(248)
++#define	AMBA_DEV_MINOR_PUBLIC_START	(128)
++#define	AMBA_DEV_MINOR_PUBLIC_END	(240)
++/*-------------------------------------------------------------------------*/
++#ifdef DEBUG
++#define AMB_DBG(dev,fmt,args...) \
++	dev_printk(KERN_DEBUG , &(dev)->gadget->dev , fmt , ## args)
++#else
++#define AMB_DBG(dev,fmt,args...) \
++	do { } while (0)
++#endif /* DEBUG */
++
++#define AMB_ERROR(dev,fmt,args...) \
++	dev_printk(KERN_ERR , &(dev)->gadget->dev , fmt , ## args)
++
++#define AMB_INFO(dev,fmt,args...) \
++	dev_printk(KERN_INFO , &(dev)->gadget->dev , fmt , ## args)
++/*-------------------------------------------------------------------------*/
++#define AMB_GADGET_MAJOR			AMBA_DEV_MAJOR
++#define AMB_GADGET_MINOR_START		(AMBA_DEV_MINOR_PUBLIC_START + 0)
++/*-------------------------------------------------------------------------*/
++static struct cdev ag_cdev;
++
++/* big enough to hold our biggest descriptor */
++#define USB_BUFSIZ	256
++/*-------------------------------------------------------------------------*/
++#define AG_NOTIFY_INTERVAL		5	/* 1 << 5 == 32 msec */
++#define AG_NOTIFY_MAXPACKET		8
++
++#define SIMPLE_CMD_SIZE		32
++struct amb_cmd {
++	u32 signature;
++	u32 command;
++	u32 parameter[(SIMPLE_CMD_SIZE / sizeof(u32)) - 2];
++};
++
++struct amb_rsp {
++	u32 signature;
++	u32 response;
++	u32 parameter0;
++	u32 parameter1;
++};
++
++struct amb_ack {
++	u32 signature;
++	u32 acknowledge;
++	u32 parameter0;
++	u32 parameter1;
++};
++
++/* for bNotifyType */
++#define PORT_STATUS_CHANGE		0x55
++#define PORT_NOTIFY_IDLE		0xff
++/* for value */
++#define PORT_FREE_ALL			2
++#define PORT_CONNECT			1
++#define PORT_NO_CONNECT		0
++/* for status */
++#define DEVICE_OPENED			1
++#define DEVICE_NOT_OPEN		0
++
++struct amb_notify {
++	u16	bNotifyType;
++	u16	port_id;
++	u16	value;
++	u16	status;
++};
++
++struct amb_notify g_port = {
++	.bNotifyType = PORT_NOTIFY_IDLE,
++	.port_id = 0xffff,
++	.value = 0,
++};
++
++/*-------------------------------------------------------------------------*/
++#define AMB_DATA_STREAM_MAGIC	'u'
++#define AMB_DATA_STREAM_WR_RSP	_IOW(AMB_DATA_STREAM_MAGIC, 1, struct amb_rsp *)
++#define AMB_DATA_STREAM_RD_CMD	_IOR(AMB_DATA_STREAM_MAGIC, 1, struct amb_cmd *)
++#define AMB_DATA_STREAM_STATUS_CHANGE	_IOW(AMB_DATA_STREAM_MAGIC, 2, struct amb_notify *)
++/*-------------------------------------------------------------------------*/
++struct amb_dev {
++	spinlock_t		lock;
++	wait_queue_head_t	wq;
++	struct mutex		mtx;
++
++	int 				config;
++	struct usb_gadget	*gadget;
++	struct usb_request	*notify_req;
++
++	struct usb_ep		*in_ep;
++	struct usb_ep		*out_ep;
++	struct usb_ep		*notify_ep;
++
++	struct list_head		in_idle_list;	/* list of idle write requests */
++	struct list_head		in_queue_list;	/* list of queueing write requests */
++	struct list_head		out_req_list;	/* list of bulk out requests */
++
++	struct usb_function		func;
++
++	int			open_count;
++	int			error;
++	char		interface;
++};
++
++struct amb_dev *ag_device;
++static dev_t ag_dev_id;
++static struct class *ag_class;
++/*-------------------------------------------------------------------------*/
++static void notify_worker(struct work_struct *work);
++static DECLARE_WORK(notify_work, notify_worker);
++/*-------------------------------------------------------------------------*/
++static unsigned int buflen = (48*1024);
++module_param (buflen, uint, S_IRUGO);
++MODULE_PARM_DESC(buflen, "buffer length, default=48K");
++
++static unsigned int qdepth = 5;
++module_param (qdepth, uint, S_IRUGO);
++MODULE_PARM_DESC(qdepth, "bulk transfer queue depth, default=5");
++/*-------------------------------------------------------------------------*/
++/*
++ * DESCRIPTORS ... most are static, but strings and (full)
++ * configuration descriptors are built on demand.
++ */
++
++#define STRING_SOURCE_SINK		USB_GADGET_FIRST_AVAIL_IDX
++
++#define DRIVER_VENDOR_ID	0x4255		/* Ambarella */
++#define DRIVER_PRODUCT_ID	0x0001
++
++#define DEV_CONFIG_VALUE		1
++
++static struct usb_device_descriptor ag_device_desc = {
++	.bLength =		sizeof ag_device_desc,
++	.bDescriptorType =	USB_DT_DEVICE,
++
++	.bcdUSB =		cpu_to_le16 (0x0200),
++	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
++
++	.idVendor =		cpu_to_le16 (DRIVER_VENDOR_ID),
++	.idProduct =		cpu_to_le16 (DRIVER_PRODUCT_ID),
++	.bNumConfigurations =	1,
++};
++
++static struct usb_config_descriptor amb_bulk_config = {
++	.bLength =		sizeof amb_bulk_config,
++	.bDescriptorType =	USB_DT_CONFIG,
++
++	.bNumInterfaces =	1,
++	.bConfigurationValue =	DEV_CONFIG_VALUE,
++	.iConfiguration =	STRING_SOURCE_SINK,
++	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
++};
++
++/* one interface in each configuration */
++static struct usb_interface_descriptor amb_data_stream_intf = {
++	.bLength =		sizeof amb_data_stream_intf,
++	.bDescriptorType =	USB_DT_INTERFACE,
++
++	.bNumEndpoints =	3,
++	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
++	.iInterface =		STRING_SOURCE_SINK,
++};
++
++/* two full speed bulk endpoints; their use is config-dependent */
++
++static struct usb_endpoint_descriptor fs_bulk_in_desc = {
++	.bLength =		USB_DT_ENDPOINT_SIZE,
++	.bDescriptorType =	USB_DT_ENDPOINT,
++
++	.bEndpointAddress =	USB_DIR_IN,
++	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
++};
++
++static struct usb_endpoint_descriptor fs_bulk_out_desc = {
++	.bLength =		USB_DT_ENDPOINT_SIZE,
++	.bDescriptorType =	USB_DT_ENDPOINT,
++
++	.bEndpointAddress =	USB_DIR_OUT,
++	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
++};
++
++static struct usb_endpoint_descriptor fs_intr_in_desc = {
++	.bLength =		USB_DT_ENDPOINT_SIZE,
++	.bDescriptorType =	USB_DT_ENDPOINT,
++	.bEndpointAddress =	USB_DIR_IN,
++	.bmAttributes =		USB_ENDPOINT_XFER_INT,
++	.wMaxPacketSize =	cpu_to_le16(AG_NOTIFY_MAXPACKET),
++	.bInterval =		1 << AG_NOTIFY_INTERVAL,
++};
++
++static struct usb_descriptor_header *fs_amb_data_stream_function[] = {
++	(struct usb_descriptor_header *) &amb_data_stream_intf,
++	(struct usb_descriptor_header *) &fs_bulk_out_desc,
++	(struct usb_descriptor_header *) &fs_bulk_in_desc,
++	(struct usb_descriptor_header *) &fs_intr_in_desc,
++	NULL,
++};
++
++static struct usb_endpoint_descriptor hs_bulk_in_desc = {
++	.bLength =		USB_DT_ENDPOINT_SIZE,
++	.bDescriptorType =	USB_DT_ENDPOINT,
++
++	/* bEndpointAddress will be copied from fs_bulk_in_desc during amb_bind() */
++	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
++	.wMaxPacketSize =	cpu_to_le16 (512),
++};
++
++static struct usb_endpoint_descriptor hs_bulk_out_desc = {
++	.bLength =		USB_DT_ENDPOINT_SIZE,
++	.bDescriptorType =	USB_DT_ENDPOINT,
++
++	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
++	.wMaxPacketSize =	cpu_to_le16 (512),
++};
++
++static struct usb_endpoint_descriptor hs_intr_in_desc = {
++	.bLength =		USB_DT_ENDPOINT_SIZE,
++	.bDescriptorType =	USB_DT_ENDPOINT,
++	.bEndpointAddress =	USB_DIR_IN,
++	.bmAttributes =		USB_ENDPOINT_XFER_INT,
++	.wMaxPacketSize =	cpu_to_le16(AG_NOTIFY_MAXPACKET),
++	.bInterval =		AG_NOTIFY_INTERVAL + 4,
++};
++
++static struct usb_qualifier_descriptor dev_qualifier = {
++	.bLength =		sizeof dev_qualifier,
++	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
++
++	.bcdUSB =		cpu_to_le16 (0x0200),
++	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
++
++	.bNumConfigurations =	1,
++};
++
++static struct usb_descriptor_header *hs_amb_data_stream_function[] = {
++	(struct usb_descriptor_header *) &amb_data_stream_intf,
++	(struct usb_descriptor_header *) &hs_bulk_in_desc,
++	(struct usb_descriptor_header *) &hs_bulk_out_desc,
++	(struct usb_descriptor_header *) &hs_intr_in_desc,
++	NULL,
++};
++
++static struct usb_otg_descriptor otg_descriptor = {
++	.bLength =		sizeof otg_descriptor,
++	.bDescriptorType =	USB_DT_OTG,
++	.bmAttributes =		USB_OTG_SRP,
++};
++
++static const struct usb_descriptor_header *otg_desc[] = {
++	(struct usb_descriptor_header *) &otg_descriptor,
++	NULL,
++};
++/*-------------------------------------------------------------------------*/
++static char serial[40] = "123456789ABC";
++
++/* static strings, in UTF-8 */
++static struct usb_string		strings[] = {
++	[USB_GADGET_MANUFACTURER_IDX].s = "",
++	[USB_GADGET_PRODUCT_IDX].s = longname,
++	[USB_GADGET_SERIAL_IDX].s = serial,
++	[STRING_SOURCE_SINK].s = "bulk in and out data",
++	{  }			/* end of list */
++};
++
++static struct usb_gadget_strings	stringtab_dev = {
++	.language	= 0x0409,	/* en-us */
++	.strings	= strings,
++};
++
++static struct usb_gadget_strings	*dev_strings[] = {
++	&stringtab_dev,
++	NULL,
++};
++
++/*-------------------------------------------------------------------------*/
++/* add a request to the tail of a list */
++void req_put(struct amb_dev *dev,
++		struct list_head *head, struct usb_request *req)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	list_add_tail(&req->list, head);
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++/* get a request and remove it from the head of a list */
++struct usb_request *req_get(struct amb_dev *dev, struct list_head *head)
++{
++	struct usb_request *req;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	if (list_empty(head)) {
++		req = NULL;
++	} else {
++		req = list_first_entry(head, struct usb_request, list);
++		list_del(&req->list);
++	}
++	spin_unlock_irqrestore(&dev->lock, flags);
++	return req;
++}
++
++/* get a request and move it from the head of "from" list
++  * to the head of "to" list
++  */
++struct usb_request *req_move(struct amb_dev *dev,
++		struct list_head *from, struct list_head *to)
++{
++	struct usb_request *req;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	if (list_empty(from)) {
++		req = NULL;
++	} else {
++		req = list_first_entry(from, struct usb_request, list);
++		list_move_tail(&req->list, to);
++	}
++	spin_unlock_irqrestore(&dev->lock, flags);
++	return req;
++}
++
++static int amb_send(u8 *buf, u32 len)
++{
++	struct amb_dev *dev = ag_device;
++	struct usb_request *req = NULL;
++	int rval = 0;
++
++	if (buf == NULL || len > buflen)
++		return -EFAULT;
++
++	if(wait_event_interruptible(dev->wq,
++		(req = req_move(dev, &dev->in_idle_list, &dev->in_queue_list))
++		|| dev->error)){
++		rval = -EINTR;
++		goto exit;
++	}
++
++	if(dev->error) {
++		AMB_ERROR(dev, "%s: device error", __func__);
++		spin_lock_irq(&dev->lock);
++		if (req)
++			list_move_tail(&req->list, &dev->in_idle_list);
++		spin_unlock_irq(&dev->lock);
++		rval = -EIO;
++		goto exit;
++	}
++
++	memcpy(req->buf, buf, len);
++
++	req->length = len;
++	rval = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
++	if (rval != 0) {
++		AMB_ERROR(dev, "%s: cannot queue bulk in request, "
++			"rval=%d\n", __func__, rval);
++		spin_lock_irq(&dev->lock);
++		list_move_tail(&req->list, &dev->in_idle_list);
++		spin_unlock_irq(&dev->lock);
++		goto exit;
++	}
++
++exit:
++	return rval;
++}
++
++static int amb_recv(u8 *buf, u32 len)
++{
++	struct amb_dev *dev = ag_device;
++	struct usb_request *req = NULL;
++	int rval = 0;
++
++	if (buf == NULL || len > buflen)
++		return -EFAULT;
++
++	if(wait_event_interruptible(dev->wq,
++		(req = req_get(dev, &dev->out_req_list)) || dev->error)){
++		return -EINTR;
++	}
++
++	if (req) {
++		memcpy(buf, req->buf, req->actual);
++
++		req->length = buflen;
++		if ((rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC))) {
++			AMB_ERROR(dev, "%s: can't queue bulk out request, "
++				"rval = %d\n", __func__, rval);
++		}
++	}
++
++	if(dev->error) {
++		AMB_ERROR(dev, "%s: device error", __func__);
++		rval = -EIO;
++	}
++
++	return rval;
++}
++
++
++/*-------------------------------------------------------------------------*/
++static long ag_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++{
++	int rval = 0;
++	struct amb_dev *dev = ag_device;
++	struct amb_cmd _cmd;
++	struct amb_rsp rsp;
++	struct amb_notify notify;
++
++	AMB_DBG(dev, "%s: Enter\n", __func__);
++
++	mutex_lock(&dev->mtx);
++
++	switch (cmd) {
++	case AMB_DATA_STREAM_WR_RSP:
++
++		if(copy_from_user(&rsp, (struct amb_rsp __user *)arg, sizeof(rsp))){
++			mutex_unlock(&dev->mtx);
++			return -EFAULT;
++		}
++
++		rval = amb_send((u8 *)&rsp, sizeof(rsp));
++		break;
++
++	case AMB_DATA_STREAM_RD_CMD:
++
++		rval = amb_recv((u8 *)&_cmd, sizeof(_cmd));
++		if(rval < 0)
++			break;
++
++		if(copy_to_user((struct amb_cmd __user *)arg, &_cmd, sizeof(_cmd))){
++			mutex_unlock(&dev->mtx);
++			return -EFAULT;
++		}
++
++		break;
++
++	case AMB_DATA_STREAM_STATUS_CHANGE:
++		if(copy_from_user(&notify, (struct amb_notify __user *)arg, sizeof(notify))){
++			mutex_unlock(&dev->mtx);
++			return -EFAULT;
++		}
++
++		spin_lock_irq(&dev->lock);
++		g_port.bNotifyType = notify.bNotifyType;
++		g_port.port_id = notify.port_id;
++		g_port.value = notify.value;
++		spin_unlock_irq(&dev->lock);
++		break;
++
++	default:
++		rval = -ENOIOCTLCMD;
++		break;
++	}
++
++	mutex_unlock(&dev->mtx);
++
++	AMB_DBG(dev, "%s: Exit\n", __func__);
++
++	return rval;
++}
++static int ag_open(struct inode *inode, struct file *filp)
++{
++	struct amb_dev *dev = ag_device;
++	struct usb_request *req = NULL;
++	int rval = 0;
++
++	mutex_lock(&dev->mtx);
++
++	/* gadget have not been configured */
++	if(dev->config == 0){
++		rval = -ENOTCONN;
++		goto exit;
++	}
++
++	if(dev->open_count > 0){
++		rval = -EBUSY;
++		goto exit;
++	}
++
++	dev->open_count++;
++	dev->error = 0;
++
++	/* throw away the data received on last connection */
++	while ((req = req_get(dev, &dev->out_req_list))) {
++		/* re-use the req again */
++		req->length = buflen;
++		if ((rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC))) {
++			AMB_ERROR(dev, "%s: can't queue bulk out request, "
++				"rval = %d\n", __func__, rval);
++			break;
++		}
++	}
++exit:
++	mutex_unlock(&dev->mtx);
++	return rval;
++}
++
++static int ag_release(struct inode *inode, struct file *filp)
++{
++	struct amb_dev *dev = ag_device;
++	struct usb_request *req;
++	int rval = 0;
++
++	mutex_lock(&dev->mtx);
++
++	/* dequeue the bulk-in request */
++	while ((req = req_move(dev, &dev->in_queue_list, &dev->in_idle_list))) {
++		rval = usb_ep_dequeue(dev->in_ep, req);
++		if (rval != 0) {
++			AMB_ERROR(dev, "%s: cannot dequeue bulk in request, "
++				"rval=%d\n", __func__, rval);
++			break;
++		}
++	}
++
++	dev->open_count--;
++
++	spin_lock_irq(&dev->lock);
++	g_port.bNotifyType = PORT_STATUS_CHANGE;
++	g_port.port_id = 0xffff;
++	g_port.value = PORT_FREE_ALL;
++	g_port.status = DEVICE_NOT_OPEN;
++	spin_unlock_irq(&dev->lock);
++
++	mutex_unlock(&dev->mtx);
++
++	return rval;
++}
++
++static int ag_read(struct file *file, char __user *buf,
++	size_t count, loff_t *ppos)
++{
++	struct amb_dev *dev = ag_device;
++	struct usb_request *req = NULL;
++	int len = 0, rval = 0;
++
++	mutex_lock(&dev->mtx);
++
++	while(count > 0){
++		if(wait_event_interruptible(dev->wq,
++			(req = req_get(dev, &dev->out_req_list)) || dev->error)){
++			mutex_unlock(&dev->mtx);
++			return -EINTR;
++		}
++
++		if(dev->error){
++			AMB_ERROR(dev, "%s: device error", __func__);
++			if (req) {
++				req->length = buflen;
++				rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
++				if (rval)
++					AMB_ERROR(dev, "%s: "
++						"can't queue bulk out request, "
++						"rval = %d\n", __func__, rval);
++			}
++			mutex_unlock(&dev->mtx);
++			return -EIO;
++		}
++
++		if(copy_to_user(buf + len, req->buf, req->actual)){
++			pr_err("len = %d, actual = %d\n", len, req->actual);
++			mutex_unlock(&dev->mtx);
++			return -EFAULT;
++		}
++		len += req->actual;
++		count -= req->actual;
++
++		req->length = buflen;
++		if ((rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC))) {
++			AMB_ERROR(dev, "%s: can't queue bulk out request, "
++				"rval = %d\n", __func__, rval);
++			len = rval;
++			break;
++		}
++
++		if (len % buflen != 0)
++			break;
++	}
++
++	mutex_unlock(&dev->mtx);
++
++	return len;
++}
++
++static int ag_write(struct file *file, const char __user *buf,
++	size_t count, loff_t *ppos)
++{
++	int rval, size, len = 0;
++	struct amb_dev *dev = ag_device;
++	struct usb_request *req = NULL;
++
++	mutex_lock(&dev->mtx);
++
++	while(count > 0) {
++		if(wait_event_interruptible(dev->wq,
++			(req = req_move(dev, &dev->in_idle_list, &dev->in_queue_list))
++			|| dev->error)){
++			mutex_unlock(&dev->mtx);
++			return -EINTR;
++		}
++
++		if(dev->error){
++			AMB_ERROR(dev, "%s: device error", __func__);
++			spin_lock_irq(&dev->lock);
++			if (req)
++				list_move_tail(&req->list, &dev->in_idle_list);
++			spin_unlock_irq(&dev->lock);
++			mutex_unlock(&dev->mtx);
++			return -EIO;
++		}
++
++		size = count < buflen ? count : buflen;
++		if(copy_from_user(req->buf, buf + len, size)){
++			mutex_unlock(&dev->mtx);
++			return -EFAULT;
++		}
++
++		req->length = size;
++		if ((count - size == 0) && (size % dev->in_ep->maxpacket == 0))
++			req->zero = 1;
++
++		rval = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
++		if (rval != 0) {
++			AMB_ERROR(dev, "%s: cannot queue bulk in request, "
++				"rval=%d\n", __func__, rval);
++			list_move_tail(&req->list, &dev->in_idle_list);
++			mutex_unlock(&dev->mtx);
++			return rval;
++		}
++
++		count -= size;
++		len += size;
++	}
++
++	mutex_unlock(&dev->mtx);
++
++	AMB_DBG(dev, "%s: Exit\n", __func__);
++
++	return len;
++}
++
++static const struct file_operations ag_fops = {
++	.owner = THIS_MODULE,
++	.unlocked_ioctl = ag_ioctl,
++	.open = ag_open,
++	.read = ag_read,
++	.write = ag_write,
++	.release = ag_release
++};
++
++static void amb_notify_complete (struct usb_ep *ep, struct usb_request *req);
++
++static void notify_worker(struct work_struct *work)
++{
++	struct amb_dev		*dev = ag_device;
++	struct usb_request	*req = NULL;
++	struct amb_notify	*event = NULL;
++	unsigned long flags;
++	int rval = 0;
++
++	if (dev && (req = dev->notify_req)) {
++		event = req->buf;
++		spin_lock_irqsave(&dev->lock, flags);
++		memcpy(event, &g_port, sizeof(struct amb_notify));
++		g_port.bNotifyType = PORT_NOTIFY_IDLE;
++		g_port.port_id = 0xffff;
++		g_port.value = 0;
++		if(dev->open_count > 0)
++			g_port.status = DEVICE_OPENED;
++		else
++			g_port.status = DEVICE_NOT_OPEN;
++
++		req->length = AG_NOTIFY_MAXPACKET;
++		req->complete = amb_notify_complete;
++		req->context = dev;
++		req->zero = !(req->length % dev->notify_ep->maxpacket);
++		spin_unlock_irqrestore(&dev->lock, flags);
++
++		rval = usb_ep_queue(dev->notify_ep, req, GFP_ATOMIC);
++		if (rval < 0)
++			AMB_DBG(dev, "status buf queue --> %d\n", rval);
++	}
++}
++
++static struct usb_request *amb_alloc_buf_req (struct usb_ep *ep,
++		unsigned length, gfp_t kmalloc_flags)
++{
++	struct usb_request	*req;
++
++	req = usb_ep_alloc_request(ep, kmalloc_flags);
++	if (req) {
++		req->length = length;
++		req->buf = kmalloc(length, kmalloc_flags);
++		if (!req->buf) {
++			usb_ep_free_request(ep, req);
++			req = NULL;
++		}
++	}
++	return req;
++}
++
++static void amb_free_buf_req (struct usb_ep *ep, struct usb_request *req)
++{
++	if(req){
++		if (req->buf){
++			kfree(req->buf);
++			req->buf = NULL;
++		}
++		usb_ep_free_request(ep, req);
++	}
++}
++
++static void amb_bulk_in_complete (struct usb_ep *ep, struct usb_request *req)
++{
++	struct amb_dev	*dev = ep->driver_data;
++	int		status = req->status;
++	unsigned long	flags;
++	int 		rval = 0;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	switch (status) {
++	case 0: 			/* normal completion? */
++		dev->error = 0;
++		list_move_tail(&req->list, &dev->in_idle_list);
++		break;
++	/* this endpoint is normally active while we're configured */
++	case -ECONNRESET:		/* request dequeued */
++		dev->error = 1;
++		usb_ep_fifo_flush(ep);
++		break;
++	case -ESHUTDOWN:		/* disconnect from host */
++		dev->error = 1;
++		amb_free_buf_req(ep, req);
++		break;
++	default:
++		AMB_ERROR(dev, "%s complete --> %d, %d/%d\n", ep->name,
++				status, req->actual, req->length);
++		dev->error = 1;
++		/* queue request again */
++		rval = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
++		if (rval != 0) {
++			AMB_ERROR(dev, "%s: cannot queue bulk in request, "
++				"rval=%d\n", __func__, rval);
++		}
++		break;
++	}
++	wake_up_interruptible(&dev->wq);
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++static void amb_bulk_out_complete (struct usb_ep *ep, struct usb_request *req)
++{
++	struct amb_dev	*dev = ep->driver_data;
++	int		status = req->status;
++	unsigned long	flags;
++	int 		rval = 0;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	switch (status) {
++	case 0: 			/* normal completion */
++		dev->error = 0;
++		list_add_tail(&req->list, &dev->out_req_list);
++		break;
++	/* this endpoint is normally active while we're configured */
++	case -ECONNRESET:		/* request dequeued */
++		dev->error = 1;
++		usb_ep_fifo_flush(ep);
++		break;
++	case -ESHUTDOWN:		/* disconnect from host */
++		dev->error = 1;
++		amb_free_buf_req(ep, req);
++		break;
++	default:
++		AMB_ERROR(dev, "%s complete --> %d, %d/%d\n", ep->name,
++				status, req->actual, req->length);
++		dev->error = 1;
++		/* queue request again */
++		rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
++		if (rval != 0) {
++			AMB_ERROR(dev, "%s: cannot queue bulk in request, "
++				"rval=%d\n", __func__, rval);
++		}
++		break;
++	}
++	wake_up_interruptible(&dev->wq);
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++static void amb_notify_complete (struct usb_ep *ep, struct usb_request *req)
++{
++	struct amb_dev	*dev = ep->driver_data;
++	int				status = req->status;
++	unsigned long	flags;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	req->context = NULL;
++
++	switch (status) {
++	case 0: 			/* normal completion */
++		/* issue the second notification if host reads the previous one */
++		schedule_work(&notify_work);
++		break;
++
++	/* this endpoint is normally active while we're configured */
++	case -ECONNRESET:		/* request dequeued */
++		usb_ep_fifo_flush(ep);
++		break;
++	case -ESHUTDOWN:		/* disconnect from host */
++		amb_free_buf_req(ep, req);
++		break;
++	default:
++		AMB_ERROR(dev, "%s complete --> %d, %d/%d\n", ep->name,
++				status, req->actual, req->length);
++		break;
++	}
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++static void amb_start_notify (struct amb_dev *dev)
++{
++	struct usb_request *req = dev->notify_req;
++	struct amb_notify *event;
++	int value;
++
++	/* flush old status
++	 * FIXME iff req->context != null just dequeue it
++	 */
++	//usb_ep_disable(dev->notify_ep);
++	//usb_ep_enable(dev->notify_ep);
++
++	event = req->buf;
++	event->bNotifyType = cpu_to_le16(PORT_NOTIFY_IDLE);
++	event->port_id = cpu_to_le16 (0);
++	event->value = cpu_to_le32 (0);
++	event->status = DEVICE_NOT_OPEN;
++
++	req->length = AG_NOTIFY_MAXPACKET;
++	req->complete = amb_notify_complete;
++	req->context = dev;
++	req->zero = !(req->length % dev->notify_ep->maxpacket);
++
++	value = usb_ep_queue(dev->notify_ep, req, GFP_ATOMIC);
++	if (value < 0)
++		AMB_DBG (dev, "status buf queue --> %d\n", value);
++}
++/*-------------------------------------------------------------------------*/
++static void amb_cfg_unbind(struct usb_configuration *c)
++{
++	device_destroy(ag_class, ag_dev_id);
++}
++
++static struct usb_configuration amb_config_driver = {
++	.label			= "AMB Stream Gadget",
++	.unbind			= amb_cfg_unbind,
++	.bConfigurationValue	= 1,
++	//.iConfiguration	=	STRING_SOURCE_SINK,
++	.bmAttributes	= USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
++	.MaxPower		= 1,
++};
++
++static int amb_set_stream_config(struct amb_dev *dev)
++{
++	int		result = 0, i;
++	struct usb_gadget	*gadget = dev->gadget;
++	struct usb_ep *ep;
++	struct usb_request *req;
++
++	/* one endpoint writes data in (to the host) */
++	result = config_ep_by_speed(gadget, &(dev->func), dev->in_ep);
++	if (result)
++		goto exit;
++	result = usb_ep_enable(dev->in_ep);
++	if (result != 0) {
++		AMB_ERROR(dev, "%s: can't enable %s, result=%d\n",
++			__func__, dev->in_ep->name, result);
++		goto exit;
++	}
++
++	/* one endpoint reads data out (from the host) */
++	result = config_ep_by_speed(gadget, &(dev->func), dev->out_ep);
++	if (result)
++		goto exit;
++	result = usb_ep_enable(dev->out_ep);
++	if (result != 0) {
++		AMB_ERROR(dev, "%s: can't enable %s, result=%d\n",
++			__func__, dev->out_ep->name, result);
++		usb_ep_disable(dev->in_ep);
++		goto exit;
++	}
++
++	/* one endpoint report status  (to the host) */
++	result = config_ep_by_speed(gadget, &(dev->func), dev->notify_ep);
++	if (result)
++		goto exit;
++	result = usb_ep_enable(dev->notify_ep);
++	if (result != 0) {
++		AMB_ERROR(dev, "%s: can't enable %s, result=%d\n",
++			__func__, dev->notify_ep->name, result);
++		usb_ep_disable(dev->out_ep);
++		usb_ep_disable(dev->in_ep);
++		dev->out_ep->desc = NULL;
++		dev->in_ep->desc = NULL;
++		goto exit;
++	}
++
++	/* allocate and queue read requests */
++	ep = dev->out_ep;
++	ep->driver_data = dev;
++	for (i = 0; i < qdepth && result == 0; i++) {
++		req = amb_alloc_buf_req(ep, buflen, GFP_ATOMIC);
++		if (req) {
++			req->complete = amb_bulk_out_complete;
++			result = usb_ep_queue(ep, req, GFP_ATOMIC);
++			if (result < 0) {
++				AMB_ERROR(dev, "%s: can't queue bulk out request, "
++					"rval = %d\n", __func__, result);
++			}
++		} else {
++			AMB_ERROR(dev, "%s: can't allocate bulk in requests\n", __func__);
++			result = -ENOMEM;
++			goto exit;
++		}
++	}
++
++	/* allocate write requests, and put on free list */
++	ep = dev->in_ep;
++	ep->driver_data = dev;
++	for (i = 0; i < qdepth; i++) {
++		req = amb_alloc_buf_req(ep, buflen, GFP_ATOMIC);
++		if (req) {
++			req->complete = amb_bulk_in_complete;
++			req_put(dev, &dev->in_idle_list, req);
++		} else {
++			AMB_ERROR(dev, "%s: can't allocate bulk in requests\n", __func__);
++			result = -ENOMEM;
++			goto exit;
++		}
++	}
++
++	ep = dev->notify_ep;
++	ep->driver_data = dev;
++	if (dev->notify_ep) {
++		dev->notify_req = amb_alloc_buf_req(ep,
++						AG_NOTIFY_MAXPACKET,GFP_ATOMIC);
++		amb_start_notify(dev);
++	}
++
++exit:
++	/* caller is responsible for cleanup on error */
++	return result;
++}
++
++static void amb_reset_config (struct amb_dev *dev)
++{
++	struct usb_request *req;
++	unsigned long flags;
++
++	if (dev->config == 0)
++		return;
++	dev->config = 0;
++
++	spin_lock_irqsave(&dev->lock, flags);
++
++	/* free write requests on the free list */
++	while(!list_empty(&dev->in_idle_list)) {
++		req = list_entry(dev->in_idle_list.next,
++				struct usb_request, list);
++		list_del_init(&req->list);
++		req->length = buflen;
++		amb_free_buf_req(dev->in_ep, req);
++	}
++	while(!list_empty(&dev->in_queue_list)) {
++		req = list_entry(dev->in_queue_list.prev,
++				struct usb_request, list);
++		list_del_init(&req->list);
++		req->length = buflen;
++		amb_free_buf_req(dev->in_ep, req);
++	}
++
++	while(!list_empty(&dev->out_req_list)) {
++		req = list_entry(dev->out_req_list.prev,
++				struct usb_request, list);
++		list_del_init(&req->list);
++		req->length = buflen;
++		amb_free_buf_req(dev->out_ep, req);
++	}
++
++	spin_unlock_irqrestore(&dev->lock, flags);
++	/* just disable endpoints, forcing completion of pending i/o.
++	 * all our completion handlers free their requests in this case.
++	 */
++	/* Disable the endpoints */
++	if (dev->notify_ep)
++		usb_ep_disable(dev->notify_ep);
++	usb_ep_disable(dev->in_ep);
++	usb_ep_disable(dev->out_ep);
++}
++
++static int amb_set_interface(struct amb_dev *dev, unsigned number)
++{
++	int result = 0;
++
++	/* Free the current interface */
++	//amb_reset_config(dev);
++
++	result = amb_set_stream_config(dev);
++
++	if (!result) {
++		dev->interface = number;
++		dev->config = 1;
++	}
++	return result;
++}
++
++static int __init amb_func_bind(struct usb_configuration *c,
++								struct usb_function *f)
++{
++	struct amb_dev *dev = container_of(f, struct amb_dev, func);
++	struct usb_composite_dev *cdev = c->cdev;
++	struct usb_ep *ep;
++	int id;
++	int ret = 0;
++
++	id = usb_interface_id(c, f);
++	if (id < 0)
++		return id;
++	amb_data_stream_intf.bInterfaceNumber = id;
++
++	/* allocate bulk endpoints */
++	ep = usb_ep_autoconfig(cdev->gadget, &fs_bulk_in_desc);
++	if (!ep) {
++autoconf_fail:
++		ERROR(cdev, "%s: can't autoconfigure on %s\n",
++			f->name, cdev->gadget->name);
++		return -ENODEV;
++	}
++	ep->driver_data = dev;	/* claim the endpoint */
++	dev->in_ep = ep;
++
++	ep = usb_ep_autoconfig(cdev->gadget, &fs_bulk_out_desc);
++	if (!ep) {
++		goto autoconf_fail;
++	}
++	ep->driver_data = dev;	/* claim the endpoint */
++	dev->out_ep = ep;
++
++	ep = usb_ep_autoconfig(cdev->gadget, &fs_intr_in_desc);
++	if (!ep) {
++		goto autoconf_fail;
++	}
++	dev->notify_ep = ep;
++	ep->driver_data = dev;	/* claim the endpoint */
++
++	/* support all relevant hardware speeds... we expect that when
++	 * hardware is dual speed, all bulk-capable endpoints work at
++	 * both speeds
++	 */
++	hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress;
++	hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress;
++	hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress;
++
++	ret = usb_assign_descriptors(f, fs_amb_data_stream_function,
++				hs_amb_data_stream_function, NULL);
++	if (ret)
++		goto fail;
++
++	printk("AMB STREAM: %s speed IN/%s OUT/%s NOTIFY/%s\n",
++			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
++			dev->in_ep->name, dev->out_ep->name,dev->notify_ep->name);
++	return 0;
++fail:
++	usb_free_all_descriptors(f);
++	if (dev->in_ep)
++		dev->in_ep->driver_data = NULL;
++	if (dev->out_ep)
++		dev->out_ep->driver_data = NULL;
++	if (dev->notify_ep)
++		dev->notify_ep->driver_data = NULL;
++
++	printk("%s: can't bind, err %d\n", f->name, ret);
++	return ret;
++}
++
++static void amb_func_unbind(struct usb_configuration *c,
++							struct usb_function *f)
++{
++	usb_free_all_descriptors(f);
++}
++
++static int amb_func_set_alt(struct usb_function *f,
++							unsigned inf, unsigned alt)
++{
++	struct amb_dev *dev = container_of(f, struct amb_dev, func);
++	int ret = -ENOTSUPP;
++
++	if (!alt)
++		ret = amb_set_interface(dev, inf);
++	return ret;
++}
++
++static void amb_func_disable(struct usb_function *f)
++{
++	struct amb_dev *dev = container_of(f, struct amb_dev, func);
++	unsigned long flags;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	amb_reset_config(dev);
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++static int __init amb_bind_config(struct usb_configuration *c)
++{
++	struct usb_gadget	*gadget = c->cdev->gadget;
++	struct amb_dev		*dev;
++	struct device		*pdev;
++	int status = -ENOMEM;
++
++	usb_ep_autoconfig_reset(gadget);
++
++	dev = kzalloc(sizeof(struct amb_dev), GFP_KERNEL);
++	if (!dev)
++		return -ENOMEM;
++
++	dev->func.name = shortname;
++	dev->func.bind = amb_func_bind;
++	dev->func.unbind = amb_func_unbind;
++	dev->func.set_alt = amb_func_set_alt;
++	dev->func.disable = amb_func_disable;
++
++	spin_lock_init (&dev->lock);
++	mutex_init(&dev->mtx);
++	init_waitqueue_head(&dev->wq);
++	INIT_LIST_HEAD(&dev->in_idle_list);
++	INIT_LIST_HEAD(&dev->in_queue_list);
++	INIT_LIST_HEAD(&dev->out_req_list);
++
++	dev->gadget = gadget;
++	dev->error = 0;
++	ag_device = dev;
++
++	status = usb_add_function(c, &dev->func);
++	if (status) {
++		kfree(dev);
++		return status;
++	}
++
++	/* Setup the sysfs files for the gadget. */
++	pdev = device_create(ag_class, NULL, ag_dev_id,
++				  NULL, "amb_gadget");
++	if (IS_ERR(pdev)) {
++		status = PTR_ERR(pdev);
++		ERROR(dev, "Failed to create device: amb_gadget\n");
++		goto fail;
++	}
++
++	usb_gadget_set_selfpowered(gadget);
++
++	if (gadget->is_otg) {
++		otg_descriptor.bmAttributes |= USB_OTG_HNP;
++		amb_config_driver.descriptors = otg_desc;
++		amb_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
++	}
++#if 0
++	spin_lock_init (&dev->lock);
++	mutex_init(&dev->mtx);
++	init_waitqueue_head(&dev->wq);
++	INIT_LIST_HEAD(&dev->in_idle_list);
++	INIT_LIST_HEAD(&dev->in_queue_list);
++	INIT_LIST_HEAD(&dev->out_req_list);
++
++	dev->gadget = gadget;
++	dev->error = 0;
++	ag_device = dev;
++#endif
++	return 0;
++
++fail:
++	amb_cfg_unbind(c);
++	return status;
++}
++
++static int amb_unbind(struct usb_composite_dev *cdev)
++{
++#if 0
++	struct usb_gadget	*gadget = cdev->gadget;
++	struct amb_dev		*dev = get_gadget_data (gadget);
++
++	kfree (dev);
++	set_gadget_data(gadget, NULL);
++	ag_device = NULL;
++#else
++#endif
++	return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++static int __init amb_bind(struct usb_composite_dev *cdev)
++{
++	int ret;
++	ret = usb_string_ids_tab(cdev, strings);
++	if (ret < 0)
++		return ret;
++
++	ag_device_desc.iManufacturer = strings[USB_GADGET_MANUFACTURER_IDX].id;
++	ag_device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id;
++	ag_device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id;
++	amb_config_driver.iConfiguration = strings[STRING_SOURCE_SINK].id;
++
++	ret = usb_add_config(cdev, &amb_config_driver, amb_bind_config);
++	if (ret < 0)
++		return ret;
++
++	usb_composite_overwrite_options(cdev, &coverwrite);
++	INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
++
++	return 0;
++}
++
++static __refdata struct usb_composite_driver amb_gadget_driver = {
++	.name		=	shortname,
++	.dev		=	&ag_device_desc,
++	.strings	=	dev_strings,
++	.max_speed	=	USB_SPEED_HIGH,
++	.bind		=	amb_bind,
++	.unbind		=	amb_unbind,
++};
++
++static int __init amb_gadget_init(void)
++{
++	int rval = 0;
++
++	ag_class = class_create(THIS_MODULE, "amb_stream_gadget");
++	if (IS_ERR(ag_class)) {
++		rval = PTR_ERR(ag_class);
++		pr_err("unable to create usb_gadget class %d\n", rval);
++		return rval;
++	}
++
++	if (buflen >= 65536) {
++		pr_err("amb_gadget_init: buflen is too large\n");
++		rval = -EINVAL;
++		goto out1;
++	}
++
++	ag_dev_id = MKDEV(AMB_GADGET_MAJOR, AMB_GADGET_MINOR_START);
++	rval = register_chrdev_region(ag_dev_id, 1, "amb_gadget");
++	if(rval < 0){
++		pr_err("amb_gadget_init: register devcie number error!\n");
++		goto out1;
++	}
++
++	cdev_init(&ag_cdev, &ag_fops);
++	ag_cdev.owner = THIS_MODULE;
++	rval = cdev_add(&ag_cdev, ag_dev_id, 1);
++	if (rval) {
++		pr_err("amb_gadget_init: cdev_add failed\n");
++		unregister_chrdev_region(ag_dev_id, 1);
++		goto out1;
++	}
++
++	rval = usb_composite_probe(&amb_gadget_driver);
++	if (rval) {
++		pr_err("amb_gadget_init: cannot register gadget driver, "
++			"rval=%d\n", rval);
++		class_destroy(ag_class);
++		goto out0;
++	}
++out1:
++	if(rval)
++		class_destroy(ag_class);
++out0:
++	return rval;
++}
++module_init (amb_gadget_init);
++
++static void __exit amb_gadget_exit (void)
++{
++	usb_composite_unregister(&amb_gadget_driver);
++
++	unregister_chrdev_region(ag_dev_id, 1);
++	cdev_del(&ag_cdev);
++	class_destroy(ag_class);
++}
++module_exit (amb_gadget_exit);
++
++MODULE_AUTHOR ("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_LICENSE ("GPL");
++
++
+diff --git a/drivers/usb/gadget/ambarella_udc.c b/drivers/usb/gadget/ambarella_udc.c
+new file mode 100644
+index 00000000..ea855a75
+--- /dev/null
++++ b/drivers/usb/gadget/ambarella_udc.c
+@@ -0,0 +1,2349 @@
++/*
++* linux/drivers/usb/gadget/ambarella_udc.c
++* driver for High/Full speed USB device controller on Ambarella processors
++*
++* History:
++*	2008/06/12 - [Cao Rongrong] created file
++*	2009/03/16 - [Cao Rongrong] Change DMA descriptor allocate mode
++*
++* Copyright (C) 2008 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the
++* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++* Boston, MA  02111-1307, USA.
++*/
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <linux/usb.h>
++#include <linux/usb/gadget.h>
++#include <linux/usb/otg.h>
++#include <linux/proc_fs.h>
++#include <linux/of.h>
++#include <mach/hardware.h>
++#include <plat/rct.h>
++#include <plat/udc.h>
++#include "ambarella_udc.h"
++
++#define DRIVER_DESC	"Ambarella USB Device Controller Gadget"
++#define DRIVER_VERSION	"12 August 2015"
++#define DRIVER_AUTHOR	"Cao Rongrong <rrcao@ambarella.com>"
++
++#define	DMA_ADDR_INVALID	(~(dma_addr_t)0)
++
++static const char		gadget_name[] = "ambarella_udc";
++#if 0
++static const char		driver_desc[] = DRIVER_DESC;
++static const char 		ep0name [] = "ep0";
++#endif
++
++static const char *amb_ep_string[] = {
++	"ep0in", "ep1in", "ep2in", "ep3in",
++	"ep4in", "ep5in", "ep6in", "ep7in",
++	"ep8in", "ep9in", "ep10in", "ep11in",
++	"ep12in", "ep13in", "ep14in", "ep15in",
++
++	"ep0out", "ep1out", "ep2out", "ep3out",
++	"ep4out", "ep5out", "ep6out", "ep7out",
++	"ep8out", "ep9out", "ep10out", "ep11out",
++	"ep12out", "ep13out", "ep14out", "ep15out"
++};
++
++/*************************** DEBUG FUNCTION ***************************/
++#define DEBUG_NORMAL		0
++#define DEBUG_VERBOSE		1
++
++#define AMBARELLA_USB_DEBUG 0
++#if AMBARELLA_USB_DEBUG
++
++#define dprintk(level,format,args...) \
++	do {	\
++		if(level < 1)	\
++			printk(KERN_DEBUG "%s: " format, __FUNCTION__,## args);	\
++	} while(0)
++
++#else
++#define dprintk(args...) do { } while(0)
++#endif
++
++
++static inline struct ambarella_ep *to_ambarella_ep(struct usb_ep *ep)
++{
++	return container_of(ep, struct ambarella_ep, ep);
++}
++
++static inline struct ambarella_udc *to_ambarella_udc(struct usb_gadget *gadget)
++{
++	return container_of(gadget, struct ambarella_udc, gadget);
++}
++
++static inline struct ambarella_request *to_ambarella_req(struct usb_request *req)
++{
++	return container_of(req, struct ambarella_request, req);
++}
++
++
++/**************  PROC FILESYSTEM BEGIN *****************/
++
++static void ambarella_uevent_work(struct work_struct *data)
++{
++	struct ambarella_udc *udc;
++	char buf_status[64];
++	char buf_vbus[64];
++	char buf_driver[64];
++	char *envp[4];
++
++	udc = container_of(data, struct ambarella_udc, uevent_work);
++	buf_status[0] = '\0';
++	buf_vbus[0] = '\0';
++	buf_driver[0] = '\0';
++
++	spin_lock_irq(&udc->lock);
++	if (udc->pre_state == udc->gadget.state) {
++		spin_unlock_irq(&udc->lock);
++		return;
++	}
++
++	udc->pre_state = udc->gadget.state;
++	snprintf(buf_status, sizeof(buf_status),
++		"AMBUDC_STATUS=%s", usb_state_string(udc->gadget.state));
++	snprintf(buf_vbus, sizeof(buf_vbus), "AMBUDC_VBUS=%s",
++		udc->vbus_status ? "Connected" : "Disconnected");
++	snprintf(buf_driver, sizeof(buf_driver), "AMBUDC_DRIVER=%s",
++		udc->driver ? udc->driver->driver.name : "NULL");
++	spin_unlock_irq(&udc->lock);
++
++	envp[0] = buf_status;
++	envp[1] = buf_vbus;
++	envp[2] = buf_driver;
++	envp[3] = NULL;
++	kobject_uevent_env(&udc->dev->kobj, KOBJ_CHANGE, envp);
++}
++
++/* ========================================================================== */
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++#include <linux/seq_file.h>
++
++static const char proc_node_name[] = "driver/udc";
++static int ambarella_udc_proc_show(struct seq_file *m, void *v)
++{
++	struct ambarella_udc *udc;
++	struct usb_ctrlrequest *crq;
++
++	unsigned long	flags;
++	udc = (struct ambarella_udc *)m->private;
++	crq = (struct usb_ctrlrequest *)&udc->setup[0];
++
++	spin_lock_irqsave(&udc->lock, flags);
++
++	/* basic device status */
++	seq_printf(m,
++		DRIVER_DESC "\n"
++		"Name: %s\n"
++		"Version: %s\n"
++		"Author: %s\n\n"
++		"Gadget driver: %s\n"
++		"Host: %s\n\n",
++		gadget_name,
++		DRIVER_VERSION,
++		DRIVER_AUTHOR,
++		udc->driver ? udc->driver->driver.name : "(none)",
++		udc->vbus_status ? (udc->gadget.speed == USB_SPEED_HIGH ?
++			"high speed" : "full speed") : "disconnected");
++
++	seq_printf(m, "AMBUDC_STATUS=%s",
++			usb_state_string(udc->gadget.state));
++
++	seq_printf(m,
++		"the last setup packet is: \n"
++		"bRequestType = 0x%02x, bRequest = 0x%02x,\n"
++		"wValue = 0x%04x, wIndex = 0x%04x, wLength = 0x%04x\n\n",
++		crq->bRequestType, crq->bRequest, crq->wValue, crq->wIndex,
++		crq->wLength);
++	spin_unlock_irqrestore(&udc->lock, flags);
++	return 0;
++}
++static int ambarella_udc_proc_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, ambarella_udc_proc_show, PDE_DATA(inode));
++}
++
++static const struct file_operations ambarella_udc_fops = {
++	.open = ambarella_udc_proc_open,
++	.read = seq_read,
++	.llseek = seq_lseek,
++	.release = single_release,
++};
++
++#define remove_debugfs_files() 	remove_proc_entry(proc_node_name, NULL)
++#endif	/* CONFIG_USB_GADGET_DEBUG_FILES */
++
++/**************  PROC FILESYSTEM  END*****************/
++
++static void ambarella_regaddr_map(struct ambarella_udc *udc)
++{
++	u32 i;
++
++	for(i = 0; i < EP_NUM_MAX; i++) {
++		struct ambarella_ep *ep;
++		ep = &udc->ep[i];
++		if(ep->dir == USB_DIR_IN){
++			ep->ep_reg.ctrl_reg = USB_EP_IN_CTRL_REG(ep->id);
++			ep->ep_reg.sts_reg = USB_EP_IN_STS_REG(ep->id);
++			ep->ep_reg.buf_sz_reg = USB_EP_IN_BUF_SZ_REG(ep->id);
++			ep->ep_reg.max_pkt_sz_reg =
++				USB_EP_IN_MAX_PKT_SZ_REG(ep->id);
++			ep->ep_reg.dat_desc_ptr_reg =
++				USB_EP_IN_DAT_DESC_PTR_REG(ep->id);
++		} else {
++			ep->ep_reg.ctrl_reg = USB_EP_OUT_CTRL_REG(ep->id - 16);
++			ep->ep_reg.sts_reg = USB_EP_OUT_STS_REG(ep->id - 16);
++			ep->ep_reg.buf_sz_reg =
++				USB_EP_OUT_PKT_FRM_NUM_REG(ep->id - 16);
++			ep->ep_reg.max_pkt_sz_reg =
++				USB_EP_OUT_MAX_PKT_SZ_REG(ep->id - 16);
++			ep->ep_reg.dat_desc_ptr_reg =
++				USB_EP_OUT_DAT_DESC_PTR_REG(ep->id - 16);
++		}
++
++		ep->ep_reg.setup_buf_ptr_reg = (i == CTRL_OUT) ?
++			USB_EP_OUT_SETUP_BUF_PTR_REG(ep->id - 16) : (u32)NULL;
++	}
++}
++
++
++static void ambarella_disable_all_intr(void)
++{
++	/* device interrupt mask register */
++	amba_writel(USB_DEV_INTR_MSK_REG, 0x0000007f);
++	amba_writel(USB_DEV_EP_INTR_MSK_REG, 0xffffffff);
++	amba_writel(USB_DEV_INTR_REG, 0x0000007f);
++	amba_writel(USB_DEV_EP_INTR_REG, 0xffffffff);
++}
++
++static void ambarella_ep_fifo_flush(struct ambarella_ep *ep)
++{
++	if(ep->dir == USB_DIR_IN)  /* Empty Tx FIFO */
++		amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_FLUSH);
++	else { 			  /* Empty RX FIFO */
++		if (!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)) {
++			int retry_count = 1000;
++
++			amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_NAK);
++			amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_FLUSH_RXFIFO);
++			while(!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)) {
++				if (retry_count-- < 0) {
++					printk (KERN_ERR "%s: failed", __func__);
++					break;
++				}
++				udelay(5);
++			}
++			amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_NAK);
++		}
++	}
++}
++
++
++/*
++ * Name: ambarella_flush_fifo
++ * Description:
++ *	 Empty Tx/Rx FIFO of DMA
++ */
++static void ambarella_udc_fifo_flush(struct ambarella_udc *udc)
++{
++	struct ambarella_ep *ep;
++	u32 ep_id;
++
++	for (ep_id = 0; ep_id < EP_NUM_MAX; ep_id++) {
++		ep = &udc->ep[ep_id];
++		if(ep->ep.desc == NULL && !IS_EP0(ep))
++			continue;
++		ambarella_ep_fifo_flush(ep);
++	}
++}
++
++static void ambarella_udc_reset(void __iomem *reset_reg, struct device_node *np)
++{
++	amba_rct_setbitsl(reset_reg, UDC_SOFT_RESET_MASK);
++	msleep(1);
++	amba_rct_clrbitsl(reset_reg, UDC_SOFT_RESET_MASK);
++};
++
++static void ambarella_init_usb(struct ambarella_udc *udc)
++{
++	u32 value;
++
++	/* disconnect to host */
++	amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_SOFT_DISCON);
++	/* disable all interrupts */
++	ambarella_disable_all_intr();
++	/* disable Tx and Rx DMA */
++	amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
++	/* flush dma fifo, may used in AMboot */
++	ambarella_udc_fifo_flush(udc);
++
++	/* device config register */
++	value = USB_DEV_SPD_HI |
++		USB_DEV_SELF_POWER |
++		USB_DEV_PHY_8BIT |
++		USB_DEV_UTMI_DIR_BI |
++		USB_DEV_HALT_ACK |
++		USB_DEV_SET_DESC_STALL |
++		USB_DEV_DDR |
++		USB_DEV_CSR_PRG_EN |
++		USB_DEV_REMOTE_WAKEUP_EN;
++
++	amba_setbitsl(USB_DEV_CFG_REG, value);
++
++	/* device control register */
++	value = USB_DEV_DESC_UPD_PYL |
++		USB_DEV_LITTLE_ENDN |
++		USB_DEV_DMA_MD;
++
++	amba_setbitsl(USB_DEV_CTRL_REG, value);
++
++	// udelay(200); // FIXME: how long to wait is the best?
++}
++
++
++/*
++ * Name: init_setup_descriptor
++ * Description:
++ *  Config the setup packet to specific endpoint register
++ */
++static void init_setup_descriptor(struct ambarella_udc *udc)
++{
++	struct ambarella_ep *ep = &udc->ep[CTRL_OUT];
++
++	udc->setup_buf->status 	= USB_DMA_BUF_HOST_RDY;
++	udc->setup_buf->reserved = 0xffffffff;
++	udc->setup_buf->data0	= 0xffffffff;
++	udc->setup_buf->data1	= 0xffffffff;
++
++	amba_writel(ep->ep_reg.setup_buf_ptr_reg, udc->setup_addr | udc->dma_fix);
++}
++
++
++static int init_null_pkt_desc(struct ambarella_udc *udc)
++{
++	udc->dummy_desc = dma_pool_alloc(udc->desc_dma_pool, GFP_KERNEL,
++		&udc->dummy_desc_addr);
++	if(udc->dummy_desc == NULL){
++		printk(KERN_ERR "No memory to DMA\n");
++		return -ENOMEM;
++	}
++
++	udc->dummy_desc->data_ptr = udc->dummy_desc_addr | udc->dma_fix;
++	udc->dummy_desc->reserved = 0xffffffff;
++	udc->dummy_desc->next_desc_ptr = udc->dummy_desc_addr | udc->dma_fix;
++	udc->dummy_desc->status = USB_DMA_BUF_HOST_RDY | USB_DMA_LAST;
++
++	return 0;
++}
++
++static void init_ep0(struct ambarella_udc *udc)
++{
++	struct ambarella_ep_reg *ep_reg;
++
++	ep_reg = &udc->ep[CTRL_IN].ep_reg;
++	amba_writel(ep_reg->ctrl_reg, USB_EP_TYPE_CTRL);
++	amba_writel(ep_reg->buf_sz_reg, USB_TXFIFO_DEPTH_CTRLIN);
++	amba_writel(ep_reg->max_pkt_sz_reg, USB_EP_CTRLIN_MAX_PKT_SZ);
++	udc->ep[CTRL_IN].ctrl_sts_phase = 0;
++
++	ep_reg = &udc->ep[CTRL_OUT].ep_reg;
++	amba_writel(ep_reg->ctrl_reg, USB_EP_TYPE_CTRL);
++	amba_writel(ep_reg->max_pkt_sz_reg, USB_EP_CTRL_MAX_PKT_SZ);
++	init_setup_descriptor(udc);
++	udc->ep[CTRL_OUT].ctrl_sts_phase = 0;
++
++	/* This should be set after gadget->bind */
++	udc->ep[CTRL_OUT].ep.driver_data = udc->ep[CTRL_IN].ep.driver_data;
++
++	/* FIXME: For A5S, this bit must be set,
++	  * or USB_UDC_REG can't be read or write */
++	amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_REMOTE_WAKEUP);
++
++	/* setup ep0 CSR. Note: ep0-in and ep0-out share the same CSR reg */
++	amba_clrbitsl(USB_UDC_REG(CTRL_IN), 0x7ff << 19);
++	amba_setbitsl(USB_UDC_REG(CTRL_IN), USB_EP_CTRL_MAX_PKT_SZ << 19);
++	/* the direction bit should not take effect for ep0 */
++	amba_setbitsl(USB_UDC_REG(CTRL_IN), 0x1 << 4);
++}
++
++static int ambarella_map_dma_buffer(struct ambarella_ep *ep,
++		struct ambarella_request *req)
++{
++	struct ambarella_udc *udc = ep->udc;
++	enum dma_data_direction dmadir;
++
++	dmadir = (ep->dir & USB_DIR_IN) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
++
++	if (likely(!req->use_aux_buf)) {
++		/* map req.buf, and get req's dma address */
++		if (req->req.dma == DMA_ADDR_INVALID) {
++			req->req.dma = dma_map_single(udc->dev,
++				req->req.buf, req->req.length, dmadir);
++			/* dma address isn't 8-byte align */
++			if(req->req.dma & 0x7){
++				printk("dma address isn't 8-byte align\n");
++				BUG();
++			}
++			req->mapped = 1;
++		} else {
++			dma_sync_single_for_device(udc->dev,
++				req->req.dma, req->req.length, dmadir);
++			req->mapped = 0;
++		}
++	} else {
++		if (req->dma_aux == DMA_ADDR_INVALID) {
++			req->dma_aux = dma_map_single(udc->dev,
++				req->buf_aux, req->req.length, dmadir);
++			/* dma address isn't 8-byte align */
++			if(req->dma_aux & 0x7){
++				printk("dma address isn't 8-byte align\n");
++				BUG();
++			}
++			req->mapped = 1;
++		} else {
++			dma_sync_single_for_device(udc->dev,
++				req->dma_aux, req->req.length, dmadir);
++			req->mapped = 0;
++		}
++	}
++
++	return 0;
++}
++
++
++static int ambarella_unmap_dma_buffer(struct ambarella_ep *ep,
++		struct ambarella_request *req)
++{
++	struct ambarella_udc *udc = ep->udc;
++	enum dma_data_direction dmadir;
++
++	dmadir = (ep->dir & USB_DIR_IN) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
++
++	if (likely(!req->use_aux_buf)) {
++		if (req->mapped) {
++			dma_unmap_single(udc->dev,
++				req->req.dma, req->req.length, dmadir);
++			req->req.dma = DMA_ADDR_INVALID;
++			req->mapped = 0;
++		} else {
++			dma_sync_single_for_cpu(udc->dev,
++				req->req.dma, req->req.length, dmadir);
++		}
++	} else {
++		if (req->mapped) {
++			dma_unmap_single(udc->dev,
++				req->dma_aux, req->req.length, dmadir);
++			req->dma_aux = DMA_ADDR_INVALID;
++			req->mapped = 0;
++		} else {
++			dma_sync_single_for_cpu(udc->dev,
++				req->dma_aux, req->req.length, dmadir);
++		}
++	}
++
++	return 0;
++}
++
++static struct ambarella_data_desc *ambarella_get_last_desc(struct ambarella_ep *ep)
++{
++	struct ambarella_data_desc *desc = ep->data_desc;
++	int retry_count = 1000;
++
++	while(desc && (desc->status & USB_DMA_LAST) == 0) {
++		if (retry_count-- < 0) {
++			printk(KERN_ERR "Can't find the last descriptor\n");
++			break;
++		}
++
++		if (desc->last_aux == 1)
++			break;
++
++		desc = desc->next_desc_virt;
++	};
++
++	return desc;
++}
++
++static u32 ambarella_check_bna_error (struct ambarella_ep *ep, u32 ep_status)
++{
++	u32 retval = 0;
++
++	/* Error: Buffer Not Available */
++	if (ep_status & USB_EP_BUF_NOT_AVAIL) {
++		//printk(KERN_ERR "[USB]:BNA error in %s\n", ep->ep.name);
++		amba_writel(ep->ep_reg.sts_reg, USB_EP_BUF_NOT_AVAIL);
++		retval = 1;
++	}
++
++	return retval;
++}
++
++static u32 ambarella_check_he_error (struct ambarella_ep *ep, u32 ep_status)
++{
++	u32 retval = 0;
++
++	/* Error: Host Error */
++	if (ep_status & USB_EP_HOST_ERR) {
++		printk(KERN_ERR "[USB]:HE error in %s\n", ep->ep.name);
++		amba_writel(ep->ep_reg.sts_reg, USB_EP_HOST_ERR);
++		retval = 1;
++	}
++
++	return retval;
++}
++
++static u32 ambarella_check_dma_error (struct ambarella_ep *ep)
++{
++	u32	retval = 0, sts_tmp1, sts_tmp2;
++
++	if(ep->last_data_desc){
++		sts_tmp1 = ep->last_data_desc->status & USB_DMA_BUF_STS;
++		sts_tmp2 = ep->last_data_desc->status & USB_DMA_RXTX_STS;
++		if ((sts_tmp1 != USB_DMA_BUF_DMA_DONE) || (sts_tmp2 != USB_DMA_RXTX_SUCC)){
++			//printk(KERN_ERR "%s: DMA failed\n", ep->ep.name);
++			retval = 1;
++		}
++	}
++
++
++	return retval;
++}
++
++
++static void ambarella_free_descriptor(struct ambarella_ep *ep,
++	struct ambarella_request *req)
++{
++	struct ambarella_data_desc *data_desc, *next_data_desc;
++	struct dma_pool *desc_dma_pool = ep->udc->desc_dma_pool;
++	int i;
++
++	next_data_desc = req->data_desc;
++	for(i = 0; i < req->desc_count; i++){
++		data_desc = next_data_desc;
++		data_desc->status = USB_DMA_BUF_HOST_BUSY | USB_DMA_LAST;
++		data_desc->data_ptr = 0xffffffff;
++		data_desc->next_desc_ptr = 0;
++		data_desc->last_aux = 1;
++		next_data_desc = data_desc->next_desc_virt;
++		dma_pool_free(desc_dma_pool, data_desc, data_desc->cur_desc_addr);
++	}
++
++	req->desc_count = 0;
++	req->data_desc = NULL;
++	req->data_desc_addr = 0;
++}
++
++static int ambarella_reuse_descriptor(struct ambarella_ep *ep,
++	struct ambarella_request *req, u32 desc_count, dma_addr_t start_address)
++{
++	struct ambarella_udc *udc = ep->udc;
++	struct ambarella_data_desc *data_desc, *next_data_desc;
++	u32 data_transmit, rest_bytes, i;
++	dma_addr_t buf_dma_address;
++
++	next_data_desc = req->data_desc;
++	for(i = 0; i < desc_count; i++){
++		rest_bytes = req->req.length - i * ep->ep.maxpacket;
++		if(ep->dir == USB_DIR_IN)
++			data_transmit = rest_bytes < ep->ep.maxpacket ?
++				rest_bytes : ep->ep.maxpacket;
++		else
++			data_transmit = 0;
++
++		data_desc = next_data_desc;
++		data_desc->status = USB_DMA_BUF_HOST_RDY | data_transmit;
++		data_desc->reserved = 0xffffffff;
++		buf_dma_address = start_address + i * ep->ep.maxpacket;
++		data_desc->data_ptr = buf_dma_address | udc->dma_fix;
++		data_desc->last_aux = 0;
++
++		next_data_desc = data_desc->next_desc_virt;
++	}
++
++	/* Patch last one. */
++	data_desc->status |= USB_DMA_LAST;
++	data_desc->last_aux = 1;
++
++	return 0;
++}
++
++static int ambarella_prepare_descriptor(struct ambarella_ep *ep,
++	struct ambarella_request *req, gfp_t gfp)
++{
++	struct ambarella_udc *udc = ep->udc;
++	struct ambarella_data_desc *data_desc = NULL;
++	struct ambarella_data_desc *prev_data_desc = NULL;
++	dma_addr_t desc_phys, start_address, buf_dma_address;
++	u32 desc_count, data_transmit, rest_bytes, i;
++
++	if (likely(!req->use_aux_buf))
++		start_address = req->req.dma;
++	else
++		start_address = req->dma_aux;
++
++	desc_count = (req->req.length + ep->ep.maxpacket - 1) / ep->ep.maxpacket;
++	if(req->req.zero && (req->req.length % ep->ep.maxpacket == 0))
++		desc_count++;
++	if(desc_count == 0)
++		desc_count = 1;
++
++	req->active_desc_count = desc_count;
++
++	if (desc_count <= req->desc_count) {
++		ambarella_reuse_descriptor(ep, req, desc_count, start_address);
++		return 0;
++	}
++
++	if(req->desc_count > 0)
++		ambarella_free_descriptor(ep, req);
++
++	req->desc_count = desc_count;
++
++	for(i = 0; i < desc_count; i++){
++		rest_bytes = req->req.length - i * ep->ep.maxpacket;
++		if(ep->dir == USB_DIR_IN)
++			data_transmit = rest_bytes < ep->ep.maxpacket ?
++				rest_bytes : ep->ep.maxpacket;
++		else
++			data_transmit = 0;
++
++		data_desc = dma_pool_alloc(udc->desc_dma_pool, gfp, &desc_phys);
++		if (!data_desc) {
++			req->desc_count = i;
++			if(req->desc_count > 0)
++				ambarella_free_descriptor(ep, req);
++			return -ENOMEM;
++		}
++
++		data_desc->status = USB_DMA_BUF_HOST_RDY | data_transmit;
++		data_desc->reserved = 0xffffffff;
++		buf_dma_address = start_address + i * ep->ep.maxpacket;
++		data_desc->data_ptr = buf_dma_address | udc->dma_fix;
++		data_desc->next_desc_ptr = 0;
++		data_desc->rsvd1 = 0xffffffff;
++		data_desc->last_aux = 0;
++		data_desc->cur_desc_addr = desc_phys;
++
++		if(prev_data_desc){
++			prev_data_desc->next_desc_ptr = desc_phys | udc->dma_fix;
++			prev_data_desc->next_desc_virt = data_desc;
++		}
++
++		prev_data_desc = data_desc;
++
++		if(i == 0){
++			req->data_desc = data_desc;
++			req->data_desc_addr = desc_phys;
++		}
++	}
++
++	/* Patch last one */
++	data_desc->status |= USB_DMA_LAST;
++	data_desc->next_desc_ptr = 0;
++	data_desc->next_desc_virt = NULL;
++	data_desc->last_aux = 1;
++
++	return 0;
++}
++
++static void ambarella_clr_ep_nak(struct ambarella_ep *ep)
++{
++	struct ambarella_ep_reg *ep_reg = &ep->ep_reg;
++
++	amba_setbitsl(ep_reg->ctrl_reg, USB_EP_CLR_NAK);
++	if (amba_readl(ep_reg->ctrl_reg) & USB_EP_NAK_STS) {
++		/* can't clear NAK, let somebody clear it after Rx DMA is done. */
++		ep->need_cnak = 1;
++	}else{
++		ep->need_cnak = 0;
++	}
++}
++
++static void ambarella_set_ep_nak(struct ambarella_ep *ep)
++{
++	amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_SET_NAK);
++}
++
++static void ambarella_enable_rx_dma(struct ambarella_ep *ep)
++{
++	ep->dma_going = 1;
++	amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN);
++}
++
++static void ambarella_patch_iso_desc(struct ambarella_udc *udc,
++	struct ambarella_request * req, struct ambarella_ep *ep, int frame_fix)
++{
++	struct ambarella_data_desc *data_desc;
++	u32 current_frame, max_packet_num, i, j;
++
++	current_frame = ambarella_udc_get_frame(&udc->gadget);
++	data_desc = req->data_desc;
++
++	/* according to USB2.0 spec, each microframe can send 3 packets at most */
++	for (i = 0; i < req->active_desc_count; i += j) {
++		if ((req->active_desc_count - i) >= ISO_MAX_PACKET)
++			max_packet_num = ISO_MAX_PACKET;
++		else
++			max_packet_num = req->active_desc_count - i;
++
++		for (j = 0; j < max_packet_num; j++) {
++			data_desc->status |= ((current_frame + ep->frame_offset + frame_fix) << 16);
++			data_desc->status |= (max_packet_num << 14);
++			data_desc = data_desc->next_desc_virt;
++		}
++	}
++}
++
++static void ambarella_set_tx_dma(struct ambarella_ep *ep,
++	struct ambarella_request * req, int frame_fix)
++{
++	struct ambarella_udc *udc = ep->udc;
++	struct ambarella_ep_reg *ep_reg = &ep->ep_reg;
++
++	if (IS_ISO_IN_EP(ep))
++		ambarella_patch_iso_desc(udc, req, ep, frame_fix);
++
++	ep->data_desc = req->data_desc;
++	amba_writel(ep_reg->dat_desc_ptr_reg, req->data_desc_addr | udc->dma_fix);
++	/* set Poll command to transfer data to Tx FIFO */
++	amba_setbitsl(ep_reg->ctrl_reg, USB_EP_POLL_DEMAND);
++	ep->dma_going = 1;
++}
++
++
++static void ambarella_set_rx_dma(struct ambarella_ep *ep,
++	struct ambarella_request * req)
++{
++	struct ambarella_ep_reg *ep_reg = &ep->ep_reg;
++	struct ambarella_udc *udc = ep->udc;
++	u32 i;
++
++	if(req){
++		ep->data_desc = req->data_desc;
++		amba_writel(ep_reg->dat_desc_ptr_reg,
++				req->data_desc_addr | udc->dma_fix);
++	} else {
++		/* receive zero-length-packet */
++		udc->dummy_desc->status = USB_DMA_BUF_HOST_RDY | USB_DMA_LAST;
++		amba_writel(ep_reg->dat_desc_ptr_reg,
++				udc->dummy_desc_addr | udc->dma_fix);
++	}
++
++	/* enable dma completion interrupt for next RX data */
++	amba_clrbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
++	/* re-enable DMA read */
++	ambarella_enable_rx_dma(ep);
++
++	if (amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS) {
++		/* clear NAK for TX dma */
++		for (i = 0; i < EP_NUM_MAX; i++) {
++			struct ambarella_ep *_ep = &udc->ep[i];
++			if (_ep->need_cnak == 1)
++				ambarella_clr_ep_nak(_ep);
++		}
++	}
++
++	/* clear NAK */
++	ambarella_clr_ep_nak(ep);
++}
++
++static int ambarella_handle_ep_stall(struct ambarella_ep *ep, u32 ep_status)
++{
++	int ret = 0;
++
++	if (ep_status & USB_EP_RCV_CLR_STALL) {
++		amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_CLR_NAK);
++		amba_clrbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
++		amba_setbitsl(ep->ep_reg.sts_reg, USB_EP_RCV_CLR_STALL);
++		ret = 1;
++	}
++
++	if (ep_status & USB_EP_RCV_SET_STALL) {
++		amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
++		if (ep->dir == USB_DIR_IN)
++			amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_FLUSH);
++		amba_setbitsl(ep->ep_reg.sts_reg, USB_EP_RCV_SET_STALL);
++		ret = 1;
++	}
++
++	return ret;
++}
++
++static void ambarella_handle_request_packet(struct ambarella_udc *udc)
++{
++	struct usb_ctrlrequest *crq;
++	int ret;
++
++	ambarella_ep_nuke(&udc->ep[CTRL_OUT], -EPROTO);  // Todo
++
++	/* read out setup packet */
++	udc->setup[0] = udc->setup_buf->data0;
++	udc->setup[1] = udc->setup_buf->data1;
++	/* reinitialize setup packet */
++	init_setup_descriptor(udc);
++
++	crq = (struct usb_ctrlrequest *) &udc->setup[0];
++
++	dprintk(DEBUG_NORMAL, "bRequestType = 0x%02x, bRequest = 0x%02x, "
++		"wValue = 0x%04x, wIndex = 0x%04x, wLength = 0x%04x\n",
++		crq->bRequestType, crq->bRequest, crq->wValue, crq->wIndex,
++		crq->wLength);
++
++	if((crq->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD){
++		switch(crq->bRequest)
++		{
++		case USB_REQ_GET_STATUS:
++		case USB_REQ_SET_ADDRESS:
++		case USB_REQ_CLEAR_FEATURE:
++		case USB_REQ_SET_FEATURE:
++			pr_err("%s: This bRequest is not implemented!\n"
++				"\tbRequestType = 0x%02x, bRequest = 0x%02x,\n"
++				"\twValue = 0x%04x, wIndex = 0x%04x, wLength = 0x%04x\n",
++				__func__,
++				crq->bRequestType, crq->bRequest, crq->wValue, crq->wIndex,
++				crq->wLength);
++		}
++	}
++
++	if (crq->bRequestType & USB_DIR_IN)
++		udc->gadget.ep0 = &udc->ep[CTRL_IN].ep;
++
++	else
++		udc->gadget.ep0 = &udc->ep[CTRL_OUT].ep;
++
++	spin_unlock(&udc->lock);
++	ret = udc->driver->setup(&udc->gadget, crq);
++	spin_lock(&udc->lock);
++	if (ret < 0) {
++		pr_err("%s: SETUP request failed (%d)\n", __func__, ret);
++		amba_setbitsl(udc->ep[CTRL_IN].ep_reg.ctrl_reg, USB_EP_STALL | USB_EP_FLUSH);
++		/* Re-enable Rx DMA to receive next setup packet */
++		ambarella_enable_rx_dma(&udc->ep[CTRL_OUT]);
++		ambarella_clr_ep_nak(&udc->ep[CTRL_OUT]);
++	}
++
++	return;
++
++}
++
++static void ambarella_handle_data_in(struct ambarella_ep *ep)
++{
++	struct ambarella_request	*req = NULL;
++	struct ambarella_udc *udc = ep->udc;
++
++	/* get request */
++	if (list_empty(&ep->queue)) {
++		printk(KERN_DEBUG "%s: req NULL\n", __func__);
++		return ;
++	}
++
++	req = list_first_entry(&ep->queue, struct ambarella_request,queue);
++
++	/* If error happened, issue the request again */
++	if (ambarella_check_dma_error(ep))
++		req->req.status = -EPROTO;
++	else {
++		/* No error happened, so all the data has been sent to host */
++		req->req.actual = req->req.length;
++	}
++
++	ambarella_udc_done(ep, req, 0);
++
++	if(ep->id == CTRL_IN){
++		/* For STATUS-OUT stage */
++		udc->ep[CTRL_OUT].ctrl_sts_phase = 1;
++		ambarella_set_rx_dma(&udc->ep[CTRL_OUT], NULL);
++	}
++}
++
++static int ambarella_handle_data_out(struct ambarella_ep *ep)
++{
++	struct ambarella_request	*req = NULL;
++	struct ambarella_udc *udc = ep->udc;
++	u32 recv_size = 0, req_size;
++
++	/* get request */
++	if (list_empty(&ep->queue)) {
++		printk(KERN_DEBUG "%s: req NULL\n", __func__);
++		return -EINVAL;
++	}
++
++	req = list_first_entry(&ep->queue, struct ambarella_request,queue);
++
++	/* If error happened, issue the request again */
++	if (ambarella_check_dma_error(ep))
++		req->req.status = -EPROTO;
++
++	recv_size = ep->last_data_desc->status & USB_DMA_RXTX_BYTES;
++	if (!recv_size && req->req.length == UDC_DMA_MAXPACKET) {
++		/* on 64k packets the RXBYTES field is zero */
++		recv_size = UDC_DMA_MAXPACKET;
++	}
++
++	req_size = req->req.length - req->req.actual;
++	if (recv_size > req_size) {
++		if ((req_size % ep->ep.maxpacket) != 0)
++			req->req.status = -EOVERFLOW;
++		recv_size = req_size;
++	}
++
++	req->req.actual += recv_size;
++
++	ambarella_udc_done(ep, req, 0);
++
++	if(ep->id == CTRL_OUT) {
++		/* For STATUS-IN stage */
++		ambarella_clr_ep_nak(&udc->ep[CTRL_IN]);
++		/* Re-enable Rx DMA to receive next setup packet */
++		ambarella_enable_rx_dma(ep);
++		ep->dma_going = 0;
++	}
++
++	return 0;
++}
++
++
++static void ambarella_udc_done(struct ambarella_ep *ep,
++		struct ambarella_request *req, int status)
++{
++	unsigned halted_tmp, need_queue = 0;
++	struct ambarella_request *next_req;
++
++	halted_tmp = ep->halted;
++
++	list_del_init(&req->queue);
++
++	if(!list_empty(&ep->queue) && !ep->halted && !ep->cancel_transfer){
++		need_queue = 1;
++	} else if (!IS_EP0(ep) && (ep->dir == USB_DIR_IN) && !ep->cancel_transfer) {
++		/* ep->ep.desc = NULL when ep disabled */
++		if (!ep->ep.desc || IS_ISO_IN_EP(ep))
++			ambarella_set_ep_nak(ep);
++		amba_setbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
++	}
++
++	if (likely (req->req.status == -EINPROGRESS))
++		req->req.status = status;
++	else
++		status = req->req.status;
++
++	ambarella_unmap_dma_buffer(ep, req);
++
++	if (req->use_aux_buf && ep->dir != USB_DIR_IN)
++		memcpy(req->req.buf, req->buf_aux, req->req.actual);
++
++	ep->data_desc = NULL;
++	ep->last_data_desc = NULL;
++
++	ep->halted = 1;
++	spin_unlock(&ep->udc->lock);
++	req->req.complete(&ep->ep, &req->req);
++	spin_lock(&ep->udc->lock);
++	ep->halted = halted_tmp;
++
++	if(need_queue){
++		next_req = list_first_entry (&ep->queue,
++			 struct ambarella_request, queue);
++
++		switch(ep->dir) {
++		case USB_DIR_IN:
++			/* no need to wait for IN-token for ISO transfer */
++			if (IS_ISO_IN_EP(ep)) {
++				amba_writel(ep->ep_reg.sts_reg, USB_EP_IN_PKT);
++				ambarella_set_tx_dma(ep, next_req, 1);
++			}
++			ambarella_clr_ep_nak(ep);
++			break;
++		case USB_DIR_OUT:
++			ambarella_set_rx_dma(ep, next_req);
++			break;
++		default:
++			return;
++		}
++	}
++}
++
++static void ambarella_ep_nuke(struct ambarella_ep *ep, int status)
++{
++	while (!list_empty (&ep->queue)) {
++		struct ambarella_request *req;
++		req = list_first_entry(&ep->queue,
++			struct ambarella_request, queue);
++		ambarella_udc_done(ep, req, status);
++	}
++}
++
++/*
++ * Name: device_interrupt
++ * Description:
++ *	Process related device interrupt
++ */
++static void udc_device_interrupt(struct ambarella_udc *udc, u32 int_value)
++{
++	/* case 1. Get set_config or set_interface request from host */
++	if (int_value & (USB_DEV_SET_CFG | USB_DEV_SET_INTF)) {
++		struct usb_ctrlrequest crq;
++		u32 i, ret, csr_config;
++
++		if(int_value & USB_DEV_SET_CFG) {
++			/* Ack the SC interrupt */
++			amba_writel(USB_DEV_INTR_REG, USB_DEV_SET_CFG);
++			udc->cur_config = (u16)(amba_readl(USB_DEV_STS_REG) & USB_DEV_CFG_NUM);
++
++			crq.bRequestType = 0x00;
++			crq.bRequest = USB_REQ_SET_CONFIGURATION;
++			crq.wValue = cpu_to_le16(udc->cur_config);
++			crq.wIndex = 0x0000;
++			crq.wLength = 0x0000;
++		} else if(int_value & USB_DEV_SET_INTF){
++			/* Ack the SI interrupt */
++			amba_writel(USB_DEV_INTR_REG, USB_DEV_SET_INTF);
++			udc->cur_intf = (amba_readl(USB_DEV_STS_REG) & USB_DEV_INTF_NUM) >> 4;
++			udc->cur_alt = (amba_readl(USB_DEV_STS_REG) & USB_DEV_ALT_SET) >> 8;
++
++			crq.bRequestType = 0x01;
++			crq.bRequest = USB_REQ_SET_INTERFACE;
++			crq.wValue = cpu_to_le16(udc->cur_alt);
++			crq.wIndex = cpu_to_le16(udc->cur_intf);
++			crq.wLength = 0x0000;
++		}
++
++		for (i = 0; i < EP_NUM_MAX; i++){
++			udc->ep[i].halted = 0;
++			amba_clrbitsl(udc->ep[i].ep_reg.ctrl_reg, USB_EP_STALL);
++		}
++
++		/* setup ep0 CSR. Note: ep0-in and ep0-out share the same CSR reg */
++		csr_config = (udc->cur_config << 7) | (udc->cur_intf << 11) |
++			(udc->cur_alt << 15);
++		amba_clrbitsl(USB_UDC_REG(CTRL_IN), 0xfff << 7);
++		amba_setbitsl(USB_UDC_REG(CTRL_IN), csr_config);
++
++		udc->auto_ack_0_pkt = 1;
++		ambarella_ep_nuke(&udc->ep[CTRL_OUT], -EPROTO);
++		spin_unlock(&udc->lock);
++		ret = udc->driver->setup(&udc->gadget, &crq);
++		spin_lock(&udc->lock);
++		if(ret < 0)
++			printk(KERN_ERR "set config failed. (%d)\n", ret);
++
++		/* told UDC the configuration is done, and to ack HOST
++		 * UDC has to ack the host quickly, or Host will think failed,
++		 * do don't add much debug message when receive SC/SI irq.*/
++		amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_CSR_DONE);
++		udelay(150);
++		usb_gadget_set_state(&udc->gadget, USB_STATE_CONFIGURED);
++		schedule_work(&udc->uevent_work);
++
++	}
++
++	/* case 2. Get reset Interrupt */
++	else if (int_value & USB_DEV_RESET) {
++
++		dprintk(DEBUG_NORMAL, "USB reset IRQ\n");
++
++		amba_writel(USB_DEV_INTR_REG, USB_DEV_RESET);
++
++		ambarella_disable_all_intr();
++
++		if (udc->host_suspended && udc->driver && udc->driver->resume){
++			spin_unlock(&udc->lock);
++			udc->driver->resume(&udc->gadget);
++			spin_lock(&udc->lock);
++			udc->host_suspended = 0;
++		}
++
++		ambarella_stop_activity(udc);
++
++		udc->gadget.speed = USB_SPEED_UNKNOWN;
++		udc->auto_ack_0_pkt = 0;
++		udc->remote_wakeup_en = 0;
++
++		udc->udc_is_enabled = 0;
++		ambarella_udc_enable(udc);
++
++		usb_gadget_set_state(&udc->gadget, USB_STATE_ATTACHED);
++		schedule_work(&udc->uevent_work);
++#if 0
++		/* enable suspend interrupt */
++		amba_clrbitsl(USB_DEV_INTR_MSK_REG, UDC_INTR_MSK_US);
++#endif
++	}
++
++	/* case 3. Get suspend Interrupt */
++	else if (int_value & USB_DEV_SUSP) {
++
++		pr_err("%s: USB suspend IRQ\n", __func__);
++
++		amba_writel(USB_DEV_INTR_REG, USB_DEV_SUSP);
++
++		if (udc->driver->suspend) {
++			udc->host_suspended = 1;
++			spin_unlock(&udc->lock);
++			udc->driver->suspend(&udc->gadget);
++			spin_lock(&udc->lock);
++		}
++	}
++
++	/* case 4. enumeration complete */
++	else if(int_value & USB_DEV_ENUM_CMPL) {
++		u32 	value = 0;
++
++		/* Ack the CMPL interrupt */
++		amba_writel(USB_DEV_INTR_REG, USB_DEV_ENUM_CMPL);
++
++		value = amba_readl(USB_DEV_STS_REG) & USB_DEV_ENUM_SPD;
++
++		if(value == USB_DEV_ENUM_SPD_HI) {  /* high speed */
++
++			dprintk(DEBUG_NORMAL,"enumeration IRQ - "
++					"High-speed bus detected\n");
++			udc->gadget.speed = USB_SPEED_HIGH;
++		} else if (value == USB_DEV_ENUM_SPD_FU) { /* full speed */
++
++			dprintk(DEBUG_NORMAL,"enumeration IRQ - "
++					"Full-speed bus detected\n");
++			udc->gadget.speed = USB_SPEED_FULL;
++		} else {
++			printk(KERN_ERR "Not supported speed!"
++					"USB_DEV_STS_REG = 0x%x\n", value);
++			udc->gadget.speed = USB_SPEED_UNKNOWN;
++
++		}
++	} /* ENUM COMPLETE */
++	else {
++		printk(KERN_ERR "Unknown Interrupt:0x%08x\n", int_value);
++		/* Ack the Unknown interrupt */
++		amba_writel(USB_DEV_INTR_REG, int_value);
++	}
++}
++
++
++/*
++ * Name: udc_epin_interrupt
++ * Description:
++ *	Process IN(CTRL or BULK) endpoint interrupt
++ */
++static void udc_epin_interrupt(struct ambarella_udc *udc, u32 ep_id)
++{
++	u32 ep_status = 0;
++	struct ambarella_ep *ep = &udc->ep[ep_id];
++	struct ambarella_request *req;
++
++	ep_status = amba_readl(ep->ep_reg.sts_reg);
++
++	/* TxFIFO is empty, but we've not used this bit, so just ignored simply. */
++	if (ep_status == USB_EP_TXFIFO_EMPTY) {
++		amba_writel(ep->ep_reg.sts_reg, ep_status);
++		return;
++	}
++
++	dprintk(DEBUG_NORMAL, "%s: ep_status = 0x%08x\n", ep->ep.name, ep_status);
++
++	if (ambarella_handle_ep_stall(ep, ep_status))
++		return;
++
++	if (ambarella_check_bna_error(ep, ep_status)
++			|| ambarella_check_he_error(ep, ep_status)) {
++		struct ambarella_request	*req = NULL;
++		ep->dma_going = 0;
++		ep->cancel_transfer = 0;
++		ep->need_cnak = 0;
++		if (!list_empty(&ep->queue)) {
++			req = list_first_entry(&ep->queue, struct ambarella_request,queue);
++			req->req.status = -EPROTO;
++			ambarella_udc_done(ep, req, 0);
++		}
++		return;
++	}
++
++	if (ep_status & USB_EP_TRN_DMA_CMPL) {
++		/* write dummy desc to try to avoid BNA error */
++		ep->udc->dummy_desc->status =
++			USB_DMA_BUF_HOST_RDY | USB_DMA_LAST;
++		amba_writel(ep->ep_reg.dat_desc_ptr_reg,
++			udc->dummy_desc_addr | udc->dma_fix);
++
++		if(ep->halted || ep->dma_going == 0 || ep->cancel_transfer == 1
++				|| list_empty(&ep->queue)) {
++			ep_status &= (USB_EP_IN_PKT | USB_EP_TRN_DMA_CMPL);
++			amba_writel(ep->ep_reg.sts_reg, ep_status);
++			ep->dma_going = 0;
++			ep->cancel_transfer = 0;
++			return;
++		}
++
++		ep->dma_going = 0;
++		ep->cancel_transfer = 0;
++		ep->need_cnak = 0;
++
++		ep->last_data_desc = ambarella_get_last_desc(ep);
++		if(ep->last_data_desc == NULL){
++			printk(KERN_ERR "%s: last_data_desc is NULL\n", ep->ep.name);
++			BUG();
++			return;
++		}
++		ambarella_handle_data_in(&udc->ep[ep_id]);
++	} else if(ep_status & USB_EP_IN_PKT) {
++#if 0
++		if (IS_ISO_IN_EP(ep))
++			goto finish;
++#endif
++
++		if(!ep->halted && !ep->cancel_transfer && !list_empty(&ep->queue)){
++			req = list_first_entry(&ep->queue,
++				struct ambarella_request, queue);
++			ambarella_set_tx_dma(ep, req, 0);
++		} else if (ep->dma_going == 0 || ep->halted || ep->cancel_transfer) {
++			ambarella_set_ep_nak(ep);
++		}
++		ep->cancel_transfer = 0;
++	} else if (ep_status != 0){
++		pr_err("%s: %s, Unknown int source(0x%08x)\n", __func__,
++			ep->ep.name, ep_status);
++		amba_writel(ep->ep_reg.sts_reg, ep_status);
++		return;
++	}
++
++//finish:
++	if (ep_status != 0) {
++		ep_status &= (USB_EP_IN_PKT | USB_EP_TRN_DMA_CMPL | USB_EP_TXFIFO_EMPTY);
++//		ep_status &= (USB_EP_IN_PKT | USB_EP_TRN_DMA_CMPL | USB_EP_RCV_CLR_STALL);
++		amba_writel(ep->ep_reg.sts_reg, ep_status);
++	}
++}
++
++
++/*
++ * Name: udc_epout_interrupt
++ * Description:
++ *	Process OUT endpoint interrupt
++ */
++static void udc_epout_interrupt(struct ambarella_udc *udc, u32 ep_id)
++{
++	struct ambarella_ep *ep = &udc->ep[ep_id];
++	u32 desc_status, ep_status, i;
++
++	/* check the status bits for what kind of packets in */
++	ep_status = amba_readl(ep->ep_reg.sts_reg);
++
++	if (ambarella_handle_ep_stall(ep, ep_status))
++		return;
++
++
++	if(ep_id == CTRL_OUT) {
++		/* Cope with setup-data packet  */
++		if((ep_status & USB_EP_OUT_PKT_MSK) == USB_EP_SETUP_PKT){
++			amba_writel(ep->ep_reg.sts_reg, USB_EP_SETUP_PKT);
++			ep->ctrl_sts_phase = 0;
++			ep->dma_going = 0;
++			ambarella_handle_request_packet(udc);
++		}
++	}
++
++	/* Cope with normal data packet  */
++	if((ep_status & USB_EP_OUT_PKT_MSK) == USB_EP_OUT_PKT) {
++
++		amba_writel(ep->ep_reg.sts_reg, USB_EP_OUT_PKT);
++		ep->dma_going = 0;
++
++		/* Just cope with the zero-length packet */
++		if(ep->ctrl_sts_phase == 1) {
++			ep->ctrl_sts_phase = 0;
++			ambarella_enable_rx_dma(ep);
++			ep->dma_going = 0;
++			return;
++		}
++
++		if(ep->halted || ep->cancel_transfer || list_empty(&ep->queue)) {
++			amba_writel(ep->ep_reg.sts_reg, ep_status);
++			return;
++		}
++
++		if (ambarella_check_bna_error(ep, ep_status))
++			return;
++
++		if(ambarella_check_he_error(ep, ep_status) && !list_empty(&ep->queue)) {
++			struct ambarella_request *req = NULL;
++			req = list_first_entry(&ep->queue,
++				struct ambarella_request, queue);
++			req->req.status = -EPROTO;
++			ambarella_udc_done(ep, req, 0);
++			return;
++		}
++
++		ep->last_data_desc = ambarella_get_last_desc(ep);
++		if(ep->last_data_desc == NULL){
++			pr_err("%s: %s, last_data_desc is NULL\n", __func__, ep->ep.name);
++			BUG();
++			return;
++		}
++
++		if(ep_id != CTRL_OUT){
++			desc_status = ep->last_data_desc->status;
++			/* received data */
++			if((desc_status & USB_DMA_BUF_STS) == USB_DMA_BUF_DMA_DONE) {
++				amba_setbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep_id);
++				ambarella_set_ep_nak(ep);
++			}
++		}
++
++		ambarella_handle_data_out(ep);
++
++		/* clear NAK for TX dma */
++		if (amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS) {
++			for (i = 0; i < EP_NUM_MAX; i++) {
++				struct ambarella_ep *_ep = &udc->ep[i];
++				if (_ep->need_cnak == 1)
++					ambarella_clr_ep_nak(_ep);
++			}
++		}
++	}
++
++	return;
++}
++
++static irqreturn_t ambarella_udc_irq(int irq, void *_dev)
++{
++	struct ambarella_udc *udc = _dev;
++	u32 value, handled = 0, i, ep_irq;
++
++	spin_lock(&udc->lock);
++	/* If gadget driver is not connected, do not handle the interrupt  */
++	if (!udc->driver) {
++		amba_writel(USB_DEV_INTR_REG, amba_readl(USB_DEV_INTR_REG));
++		amba_writel(USB_DEV_EP_INTR_REG, amba_readl(USB_DEV_EP_INTR_REG));
++		ambarella_udc_set_pullup(udc, 0);
++	}
++
++	/* 1. check if device interrupt */
++	value = amba_readl(USB_DEV_INTR_REG);
++	if(value) {
++
++		dprintk(DEBUG_NORMAL, "device int value = 0x%x\n", value);
++
++		handled = 1;
++		udc_device_interrupt(udc, value);
++
++	}
++	/* 2. check if endpoint interrupt */
++	value = amba_readl(USB_DEV_EP_INTR_REG);
++	if(value) {
++		handled = 1;
++
++		for(i = 0; i < EP_NUM_MAX; i++){
++			ep_irq = 1 << i;
++			if (!(value & ep_irq))
++				continue;
++
++			/* ack the endpoint interrupt */
++			amba_writel(USB_DEV_EP_INTR_REG, ep_irq);
++
++			/* irq for out ep ? */
++			if (i >= EP_IN_NUM)
++				udc_epout_interrupt(udc, i);
++			else
++				udc_epin_interrupt(udc, i);
++
++			value &= ~ep_irq;
++			if(value == 0)
++				break;
++		}
++	}
++
++	spin_unlock(&udc->lock);
++
++	return IRQ_RETVAL(handled);
++}
++
++static void ambarella_vbus_timer(unsigned long data)
++{
++	struct ambarella_udc *udc = (struct ambarella_udc *)data;
++	enum usb_device_state state;
++	u32 raw_status, connected, suspended;
++
++	suspended = (amba_readl(USB_DEV_STS_REG) & USB_DEV_SUSP_STS);
++	raw_status = amba_readl(AHB_SCRATCHPAD_REG(0x04));
++	connected = !!(raw_status & (1 << 26));
++
++	if (suspended)
++		usb_gadget_set_state(&udc->gadget, USB_STATE_SUSPENDED);
++
++	if (udc->vbus_status != connected) {
++		state = connected ? USB_STATE_ATTACHED : USB_STATE_NOTATTACHED;
++		usb_gadget_set_state(&udc->gadget, state);
++		udc->vbus_status = connected;
++		schedule_work(&udc->uevent_work);
++		if (udc->driver != NULL)
++			ambarella_udc_vbus_session(&udc->gadget, udc->vbus_status);
++	}
++
++	mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
++}
++
++static void ambarella_stop_activity(struct ambarella_udc *udc)
++{
++	struct usb_gadget_driver *driver = udc->driver;
++	struct ambarella_ep *ep;
++	u32  i;
++
++	/* Disable Tx and Rx DMA */
++	amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
++
++	if (udc->gadget.speed == USB_SPEED_UNKNOWN)
++		driver = NULL;
++	udc->gadget.speed = USB_SPEED_UNKNOWN;
++
++	for (i = 0; i < EP_NUM_MAX; i++) {
++		ep = &udc->ep[i];
++
++		if(ep->ep.desc == NULL && !IS_EP0(ep))
++			continue;
++
++		ambarella_set_ep_nak(ep);
++
++		ep->halted = 1;
++		ambarella_ep_nuke(ep, -ESHUTDOWN);
++	}
++	if (driver) {
++		spin_unlock(&udc->lock);
++		driver->disconnect(&udc->gadget);
++		spin_lock(&udc->lock);
++	}
++
++	ambarella_udc_reinit(udc);
++}
++
++static int ambarella_udc_ep_enable(struct usb_ep *_ep,
++				 const struct usb_endpoint_descriptor *desc)
++{
++	struct ambarella_udc	*udc;
++	struct ambarella_ep	*ep = to_ambarella_ep(_ep);
++	u32			max_packet, tmp, type, idx = 0;
++	unsigned long		flags;
++
++	/* Sanity check  */
++	if (!_ep || !desc || IS_EP0(ep)
++		|| desc->bDescriptorType != USB_DT_ENDPOINT) {
++		printk("%s ep %d is inval \n",__func__,ep->id);
++		return -EINVAL;
++	}
++	udc = ep->udc;
++	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
++		return -ESHUTDOWN;
++
++	max_packet = usb_endpoint_maxp(desc) & 0x7ff;
++
++	spin_lock_irqsave(&udc->lock, flags);
++	ep->ep.maxpacket = max_packet;
++	ep->ep.desc = desc;
++	ep->halted = 0;
++	ep->data_desc = NULL;
++	ep->last_data_desc = NULL;
++	ep->ctrl_sts_phase = 0;
++	ep->dma_going = 0;
++	ep->cancel_transfer = 0;
++	ep->frame_offset =  (1 << (desc->bInterval - 1));
++
++	if(ep->dir == USB_DIR_IN){
++		idx = ep->id;
++	} else {
++		idx = ep->id - CTRL_OUT_UDC_IDX;
++	}
++
++	/* setup CSR */
++	amba_clrbitsl(USB_UDC_REG(idx), 0x3fffffff);
++	tmp = (desc->bEndpointAddress & 0xf) << 0;
++	tmp |= (desc->bEndpointAddress >> 7) << 4;
++	tmp |= (desc->bmAttributes & 0x3) << 5;
++	tmp |= udc->cur_config << 7;
++	tmp |= udc->cur_intf << 11;
++	tmp |= udc->cur_alt << 15;
++	tmp |= max_packet << 19;
++	amba_setbitsl(USB_UDC_REG(idx), tmp);
++
++	type = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) << 4;
++	amba_writel(ep->ep_reg.ctrl_reg, type | USB_EP_SET_NAK);
++
++	if(ep->dir == USB_DIR_IN) {
++		/* NOTE: total IN fifo size must be less than 576 * 4B */
++		tmp = max_packet / 4;
++#if 0
++		if (IS_ISO_IN_EP(ep))
++			tmp *= max_packet > 1024 ? 1 : max_packet > 512 ? 2 : 3;
++		else
++#endif
++			tmp *= 2;
++		amba_writel(ep->ep_reg.buf_sz_reg, tmp);
++	}
++	amba_writel(ep->ep_reg.max_pkt_sz_reg, max_packet);
++
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	return 0;
++}
++
++static int ambarella_udc_ep_disable(struct usb_ep *_ep)
++{
++	struct ambarella_ep *ep = to_ambarella_ep(_ep);
++	unsigned long flags;
++
++	if (!_ep || !ep->ep.desc) {
++		dprintk(DEBUG_NORMAL, "%s not enabled\n",
++			_ep ? ep->ep.name : NULL);
++		return -EINVAL;
++	}
++
++	spin_lock_irqsave(&ep->udc->lock, flags);
++
++	ep->ep.desc = NULL;
++	ep->halted = 1;
++	ambarella_ep_nuke(ep, -ESHUTDOWN);
++
++	ambarella_set_ep_nak(ep);
++
++	if(ep->dir == USB_DIR_IN){
++		/* clear DMA poll demand bit */
++		amba_clrbitsl(ep->ep_reg.ctrl_reg, USB_EP_POLL_DEMAND);
++		/* clear status register */
++		amba_setbitsl(ep->ep_reg.sts_reg, USB_EP_IN_PKT);
++		/* flush the fifo */
++		amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_FLUSH);
++	}
++
++	/* disable irqs */
++	amba_setbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
++
++	spin_unlock_irqrestore(&ep->udc->lock, flags);
++
++	return 0;
++}
++
++
++static struct usb_request *
++ambarella_udc_alloc_request(struct usb_ep *_ep, gfp_t mem_flags)
++{
++	struct ambarella_request *req;
++
++	if (!_ep)
++		return NULL;
++
++	req = kzalloc (sizeof(struct ambarella_request), mem_flags);
++	if (!req)
++		return NULL;
++
++	req->req.dma = DMA_ADDR_INVALID;
++	INIT_LIST_HEAD (&req->queue);
++	req->desc_count = 0;
++
++	req->buf_aux = NULL;
++	req->dma_aux = DMA_ADDR_INVALID;
++	req->use_aux_buf = 0;
++
++	return &req->req;
++}
++
++
++static void
++ambarella_udc_free_request(struct usb_ep *_ep, struct usb_request *_req)
++{
++	struct ambarella_ep	*ep = to_ambarella_ep(_ep);
++	struct ambarella_request	*req = to_ambarella_req(_req);
++
++	if (!ep || !_req)
++		return;
++
++	if(req->desc_count > 0)
++		ambarella_free_descriptor(ep, req);
++
++	if (req->buf_aux) {
++		kfree(req->buf_aux);
++		req->buf_aux = NULL;
++	}
++
++	WARN_ON (!list_empty (&req->queue));
++	kfree(req);
++}
++
++
++static int ambarella_udc_queue(struct usb_ep *_ep, struct usb_request *_req,
++		gfp_t gfp_flags)
++{
++	struct ambarella_request	*req = NULL;
++	struct ambarella_ep	*ep = NULL;
++	struct ambarella_udc	*udc;
++	unsigned long flags;
++	int i;
++
++	if (unlikely (!_ep)) {
++		pr_err("%s: _ep is NULL\n", __func__);
++		return -EINVAL;
++	}
++
++	ep = to_ambarella_ep(_ep);
++	udc = ep->udc;
++
++	for(i = 0; i < EP_NUM_MAX; i++) {
++		struct ambarella_ep *endp;
++		endp = &udc->ep[i];
++
++		if (endp != NULL && endp->dma_going) //Check for any ongoing DMA
++			break;
++
++		//If no other onging DMA and the current req is for ISO, enable the DMA
++		if((i == EP_NUM_MAX - 1) && IS_ISO_IN_EP(ep)) {
++			amba_setbitsl(USB_DEV_CTRL_REG,
++				USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
++		}
++        }
++
++	if (unlikely (!ep->ep.desc && !IS_EP0(ep))) {
++		pr_err("%s: %s, invalid args\n", __func__, _ep->name);
++		return -EINVAL;
++	}
++
++	if( unlikely( !udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)){
++		dprintk(DEBUG_NORMAL, "%s: %01d %01d\n", _ep->name,
++			!udc->driver, udc->gadget.speed==USB_SPEED_UNKNOWN);
++		return -ESHUTDOWN;
++	}
++
++	if (unlikely(!_req )) {
++		pr_err("%s: %s, _req is NULL\n", __func__, _ep->name);
++		return -EINVAL;
++	}
++
++	req = to_ambarella_req(_req);
++	if (unlikely(!req->req.complete || !req->req.buf
++				|| !list_empty(&req->queue))) {
++		pr_err("%s: %s, %01d %01d %01d\n", __func__, _ep->name,
++			!_req->complete, !_req->buf, !list_empty(&req->queue));
++
++		return -EINVAL;
++	}
++
++	if(IS_EP0(ep) && (udc->auto_ack_0_pkt == 1)){
++		/* It's status stage in setup packet. And A2/A3 will
++		  * automatically send the zero-length packet to Host */
++		udc->auto_ack_0_pkt = 0;
++		req->req.actual = 0;
++		req->req.complete(&ep->ep, &req->req);
++		return 0;
++	}
++
++	/* check whether USB is suspended */
++	if(amba_readl(USB_DEV_STS_REG) & USB_DEV_SUSP_STS){
++		pr_err("%s: UDC is suspended!\n", __func__);
++		return -ESHUTDOWN;
++	}
++
++	if (unlikely((unsigned long)req->req.buf & 0x7)) {
++		req->use_aux_buf = 1;
++
++		if (req->buf_aux == NULL) {
++			req->buf_aux = kmalloc(UDC_DMA_MAXPACKET, GFP_ATOMIC);
++			if (req->buf_aux == NULL)
++				return -ENOMEM;
++		}
++
++		if (ep->dir == USB_DIR_IN)
++			memcpy(req->buf_aux, req->req.buf, req->req.length);
++	} else {
++		req->use_aux_buf = 0;
++	}
++
++	ambarella_map_dma_buffer(ep, req);
++
++	/* disable IRQ handler's bottom-half  */
++	spin_lock_irqsave(&udc->lock, flags);
++
++	_req->status = -EINPROGRESS;
++	_req->actual = 0;
++
++	ambarella_prepare_descriptor(ep, req, gfp_flags);
++
++	/* kickstart this i/o queue? */
++	//if (list_empty(&ep->queue) && !ep->halted) {
++	if (list_empty(&ep->queue)) {
++		/* when the data length in ctrl-out transfer is zero, we just
++		  * need to implement the STATUS-IN stage. But we don't
++		  * implement the case that the data length in ctrl-in transfer
++		  * is zero. */
++		if(req->req.length == 0) {
++			if(ep->id == CTRL_OUT) {
++				ambarella_udc_done(ep, req, 0);
++				/* told UDC the configuration is done, and to ack HOST */
++				//amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_CSR_DONE);
++				//udelay(150);
++				/* For STATUS-IN stage */
++				ambarella_clr_ep_nak(&udc->ep[CTRL_IN]);
++				/* Re-enable Rx DMA to receive next setup packet */
++				ambarella_set_rx_dma(ep, NULL);
++				ep->dma_going = 0;
++				goto finish;
++			} else if (ep->id == CTRL_IN) {
++				//printk("the data length of ctrl-in is zero\n");
++				//BUG();
++			}
++		}
++
++		if (ep->dir == USB_DIR_IN) {
++			/* no need to wait for IN-token for ISO transfer */
++#if 0
++			if (IS_ISO_IN_EP(ep)) {
++				amba_writel(ep->ep_reg.sts_reg, USB_EP_IN_PKT);
++				ambarella_set_tx_dma(ep, req);
++			}
++#endif
++			/* enable dma completion interrupt for current TX data */
++			amba_clrbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
++			ambarella_clr_ep_nak(ep);
++		} else {
++			ambarella_set_rx_dma(ep, req);
++		}
++	}
++
++	list_add_tail(&req->queue, &ep->queue);
++
++finish:
++	/* enable IRQ handler's bottom-half  */
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	return 0;
++}
++
++static int ambarella_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
++{
++	struct ambarella_ep *ep = to_ambarella_ep(_ep);
++	struct ambarella_request *req;
++	unsigned long flags;
++	unsigned halted;
++
++	if (!ep->udc->driver)
++		return -ESHUTDOWN;
++
++	if (!_ep || !_req)
++		return -EINVAL;
++
++	spin_lock_irqsave(&ep->udc->lock, flags);
++
++	/* make sure the request is actually queued on this endpoint */
++	list_for_each_entry (req, &ep->queue, queue) {
++		if (&req->req == _req)
++			break;
++	}
++	if (&req->req != _req) {
++		spin_unlock_irqrestore(&ep->udc->lock, flags);
++		return -EINVAL;
++	}
++
++	halted = ep->halted;
++	ep->halted = 1;
++
++	/* request in processing */
++	if((ep->data_desc == req->data_desc) && (ep->dma_going == 1)) {
++		if (ep->dir == USB_DIR_IN)
++			ep->cancel_transfer = 1;
++		else {
++			u32 tmp, desc_status;
++			/* stop potential receive DMA */
++			tmp = amba_readl(USB_DEV_CTRL_REG);
++			amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN);
++
++			/* cancel transfer later in ISR if descriptor was touched. */
++			desc_status = req->data_desc->status;
++			if (desc_status != USB_DMA_BUF_HOST_RDY)
++				ep->cancel_transfer = 1;
++
++			amba_writel(USB_DEV_CTRL_REG, tmp);
++		}
++	}
++
++	ambarella_udc_done(ep, req, -ECONNRESET);
++
++	ep->halted = halted;
++	spin_unlock_irqrestore(&ep->udc->lock, flags);
++
++	return 0;
++}
++
++/*
++ * ambarella_udc_set_halt
++ */
++static int ambarella_udc_set_halt(struct usb_ep *_ep, int value)
++{
++	struct ambarella_ep *ep = to_ambarella_ep(_ep);
++	unsigned long flags;
++
++	if (unlikely (!_ep || (!ep->ep.desc && !IS_EP0(ep)))) {
++		pr_err("%s: %s, -EINVAL 1\n", __func__,_ep->name);
++		return -EINVAL;
++	}
++	if (!ep->udc->driver || ep->udc->gadget.speed == USB_SPEED_UNKNOWN){
++		pr_err("%s: %s, -ESHUTDOWN\n", __func__, _ep->name);
++		return -ESHUTDOWN;
++	}
++	/* isochronous transfer never halts because there is no handshake
++	 * to report a halt condition */
++	if (ep->ep.desc /* not ep0 */ && IS_ISO_IN_EP(ep)) {
++		pr_err("%s: %s, -EINVAL 2\n", __func__, _ep->name);
++		return -EINVAL;
++	}
++
++	spin_lock_irqsave(&ep->udc->lock, flags);
++
++	/* set/clear, then synch memory views with the device */
++	if (value) { /* stall endpoint */
++		if (ep->dir == USB_DIR_IN) {
++			amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL | USB_EP_FLUSH);
++		} else {
++			int retry_count = 10000;
++			/* Wait Rx-FIFO to be empty */
++			while(!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)){
++				if (retry_count-- < 0) {
++					printk(KERN_ERR"[USB] stall_endpoint:failed");
++					break;
++				}
++			}
++			amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
++		}
++	} else { /* clear stall endpoint */
++		amba_clrbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
++	}
++
++	ep->halted = !!value;
++
++	spin_unlock_irqrestore(&ep->udc->lock, flags);
++
++	return 0;
++}
++
++
++static const struct usb_ep_ops ambarella_ep_ops = {
++	.enable		= ambarella_udc_ep_enable,
++	.disable	= ambarella_udc_ep_disable,
++
++	.alloc_request	= ambarella_udc_alloc_request,
++	.free_request	= ambarella_udc_free_request,
++
++	.queue		= ambarella_udc_queue,
++	.dequeue	= ambarella_udc_dequeue,
++
++	.set_halt	= ambarella_udc_set_halt,
++	/* fifo ops not implemented */
++};
++
++/*------------------------- usb_gadget_ops ----------------------------------*/
++
++
++static int ambarella_udc_get_frame(struct usb_gadget *_gadget)
++{
++	return (amba_readl(USB_DEV_STS_REG) >> 18) & 0x7ff;
++}
++
++
++static int ambarella_udc_wakeup(struct usb_gadget *_gadget)
++{
++	struct ambarella_udc *udc = to_ambarella_udc(_gadget);
++	u32 tmp;
++
++	tmp = amba_readl(USB_DEV_CFG_REG);
++	/* Remote wakeup feature not enabled by host */
++	if ((!udc->remote_wakeup_en) || (!(tmp & USB_DEV_REMOTE_WAKEUP_EN)))
++		return -ENOTSUPP;
++
++	tmp = amba_readl(USB_DEV_STS_REG);
++	/* not suspended? */
++	if (!(tmp & USB_DEV_SUSP_STS))
++		return 0;
++
++	/* trigger force resume */
++	amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_REMOTE_WAKEUP);
++
++	return 0;
++}
++
++static int ambarella_udc_set_pullup(struct ambarella_udc *udc, int is_on)
++{
++	if (is_on) {
++		ambarella_udc_enable(udc);
++		/* reconnect to host */
++		amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_SOFT_DISCON);
++	} else {
++		if (udc->gadget.speed != USB_SPEED_UNKNOWN)
++			ambarella_stop_activity(udc);
++		/* disconnect to host */
++		amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_SOFT_DISCON);
++		ambarella_udc_disable(udc);
++	}
++
++	return 0;
++}
++
++static int ambarella_udc_vbus_session(struct usb_gadget *gadget, int is_active)
++{
++	unsigned long flags;
++	struct ambarella_udc *udc = to_ambarella_udc(gadget);
++
++	spin_lock_irqsave(&udc->lock, flags);
++	if (udc->driver)
++		ambarella_udc_set_pullup(udc, is_active);
++	else
++		ambarella_udc_set_pullup(udc, 0);
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	return 0;
++}
++
++static int ambarella_udc_pullup(struct usb_gadget *gadget, int is_on)
++{
++	unsigned long	flags;
++	struct ambarella_udc *udc = to_ambarella_udc(gadget);
++
++	spin_lock_irqsave(&udc->lock, flags);
++	ambarella_udc_set_pullup(udc, is_on);
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	return 0;
++}
++
++static int ambarella_udc_start(struct usb_gadget *gadget,
++			struct usb_gadget_driver *driver)
++{
++	struct ambarella_udc *udc = to_ambarella_udc(gadget);
++	unsigned long flags;
++
++	spin_lock_irqsave(&udc->lock, flags);
++
++	/* Hook the driver */
++	driver->driver.bus = NULL;
++	udc->driver = driver;
++	/* Enable udc */
++	ambarella_udc_enable(udc);
++
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	return 0;
++}
++
++static int ambarella_udc_stop(struct usb_gadget *gadget,
++			struct usb_gadget_driver *driver)
++{
++	struct ambarella_udc *udc = to_ambarella_udc(gadget);
++	unsigned long flags;
++
++	spin_lock_irqsave(&udc->lock, flags);
++
++	ambarella_stop_activity(udc);
++	ambarella_udc_disable(udc);
++	udc->driver = NULL;
++
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	return 0;
++}
++
++static const struct usb_gadget_ops ambarella_ops = {
++	.get_frame		= ambarella_udc_get_frame,
++	.wakeup			= ambarella_udc_wakeup,
++	.pullup			= ambarella_udc_pullup,
++	.vbus_session		= ambarella_udc_vbus_session,
++	/*.set_selfpowered: Always selfpowered */
++	.udc_start		= ambarella_udc_start,
++	.udc_stop		= ambarella_udc_stop,
++};
++
++/*------------------------- gadget driver handling---------------------------*/
++
++/* Tears down device */
++static void ambarella_gadget_release(struct device *dev)
++{
++	struct ambarella_udc *udc = dev_get_drvdata(dev);
++	kfree(udc);
++}
++
++static void ambarella_init_gadget(struct ambarella_udc *udc,
++	struct platform_device *pdev)
++{
++	struct ambarella_ep *ep;
++	u32 i;
++
++	spin_lock_init (&udc->lock);
++
++	udc->gadget.ops = &ambarella_ops;
++	udc->gadget.name = gadget_name;
++	udc->gadget.max_speed = USB_SPEED_HIGH;
++	udc->gadget.ep0 = &udc->ep[CTRL_IN].ep;
++	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
++
++	/* set basic ep parameters */
++	for (i = 0; i < EP_NUM_MAX; i++) {
++		ep = &udc->ep[i];
++		ep->ep.name = amb_ep_string[i];
++		ep->id = i;
++		ep->ep.ops = &ambarella_ep_ops;
++		ep->ep.maxpacket = (unsigned short) ~0;
++
++		if (i < EP_IN_NUM) {
++			ep->dir = USB_DIR_IN;
++		} else {
++			ep->dir = USB_DIR_OUT;
++		}
++	}
++
++	udc->ep[CTRL_IN].ep.maxpacket = USB_EP_CTRL_MAX_PKT_SZ;
++	udc->ep[CTRL_OUT].ep.maxpacket = USB_EP_CTRL_MAX_PKT_SZ;
++
++	return;
++}
++
++static void ambarella_udc_enable(struct ambarella_udc *udc)
++{
++	if (udc->udc_is_enabled)
++		return;
++
++	udc->udc_is_enabled = 1;
++
++	/* Disable Tx and Rx DMA */
++	amba_clrbitsl(USB_DEV_CTRL_REG,
++		USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
++
++	/* flush all of dma fifo */
++	ambarella_udc_fifo_flush(udc);
++
++	/* initialize ep0 register */
++	init_ep0(udc);
++
++	/* enable ep0 interrupt. */
++	amba_clrbitsl(USB_DEV_EP_INTR_MSK_REG,
++		USB_DEV_MSK_EP0_IN | USB_DEV_MSK_EP0_OUT);
++
++	/* enable Tx and Rx DMA */
++	amba_setbitsl(USB_DEV_CTRL_REG,
++		USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
++
++	/* enable device interrupt:
++	 * Set_Configure, Set_Interface, Speed Enumerate Complete, Reset */
++	amba_clrbitsl(USB_DEV_INTR_MSK_REG,
++			USB_DEV_MSK_SET_CFG |
++			USB_DEV_MSK_SET_INTF |
++			USB_DEV_MSK_SPD_ENUM_CMPL |
++			USB_DEV_MSK_RESET);
++}
++
++static void ambarella_udc_disable(struct ambarella_udc *udc)
++{
++	/* Disable all interrupts and Clear the interrupt registers */
++	ambarella_disable_all_intr();
++
++	/* Disable Tx and Rx DMA */
++	amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
++
++	udc->gadget.speed = USB_SPEED_UNKNOWN;
++	udc->udc_is_enabled = 0;
++}
++
++
++/*
++ * ambarella_udc_reinit
++ */
++static void ambarella_udc_reinit(struct ambarella_udc *udc)
++{
++	u32 i;
++
++	/* device/ep0 records init */
++	INIT_LIST_HEAD (&udc->gadget.ep_list);
++	INIT_LIST_HEAD (&udc->gadget.ep0->ep_list);
++	udc->auto_ack_0_pkt = 0;
++	udc->remote_wakeup_en = 0;
++
++	for (i = 0; i < EP_NUM_MAX; i++) {
++		struct ambarella_ep *ep = &udc->ep[i];
++
++		if (!IS_EP0(ep))
++			list_add_tail (&ep->ep.ep_list, &udc->gadget.ep_list);
++
++		ep->udc = udc;
++		ep->halted = 0;
++		ep->data_desc = NULL;
++		ep->last_data_desc = NULL;
++		INIT_LIST_HEAD (&ep->queue);
++	}
++}
++
++static int ambarella_udc_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct ambarella_udc *udc;
++	struct resource *res;
++	struct usb_phy *phy;
++	int retval;
++
++	dev_info(&pdev->dev, "%s: version %s\n", gadget_name, DRIVER_VERSION);
++
++	udc = devm_kzalloc(&pdev->dev, sizeof(struct ambarella_udc), GFP_KERNEL);
++	if (!udc) {
++		dev_err(&pdev->dev, "failed to allocate memory\n");
++		return -ENOMEM;
++	}
++	udc->dev = &pdev->dev;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (res == NULL) {
++		dev_err(&pdev->dev, "no mem resource for base_reg!\n");
++		return -ENXIO;
++	}
++
++	udc->base_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (udc->base_reg == NULL) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++	if (res == NULL) {
++		dev_err(&pdev->dev, "no mem resource for reset_reg!\n");
++		return -ENXIO;
++	}
++
++	udc->reset_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++	if (udc->reset_reg == NULL) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	udc->irq = platform_get_irq(pdev, 0);
++	if (udc->irq < 0) {
++		dev_err(&pdev->dev, "no irq!\n");
++		return -ENODEV;
++	}
++
++	if (of_find_property(np, "amb,dma-addr-fix", NULL))
++		udc->dma_fix = 0xc0000000;
++	else
++		udc->dma_fix = 0;
++
++	/* get the PHY device */
++	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "amb,usbphy", 0);
++	if (IS_ERR(phy)) {
++		dev_err(&pdev->dev, "Can't get USB PHY %ld\n", PTR_ERR(phy));
++		return -ENXIO;
++	}
++
++	usb_phy_init(phy);
++	udc->phy = phy;
++
++	ambarella_udc_reset(udc->reset_reg, np);
++
++	udc->udc_is_enabled = 0;
++	udc->vbus_status = 0;
++
++	ambarella_init_gadget(udc, pdev);
++	ambarella_udc_reinit(udc);
++	ambarella_regaddr_map(udc);
++
++	/*initial usb hardware, and set soft disconnect */
++	ambarella_init_usb(udc);
++
++	/* DMA pool create */
++	udc->desc_dma_pool = dma_pool_create("desc_dma_pool", NULL,
++		sizeof(struct ambarella_data_desc), 16, 0);
++	if (!udc->desc_dma_pool) {
++		pr_err("%s: can't get descriptor dma pool\n", __func__);
++		return -ENOMEM;
++	}
++
++	udc->setup_buf = dma_pool_alloc(udc->desc_dma_pool, GFP_KERNEL,
++		&udc->setup_addr);
++	if(udc->setup_buf == NULL) {
++		printk(KERN_ERR "No memory to DMA\n");
++		retval = -ENOMEM;
++		goto err_out1;
++	}
++
++	retval = init_null_pkt_desc(udc);
++	if(retval){
++		goto err_out2;
++	}
++
++	/* irq setup after old hardware state is cleaned up */
++	retval = devm_request_irq(&pdev->dev, udc->irq, ambarella_udc_irq,
++				IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), udc);
++	if (retval != 0) {
++		pr_err("%s: cannot get irq %d\n", __func__, udc->irq);
++		goto err_out3;
++	}
++
++	setup_timer(&udc->vbus_timer,
++		ambarella_vbus_timer, (unsigned long)udc);
++	mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
++
++	udc->pre_state = USB_STATE_NOTATTACHED;
++	INIT_WORK(&udc->uevent_work, ambarella_uevent_work);
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++	udc->proc_file = proc_create_data(proc_node_name, 0,
++		NULL, &ambarella_udc_fops, udc);
++	if (udc->proc_file == NULL) {
++		retval = -ENOMEM;
++		goto err_out3;
++	}
++#endif
++
++	/* Register gadget driver */
++	retval = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
++					ambarella_gadget_release);
++	if (retval) {
++		goto err_out4;
++	}
++
++	platform_set_drvdata(pdev, udc);
++
++	return 0;
++
++err_out4:
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++	remove_debugfs_files();
++#endif
++err_out3:
++	dma_pool_free(udc->desc_dma_pool, udc->dummy_desc, udc->dummy_desc_addr);
++err_out2:
++	dma_pool_free(udc->desc_dma_pool, udc->setup_buf, udc->setup_addr);
++err_out1:
++	dma_pool_destroy(udc->desc_dma_pool);
++	return retval;
++}
++
++
++/*
++ * Name: ambarella_udc_remove
++ * Description:
++ *	Remove udc driver.
++ */
++static int ambarella_udc_remove(struct platform_device *pdev)
++{
++	struct ambarella_udc *udc = platform_get_drvdata(pdev);
++
++	usb_del_gadget_udc(&udc->gadget);
++	if (udc->driver)
++		return -EBUSY;
++
++	del_timer_sync(&udc->vbus_timer);
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++	remove_debugfs_files();
++#endif
++	dma_pool_free(udc->desc_dma_pool, udc->dummy_desc, udc->dummy_desc_addr);
++	dma_pool_free(udc->desc_dma_pool, udc->setup_buf, udc->setup_addr);
++	dma_pool_destroy(udc->desc_dma_pool);
++
++	return 0;
++}
++
++
++#ifdef CONFIG_PM
++static int ambarella_udc_suspend(struct platform_device *pdev, pm_message_t message)
++{
++	unsigned long flags;
++	int retval = 0;
++	struct ambarella_udc *udc;
++
++	udc = platform_get_drvdata(pdev);
++	udc->sys_suspended = 1;
++	disable_irq(udc->irq);
++
++	del_timer_sync(&udc->vbus_timer);
++
++	spin_lock_irqsave(&udc->lock, flags);
++	ambarella_udc_set_pullup(udc, 0);
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	udc->udc_is_enabled = 0;
++	udc->vbus_status = 0;
++
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++		__func__, retval, message.event);
++
++	return retval;
++}
++
++static int ambarella_udc_resume(struct platform_device *pdev)
++{
++	unsigned long flags;
++	int retval = 0;
++	struct ambarella_udc *udc;
++
++	udc = platform_get_drvdata(pdev);
++	udc->sys_suspended = 0;
++
++	/* Initial USB PLL */
++	usb_phy_init(udc->phy);
++	/* Reset USB */
++	ambarella_udc_reset(udc->reset_reg, pdev->dev.of_node);
++	/*initial usb hardware */
++	ambarella_init_usb(udc);
++
++	enable_irq(udc->irq);
++
++	spin_lock_irqsave(&udc->lock, flags);
++	ambarella_udc_set_pullup(udc, 1);
++	spin_unlock_irqrestore(&udc->lock, flags);
++
++	setup_timer(&udc->vbus_timer,
++		ambarella_vbus_timer, (unsigned long)udc);
++	mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, retval);
++
++	return retval;
++}
++#endif
++
++static const struct of_device_id ambarella_udc_dt_ids[] = {
++	{ .compatible = "ambarella,udc" },
++	{ /* sentinel */ }
++};
++
++MODULE_DEVICE_TABLE(of, ambarella_udc_dt_ids);
++
++static struct platform_driver ambarella_udc_driver = {
++	.driver		= {
++		.name	= "ambarella-udc",
++		.owner	= THIS_MODULE,
++		.of_match_table	= ambarella_udc_dt_ids,
++	},
++	.remove		= ambarella_udc_remove,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_udc_suspend,
++	.resume		= ambarella_udc_resume,
++#endif
++};
++
++module_platform_driver_probe(ambarella_udc_driver, ambarella_udc_probe);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_VERSION(DRIVER_VERSION);
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:ambarella-usbgadget");
++
+diff --git a/drivers/usb/gadget/ambarella_udc.h b/drivers/usb/gadget/ambarella_udc.h
+new file mode 100644
+index 00000000..fef8433f
+--- /dev/null
++++ b/drivers/usb/gadget/ambarella_udc.h
+@@ -0,0 +1,202 @@
++/*
++* linux/drivers/usb/gadget/ambarella_udc.h
++* driver for High/Full speed
++USB device controller on Ambarella processors
++*
++* History:
++*	2008/06/12 - [Cao Rongrong] created file
++*
++* Copyright (C) 2008 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the
++* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++* Boston, MA  02111-1307, USA.
++*/
++
++#ifndef _AMBARELLA_UDC_H
++#define _AMBARELLA_UDC_H
++
++#define CTRL_IN			0
++#define CTRL_OUT		16
++
++#define EP_IN_NUM		16
++#define EP_NUM_MAX		32
++
++#define CTRL_OUT_UDC_IDX	11
++
++#define ISO_MAX_PACKET		3
++
++#define IS_EP0(ep)		(ep->id == CTRL_IN || ep->id == CTRL_OUT)
++#define IS_ISO_IN_EP(ep)	(!IS_EP0(ep) && usb_endpoint_is_isoc_in(ep->ep.desc))
++
++#define UDC_DMA_MAXPACKET	65536
++
++#define VBUS_POLL_TIMEOUT	msecs_to_jiffies(500)
++
++//-------------------------------------
++// Structure definition
++//-------------------------------------
++// SETUP buffer descriptor
++struct ambarella_setup_desc {
++	u32 status;
++	u32 reserved;
++	u32 data0;
++	u32 data1;
++	u32 rsvd1;
++	u32 rsvd2;
++	u32 rsvd3;
++	u32 rsvd4;
++};
++
++// IN/OUT data descriptor
++struct ambarella_data_desc {
++	u32 status;
++	u32 reserved;
++	u32 data_ptr;
++	u32 next_desc_ptr;
++	u32 rsvd1;
++	u32 last_aux;		/* dma enginee may disturb the L bit in status
++				 * field, so we use this field as auxiliary to
++				 * mark the last descriptor */
++	dma_addr_t cur_desc_addr;	/* dma address for this descriptor */
++	struct ambarella_data_desc *next_desc_virt;
++};
++
++
++struct ambarella_ep_reg {
++	u32 ctrl_reg;
++	u32 sts_reg;
++	u32 buf_sz_reg;		// IN_EP: buf_sz_reg,     OUT_EP: pkt_frm_num_reg
++	u32 max_pkt_sz_reg;	// IN_EP: max_pkt_sz_reg,   OUT EP: buffer_size_max_pkt_sz_reg
++	u32 setup_buf_ptr_reg;	// Just for ep0
++	u32 dat_desc_ptr_reg;
++	//u32 rw_confirm;	// For slave-only mode
++};
++
++
++struct ambarella_request {
++	struct list_head	queue;		/* ep's requests */
++	struct usb_request	req;
++
++	int			desc_count;
++	int			active_desc_count;
++	dma_addr_t		data_desc_addr; /* data_desc Physical Address */
++	struct ambarella_data_desc 	*data_desc;
++
++	dma_addr_t		dma_aux;
++	void			*buf_aux;	/* If the original buffer of
++						 * usb_req is not 8-bytes
++						 * aligned, we use this buffer
++						 * instead */
++	unsigned		use_aux_buf : 1,
++				mapped : 1;
++};
++
++
++struct ambarella_ep {
++
++	struct list_head		queue;
++	struct ambarella_udc		*udc;
++	const struct usb_endpoint_descriptor *desc;
++	struct usb_ep			ep;
++	u8 				id;
++	u8 				dir;
++
++	struct ambarella_ep_reg		ep_reg;
++
++	struct ambarella_data_desc 	*data_desc;
++	struct ambarella_data_desc 	*last_data_desc;
++	dma_addr_t			data_desc_addr; /* data_desc Physical Address */
++
++	unsigned			halted : 1,
++					cancel_transfer : 1,
++					need_cnak : 1,
++					ctrl_sts_phase : 1,
++					dma_going : 1;
++
++	unsigned int frame_offset;  /* iso frame num offset */
++};
++
++struct ambarella_udc {
++	spinlock_t			lock;
++	struct device			*dev;
++	void __iomem			*base_reg;
++	void __iomem			*reset_reg;
++	int				irq;
++	struct usb_phy			*phy;
++
++	struct proc_dir_entry		*proc_file;
++	struct work_struct		uevent_work;
++	struct timer_list		vbus_timer;
++	enum usb_device_state		pre_state;
++
++	struct usb_gadget		gadget;
++	struct usb_gadget_driver	*driver;
++
++	struct dma_pool			*desc_dma_pool;
++
++	struct ambarella_ep		ep[EP_NUM_MAX];
++	u32				setup[2];
++	dma_addr_t			setup_addr;
++	struct ambarella_setup_desc	*setup_buf;
++	dma_addr_t			dummy_desc_addr;
++	struct ambarella_data_desc	*dummy_desc;
++
++	u16				cur_config;
++	u16				cur_intf;
++	u16				cur_alt;
++
++	unsigned 			auto_ack_0_pkt : 1,
++					remote_wakeup_en  : 1,
++					host_suspended : 1,
++					sys_suspended : 1,
++					reset_by_host : 1,
++					vbus_status : 1,
++					udc_is_enabled : 1;
++
++	/* dma_fix is only used for S2 chip, due to its DMA engine fault */
++	u32				dma_fix;
++};
++
++/* Function Declaration  */
++static void ambarella_udc_done(struct ambarella_ep *ep,
++		struct ambarella_request *req, int status);
++
++static void ambarella_set_tx_dma(struct ambarella_ep *ep,
++	struct ambarella_request * req, int fix);
++
++static void ambarella_set_rx_dma(struct ambarella_ep *ep,
++	struct ambarella_request * req);
++
++static void ambarella_udc_reinit(struct ambarella_udc *udc);
++
++static int ambarella_udc_set_halt(struct usb_ep *_ep, int value);
++
++static void ambarella_ep_nuke(struct ambarella_ep *ep, int status);
++
++static void ambarella_stop_activity(struct ambarella_udc *udc);
++
++static void ambarella_udc_enable(struct ambarella_udc *udc);
++
++static void ambarella_udc_disable(struct ambarella_udc *udc);
++
++static int ambarella_udc_vbus_session(struct usb_gadget *gadget, int is_active);
++
++static int ambarella_udc_set_pullup(struct ambarella_udc *udc, int is_on);
++
++static int ambarella_udc_get_frame(struct usb_gadget *_gadget);
++
++#endif
++
+diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
+index bcd04bc6..e39d2ddb 100644
+--- a/drivers/usb/gadget/gadget_chips.h
++++ b/drivers/usb/gadget/gadget_chips.h
+@@ -33,6 +33,7 @@
+ #define gadget_is_net2280(g)		(!strcmp("net2280", (g)->name))
+ #define gadget_is_pxa(g)		(!strcmp("pxa25x_udc", (g)->name))
+ #define gadget_is_pxa27x(g)		(!strcmp("pxa27x_udc", (g)->name))
++#define gadget_is_ambarella(g)	(!strcmp("ambarella_udc", (g)->name))
+ 
+ /**
+  * gadget_supports_altsettings - return true if altsettings work
+diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
+index 1f5f978d..9d4f2658 100644
+--- a/drivers/usb/gadget/serial.c
++++ b/drivers/usb/gadget/serial.c
+@@ -246,7 +246,7 @@ static int __init init(void)
+ 	 */
+ 	if (use_acm) {
+ 		serial_config_driver.label = "CDC ACM config";
+-		serial_config_driver.bConfigurationValue = 2;
++		serial_config_driver.bConfigurationValue = 1;
+ 		device_desc.bDeviceClass = USB_CLASS_COMM;
+ 		device_desc.idProduct =
+ 				cpu_to_le16(GS_CDC_PRODUCT_ID);
+@@ -258,7 +258,7 @@ static int __init init(void)
+ 			cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
+ 	} else {
+ 		serial_config_driver.label = "Generic Serial config";
+-		serial_config_driver.bConfigurationValue = 1;
++		serial_config_driver.bConfigurationValue = 2;
+ 		device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+ 		device_desc.idProduct =
+ 				cpu_to_le16(GS_PRODUCT_ID);
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 4b76124c..47e97fe3 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -239,7 +239,8 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
+ 	 * but on at least one, checksumming fails otherwise.  Note:
+ 	 * RNDIS headers involve variable numbers of LE32 values.
+ 	 */
+-	skb_reserve(skb, NET_IP_ALIGN);
++	if (!gadget_is_ambarella(dev->gadget))
++		skb_reserve(skb, NET_IP_ALIGN);
+ 
+ 	req->buf = skb->data;
+ 	req->length = size;
+@@ -563,6 +564,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
+ 
+ 		length = skb->len;
+ 	}
++
+ 	req->buf = skb->data;
+ 	req->context = skb;
+ 	req->complete = tx_complete;
+diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
+index 817a26cb..f4a04cfc 100644
+--- a/drivers/usb/gadget/udc-core.c
++++ b/drivers/usb/gadget/udc-core.c
+@@ -23,6 +23,7 @@
+ #include <linux/list.h>
+ #include <linux/err.h>
+ #include <linux/dma-mapping.h>
++#include <linux/workqueue.h>
+ 
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+@@ -101,11 +102,18 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
+ 
+ /* ------------------------------------------------------------------------- */
+ 
++static void usb_gadget_state_work(struct work_struct *work)
++{
++	struct usb_gadget	*gadget = work_to_gadget(work);
++
++	sysfs_notify(&gadget->dev.kobj, NULL, "status");
++}
++
+ void usb_gadget_set_state(struct usb_gadget *gadget,
+ 		enum usb_device_state state)
+ {
+ 	gadget->state = state;
+-	sysfs_notify(&gadget->dev.kobj, NULL, "state");
++	schedule_work(&gadget->work);
+ }
+ EXPORT_SYMBOL_GPL(usb_gadget_set_state);
+ 
+@@ -192,6 +200,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
+ 		goto err1;
+ 
+ 	dev_set_name(&gadget->dev, "gadget");
++	INIT_WORK(&gadget->work, usb_gadget_state_work);
+ 	gadget->dev.parent = parent;
+ 
+ 	dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask);
+@@ -309,6 +318,7 @@ found:
+ 		usb_gadget_remove_driver(udc);
+ 
+ 	kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
++	flush_work(&gadget->work);
+ 	device_unregister(&udc->dev);
+ 	device_unregister(&gadget->dev);
+ }
+diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
+index de456a5a..509469de 100644
+--- a/drivers/usb/gadget/uvc_queue.c
++++ b/drivers/usb/gadget/uvc_queue.c
+@@ -120,6 +120,7 @@ static int uvc_queue_init(struct uvc_video_queue *queue,
+ 	queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
+ 	queue->queue.ops = &uvc_queue_qops;
+ 	queue->queue.mem_ops = &vb2_vmalloc_memops;
++	queue->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ 	ret = vb2_queue_init(&queue->queue);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 344d5e2f..8424c952 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -121,6 +121,14 @@ config USB_EHCI_BIG_ENDIAN_MMIO
+ config USB_EHCI_BIG_ENDIAN_DESC
+ 	bool
+ 
++config USB_EHCI_AMBARELLA
++	tristate "Ambarella EHCI support"
++	depends on USB_EHCI_HCD && ARCH_AMBARELLA
++	---help---
++	  This driver enables support for EHCI found in Ambarella SoCs.
++	  Root Hub has NO inbuilt TT.
++	  You will need to enable USB_PHY and Ambarella PHY driver as well.
++
+ config XPS_USB_HCD_XILINX
+ 	bool "Use Xilinx usb host EHCI controller core"
+ 	depends on (PPC32 || MICROBLAZE)
+@@ -365,6 +373,14 @@ config USB_OHCI_HCD
+ 
+ if USB_OHCI_HCD
+ 
++config USB_OHCI_AMBARELLA
++	boolean "Ambarella OHCI support"
++	depends on ARCH_AMBARELLA
++	---help---
++	  This driver enables support for OHCI found in Ambarella SoCs.
++	  Root Hub has NO inbuilt TT.
++	  You will need to enable USB_PHY and Ambarella PHY driver as well.
++
+ config USB_OHCI_HCD_OMAP1
+ 	bool "OHCI support for OMAP1/2 chips"
+ 	depends on ARCH_OMAP1
+diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
+index 4fb73c15..46a4cb86 100644
+--- a/drivers/usb/host/Makefile
++++ b/drivers/usb/host/Makefile
+@@ -33,6 +33,7 @@ obj-$(CONFIG_USB_EHCI_HCD_SPEAR)	+= ehci-spear.o
+ obj-$(CONFIG_USB_EHCI_S5P)	+= ehci-s5p.o
+ obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
+ obj-$(CONFIG_USB_EHCI_MSM)	+= ehci-msm.o
++obj-$(CONFIG_USB_EHCI_AMBARELLA) += ehci-ambarella.o
+ 
+ obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
+ obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
+diff --git a/drivers/usb/host/ehci-ambarella.c b/drivers/usb/host/ehci-ambarella.c
+new file mode 100644
+index 00000000..affec7eb
+--- /dev/null
++++ b/drivers/usb/host/ehci-ambarella.c
+@@ -0,0 +1,247 @@
++/*
++* linux/drivers/usb/host/ehci-ambarella.c
++* driver for High speed (USB2.0) USB host controller on Ambarella processors
++*
++* History:
++*	2010/08/11 - [Cao Rongrong] created file
++*
++* Copyright (C) 2008 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the
++* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++* Boston, MA  02111-1307, USA.
++*/
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/usb/ulpi.h>
++#include <linux/pm_runtime.h>
++#include <linux/gpio.h>
++#include <linux/clk.h>
++#include <linux/usb.h>
++#include <linux/usb/hcd.h>
++#include <linux/of.h>
++#include <linux/dma-mapping.h>
++#include <mach/hardware.h>
++#include <plat/rct.h>
++
++#include "ehci.h"
++
++#define DRIVER_DESC "AMBARELLA-EHCI Host Controller driver"
++static const char hcd_name[] = "ehci-ambarella";
++
++
++struct ehci_ambarella_priv {
++	struct usb_phy *phy;
++	u32 nports;
++};
++
++static struct hc_driver __read_mostly ehci_ambarella_hc_driver;
++
++static int ambarella_ehci_setup(struct usb_hcd *hcd)
++{
++	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++	struct ehci_ambarella_priv *priv;
++	int ret = 0;
++
++	/* registers start at offset 0x0 */
++	ehci->caps = hcd->regs;
++
++	ret = ehci_setup(hcd);
++	if (ret)
++		return ret;
++
++	/* EHCI will still detect 2 ports even though usb port1 is configured
++	 * as device port, so we fake the port number manually and report
++	 * it to EHCI.*/
++	priv = (struct ehci_ambarella_priv *)hcd_to_ehci(hcd)->priv;
++	ehci->hcs_params &= ~0xf;
++	ehci->hcs_params |= priv->nports;
++
++	return 0;
++}
++
++static const struct ehci_driver_overrides ehci_ambarella_overrides __initdata = {
++	.reset = ambarella_ehci_setup,
++	.extra_priv_size = sizeof(struct ehci_ambarella_priv),
++};
++
++static int ehci_ambarella_drv_probe(struct platform_device *pdev)
++{
++	struct ehci_ambarella_priv *priv;
++	struct usb_hcd *hcd;
++	struct usb_phy *phy;
++	struct resource *res;
++	int irq, ret;
++
++	if (usb_disabled())
++		return -ENODEV;
++
++	/* Right now device-tree probed devices don't get dma_mask set.
++	 * Since shared usb code relies on it, set it here for now.
++	 * Once we have dma capability bindings this can go away.
++	 */
++	if (!pdev->dev.dma_mask)
++		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++	if (!pdev->dev.coherent_dma_mask)
++		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
++
++	hcd = usb_create_hcd(&ehci_ambarella_hc_driver, &pdev->dev, "AmbUSB");
++	if (!hcd)
++		return -ENOMEM;
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
++		ret = irq;
++		goto amb_ehci_err;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "Unable to get memory resource\n");
++		ret = -ENODEV;
++		goto amb_ehci_err;
++	}
++
++	hcd->rsrc_start = res->start;
++	hcd->rsrc_len = resource_size(res);
++	hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
++	if (!hcd->regs) {
++		dev_err(&pdev->dev, "ioremap failed\n");
++		ret = -ENOMEM;
++		goto amb_ehci_err;
++	}
++
++	priv = (struct ehci_ambarella_priv *)hcd_to_ehci(hcd)->priv;
++
++	/* get the PHY device */
++	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "amb,usbphy", 0);
++	if (IS_ERR(phy)) {
++		ret = PTR_ERR(phy);
++		dev_err(&pdev->dev, "Can't get USB PHY %d\n", ret);
++		goto amb_ehci_err;
++	}
++
++	ret = of_property_read_u32(phy->dev->of_node,
++				"amb,host-phy-num", &priv->nports);
++	if (ret < 0){
++		dev_err(&pdev->dev, "Can't get host phy num %d\n", ret);
++		goto amb_ehci_err;
++	}
++
++	usb_phy_init(phy);
++	priv->phy = phy;
++
++	ret = usb_add_hcd(hcd, irq, 0);
++	if (ret < 0)
++		goto amb_ehci_err;
++
++	platform_set_drvdata(pdev, hcd);
++
++	return 0;
++
++amb_ehci_err:
++	usb_put_hcd(hcd);
++	return ret;
++}
++
++static int ehci_ambarella_drv_remove(struct platform_device *pdev)
++{
++	struct usb_hcd *hcd = platform_get_drvdata(pdev);
++
++	usb_remove_hcd(hcd);
++	usb_put_hcd(hcd);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++
++static int ehci_ambarella_drv_resume(struct device *dev)
++{
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++	struct ehci_ambarella_priv *priv;
++
++	priv = (struct ehci_ambarella_priv *)hcd_to_ehci(hcd)->priv;
++
++	usb_phy_init(priv->phy);
++
++	ehci_resume(hcd, false);
++
++	return 0;
++}
++
++static int ehci_ambarella_drv_suspend(struct device *dev)
++{
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++	bool do_wakeup = device_may_wakeup(dev);
++
++	return ehci_suspend(hcd, do_wakeup);;
++}
++
++static struct dev_pm_ops ambarella_ehci_pmops = {
++	.suspend	= ehci_ambarella_drv_suspend,
++	.resume		= ehci_ambarella_drv_resume,
++	.freeze		= ehci_ambarella_drv_suspend,
++	.thaw		= ehci_ambarella_drv_resume,
++};
++
++#define AMBARELLA_EHCI_PMOPS &ambarella_ehci_pmops
++
++#else
++#define AMBARELLA_EHCI_PMOPS NULL
++#endif
++
++
++static struct of_device_id ambarella_ehci_dt_ids[] = {
++	{ .compatible = "ambarella,ehci", },
++	{ },
++};
++
++static struct platform_driver ehci_hcd_ambarella_driver = {
++	.probe		= ehci_ambarella_drv_probe,
++	.remove		= ehci_ambarella_drv_remove,
++	.shutdown	= usb_hcd_platform_shutdown,
++	.driver = {
++		.name	= "ambarella-ehci",
++		.of_match_table = of_match_ptr(ambarella_ehci_dt_ids),
++		.pm	= AMBARELLA_EHCI_PMOPS,
++	}
++};
++
++static int __init ehci_ambarella_init(void)
++{
++	if (usb_disabled())
++		return -ENODEV;
++
++	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
++
++	ehci_init_driver(&ehci_ambarella_hc_driver, &ehci_ambarella_overrides);
++	return platform_driver_register(&ehci_hcd_ambarella_driver);
++}
++module_init(ehci_ambarella_init);
++
++static void __exit ehci_ambarella_cleanup(void)
++{
++	platform_driver_unregister(&ehci_hcd_ambarella_driver);
++}
++module_exit(ehci_ambarella_cleanup);
++
++MODULE_ALIAS("platform:ambarella-ehci");
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
+index ca6289b4..7ddf38f5 100644
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -694,6 +694,142 @@ ehci_hub_descriptor (
+ 	desc->wHubCharacteristics = cpu_to_le16(temp);
+ }
+ 
++/*-------------------------------------------------------------------------*/
++#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
++
++static void usb_ehset_completion(struct urb *urb)
++{
++	struct completion  *done = urb->context;
++
++	complete(done);
++}
++static int submit_single_step_set_feature(
++	struct usb_hcd	*hcd,
++	struct urb	*urb,
++	int		is_setup
++);
++
++/*
++ * Allocate and initialize a control URB. This request will be used by the
++ * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
++ * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
++ * Return NULL if failed.
++ */
++static struct urb *request_single_step_set_feature_urb(
++	struct usb_device	*udev,
++	void			*dr,
++	void			*buf,
++	struct completion	*done
++) {
++	struct urb *urb;
++	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
++	struct usb_host_endpoint *ep;
++
++	urb = usb_alloc_urb(0, GFP_KERNEL);
++	if (!urb)
++		return NULL;
++
++	urb->pipe = usb_rcvctrlpipe(udev, 0);
++	ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
++				[usb_pipeendpoint(urb->pipe)];
++	if (!ep) {
++		usb_free_urb(urb);
++		return NULL;
++	}
++
++	urb->ep = ep;
++	urb->dev = udev;
++	urb->setup_packet = (void *)dr;
++	urb->transfer_buffer = buf;
++	urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
++	urb->complete = usb_ehset_completion;
++	urb->status = -EINPROGRESS;
++	urb->actual_length = 0;
++	urb->transfer_flags = URB_DIR_IN;
++	usb_get_urb(urb);
++	atomic_inc(&urb->use_count);
++	atomic_inc(&urb->dev->urbnum);
++	urb->setup_dma = dma_map_single(
++			hcd->self.controller,
++			urb->setup_packet,
++			sizeof(struct usb_ctrlrequest),
++			DMA_TO_DEVICE);
++	urb->transfer_dma = dma_map_single(
++			hcd->self.controller,
++			urb->transfer_buffer,
++			urb->transfer_buffer_length,
++			DMA_FROM_DEVICE);
++	urb->context = done;
++	return urb;
++}
++
++static int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
++{
++	int retval = -ENOMEM;
++	struct usb_ctrlrequest *dr;
++	struct urb *urb;
++	struct usb_device *udev;
++	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++	struct usb_device_descriptor *buf;
++	DECLARE_COMPLETION_ONSTACK(done);
++
++	/* Obtain udev of the rhub's child port */
++	udev = usb_hub_find_child(hcd->self.root_hub, port);
++	if (!udev) {
++		ehci_err(ehci, "No device attached to the RootHub\n");
++		return -ENODEV;
++	}
++	buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++
++	dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
++	if (!dr) {
++		kfree(buf);
++		return -ENOMEM;
++	}
++
++	/* Fill Setup packet for GetDescriptor */
++	dr->bRequestType = USB_DIR_IN;
++	dr->bRequest = USB_REQ_GET_DESCRIPTOR;
++	dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
++	dr->wIndex = 0;
++	dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
++	urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
++	if (!urb)
++		goto cleanup;
++
++	/* Submit just the SETUP stage */
++	retval = submit_single_step_set_feature(hcd, urb, 1);
++	if (retval)
++		goto out1;
++	if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
++		usb_kill_urb(urb);
++		retval = -ETIMEDOUT;
++		ehci_err(ehci, "%s SETUP stage timed out on ep0\n", __func__);
++		goto out1;
++	}
++	msleep(15 * 1000);
++
++	/* Complete remaining DATA and STATUS stages using the same URB */
++	urb->status = -EINPROGRESS;
++	usb_get_urb(urb);
++	atomic_inc(&urb->use_count);
++	atomic_inc(&urb->dev->urbnum);
++	retval = submit_single_step_set_feature(hcd, urb, 0);
++	if (!retval && !wait_for_completion_timeout(&done,
++						msecs_to_jiffies(2000))) {
++		usb_kill_urb(urb);
++		retval = -ETIMEDOUT;
++		ehci_err(ehci, "%s IN stage timed out on ep0\n", __func__);
++	}
++out1:
++	usb_free_urb(urb);
++cleanup:
++	kfree(dr);
++	kfree(buf);
++	return retval;
++}
+ /*-------------------------------------------------------------------------*/
+ 
+ static int ehci_hub_control (
+@@ -1076,7 +1212,13 @@ static int ehci_hub_control (
+ 		 * about the EHCI-specific stuff.
+ 		 */
+ 		case USB_PORT_FEAT_TEST:
+-			if (!selector || selector > 5)
++			if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) {
++				spin_unlock_irqrestore(&ehci->lock, flags);
++				retval = ehset_single_step_set_feature(hcd,
++									wIndex);
++				spin_lock_irqsave(&ehci->lock, flags);
++				break;
++			} else if (!selector || selector > 5)
+ 				goto error;
+ 			spin_unlock_irqrestore(&ehci->lock, flags);
+ 			ehci_quiesce(ehci);
+diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
+index d34b399b..702a0e93 100644
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -1143,6 +1143,107 @@ submit_async (
+ 	return rc;
+ }
+ 
++/*-------------------------------------------------------------------------*/
++/*
++ * This function creates the qtds and submits them for the
++ * SINGLE_STEP_SET_FEATURE Test.
++ * This is done in two parts: first SETUP req for GetDesc is sent then
++ * 15 seconds later, the IN stage for GetDesc starts to req data from dev
++ *
++ * is_setup : i/p arguement decides which of the two stage needs to be
++ * performed; TRUE - SETUP and FALSE - IN+STATUS
++ * Returns 0 if success
++ */
++static int submit_single_step_set_feature(
++	struct usb_hcd  *hcd,
++	struct urb      *urb,
++	int             is_setup
++) {
++	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
++	struct list_head	qtd_list;
++	struct list_head	*head;
++
++	struct ehci_qtd		*qtd, *qtd_prev;
++	dma_addr_t		buf;
++	int			len, maxpacket;
++	u32			token;
++
++	INIT_LIST_HEAD(&qtd_list);
++	head = &qtd_list;
++
++	/* URBs map to sequences of QTDs:  one logical transaction */
++	qtd = ehci_qtd_alloc(ehci, GFP_KERNEL);
++	if (unlikely(!qtd))
++		return -1;
++	list_add_tail(&qtd->qtd_list, head);
++	qtd->urb = urb;
++
++	token = QTD_STS_ACTIVE;
++	token |= (EHCI_TUNE_CERR << 10);
++
++	len = urb->transfer_buffer_length;
++	/*
++	 * Check if the request is to perform just the SETUP stage (getDesc)
++	 * as in SINGLE_STEP_SET_FEATURE test, DATA stage (IN) happens
++	 * 15 secs after the setup
++	 */
++	if (is_setup) {
++		/* SETUP pid */
++		qtd_fill(ehci, qtd, urb->setup_dma,
++				sizeof(struct usb_ctrlrequest),
++				token | (2 /* "setup" */ << 8), 8);
++
++		submit_async(ehci, urb, &qtd_list, GFP_ATOMIC);
++		return 0; /*Return now; we shall come back after 15 seconds*/
++	}
++
++	/*
++	 * IN: data transfer stage:  buffer setup : start the IN txn phase for
++	 * the get_Desc SETUP which was sent 15seconds back
++	 */
++	token ^= QTD_TOGGLE;   /*We need to start IN with DATA-1 Pid-sequence*/
++	buf = urb->transfer_dma;
++
++	token |= (1 /* "in" */ << 8);  /*This is IN stage*/
++
++	maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, 0));
++
++	qtd_fill(ehci, qtd, buf, len, token, maxpacket);
++
++	/*
++	 * Our IN phase shall always be a short read; so keep the queue running
++	 * and let it advance to the next qtd which zero length OUT status
++	 */
++	qtd->hw_alt_next = EHCI_LIST_END(ehci);
++
++	/* STATUS stage for GetDesc control request */
++	token ^= 0x0100;        /* "in" <--> "out"  */
++	token |= QTD_TOGGLE;    /* force DATA1 */
++
++	qtd_prev = qtd;
++	qtd = ehci_qtd_alloc(ehci, GFP_ATOMIC);
++	if (unlikely(!qtd))
++		goto cleanup;
++	qtd->urb = urb;
++	qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
++	list_add_tail(&qtd->qtd_list, head);
++
++	/* dont fill any data in such packets */
++	qtd_fill(ehci, qtd, 0, 0, token, 0);
++
++	/* by default, enable interrupt on urb completion */
++	if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
++		qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
++
++	submit_async(ehci, urb, &qtd_list, GFP_KERNEL);
++
++	return 0;
++
++cleanup:
++	qtd_list_free(ehci, urb, head);
++	return -1;
++}
++
+ /*-------------------------------------------------------------------------*/
+ 
+ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+index 03322d9c..642b4664 100644
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -664,6 +664,13 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
+ #define writel_be(val, addr)	__raw_writel(val, (__force unsigned *)addr)
+ #endif
+ 
++#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
++#undef writel
++#undef readl
++#define writel(v, p)		amba_writel(p, v)
++#define readl(p)		amba_readl(p)
++#endif
++
+ static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
+ 		__u32 __iomem * regs)
+ {
+diff --git a/drivers/usb/host/ohci-ambarella.c b/drivers/usb/host/ohci-ambarella.c
+new file mode 100644
+index 00000000..bc5b27d1
+--- /dev/null
++++ b/drivers/usb/host/ohci-ambarella.c
+@@ -0,0 +1,264 @@
++/*
++* linux/drivers/usb/host/ohci-ambarella.c
++* driver for Full speed (USB1.1) USB host controller on Ambarella processors
++*
++* History:
++*	2010/08/11 - [Cao Rongrong] created file
++*
++* Copyright (C) 2008 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the
++* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++* Boston, MA  02111-1307, USA.
++*/
++
++#include <linux/platform_device.h>
++#include <linux/of.h>
++#include <mach/hardware.h>
++
++extern int usb_disabled(void);
++
++struct ohci_ambarella {
++	struct ohci_hcd ohci;
++	struct usb_phy *phy;
++	u32 nports;
++};
++
++
++static struct ohci_ambarella *hcd_to_ohci_ambarella(struct usb_hcd *hcd)
++{
++	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++	return container_of(ohci, struct ohci_ambarella, ohci);
++}
++
++static int ohci_ambarella_start(struct usb_hcd *hcd)
++{
++	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
++	struct ohci_ambarella *amb_ohci = hcd_to_ohci_ambarella(hcd);
++	int ret;
++
++	/* OHCI will still detect 2 ports even though usb port1 is configured
++	 * as device port, so we fake the port number manually and report
++	 * it to OHCI.*/
++	ohci->num_ports = amb_ohci->nports;
++
++	if ((ret = ohci_init(ohci)) < 0)
++		return ret;
++
++	if ((ret = ohci_run(ohci)) < 0) {
++		dev_err(hcd->self.controller, "can't start\n");
++		ohci_stop(hcd);
++		return ret;
++	}
++
++	return 0;
++}
++
++static const struct hc_driver ohci_ambarella_hc_driver = {
++	.description =		hcd_name,
++	.product_desc =		"Ambarella OHCI",
++	.hcd_priv_size =	sizeof(struct ohci_ambarella),
++
++	/*
++	 * generic hardware linkage
++	 */
++	.irq =			ohci_irq,
++	.flags =		HCD_USB11 | HCD_MEMORY,
++
++	/*
++	 * basic lifecycle operations
++	 */
++	.start =		ohci_ambarella_start,
++	.stop =			ohci_stop,
++	.shutdown =		ohci_shutdown,
++
++	/*
++	 * managing i/o requests and associated device resources
++	 */
++	.urb_enqueue =		ohci_urb_enqueue,
++	.urb_dequeue =		ohci_urb_dequeue,
++	.endpoint_disable =	ohci_endpoint_disable,
++
++	/*
++	 * scheduling support
++	 */
++	.get_frame_number =	ohci_get_frame,
++
++	/*
++	 * root hub support
++	 */
++	.hub_status_data =	ohci_hub_status_data,
++	.hub_control =		ohci_hub_control,
++#ifdef	CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
++#endif
++	.start_port_reset =	ohci_start_port_reset,
++};
++
++static int ohci_hcd_ambarella_drv_probe(struct platform_device *pdev)
++{
++	struct ohci_ambarella *amb_ohci;
++	struct usb_hcd *hcd;
++	struct resource *res;
++	struct usb_phy *phy;
++	int irq, ret;
++
++	if (usb_disabled())
++		return -ENODEV;
++
++	/* Right now device-tree probed devices don't get dma_mask set.
++	 * Since shared usb code relies on it, set it here for now.
++	 * Once we have dma capability bindings this can go away.
++	 */
++	if (!pdev->dev.dma_mask)
++		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++	if (!pdev->dev.coherent_dma_mask)
++		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
++
++	hcd = usb_create_hcd(&ohci_ambarella_hc_driver, &pdev->dev, "AmbUSB");
++	if (!hcd)
++		return -ENOMEM;
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
++		ret = irq;
++		goto amb_ohci_err;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "Unable to get memory resource\n");
++		ret = -ENODEV;
++		goto amb_ohci_err;
++	}
++
++	hcd->rsrc_start = res->start;
++	hcd->rsrc_len = resource_size(res);
++	hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
++	if (!hcd->regs) {
++		dev_err(&pdev->dev, "ioremap failed\n");
++		ret = -ENOMEM;
++		goto amb_ohci_err;
++	}
++
++	amb_ohci = hcd_to_ohci_ambarella(hcd);
++
++	/* get the PHY device */
++	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "amb,usbphy", 0);
++	if (IS_ERR(phy)) {
++		ret = PTR_ERR(phy);
++		dev_err(&pdev->dev, "Can't get USB PHY %d\n", ret);
++		goto amb_ohci_err;
++	}
++
++	ret = of_property_read_u32(phy->dev->of_node,
++				"amb,host-phy-num", &amb_ohci->nports);
++	if (ret < 0){
++		dev_err(&pdev->dev, "Can't get host phy num %d\n", ret);
++		goto amb_ohci_err;
++	}
++
++	usb_phy_init(phy);
++	amb_ohci->phy = phy;
++
++	ohci_hcd_init(hcd_to_ohci(hcd));
++
++	ret = usb_add_hcd(hcd, irq, IRQF_TRIGGER_HIGH);
++	if (ret < 0)
++		goto amb_ohci_err;
++
++	platform_set_drvdata(pdev, hcd);
++
++	return 0;
++
++amb_ohci_err:
++	usb_put_hcd(hcd);
++	return ret;
++}
++
++static int ohci_hcd_ambarella_drv_remove(struct platform_device *pdev)
++{
++	struct usb_hcd *hcd = platform_get_drvdata(pdev);
++
++	usb_remove_hcd(hcd);
++	usb_put_hcd(hcd);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++
++/* Maybe just need to suspend/resume controller via HAL function. */
++static int ohci_hcd_ambarella_drv_suspend(struct device *dev)
++{
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++	if (time_before(jiffies, ohci->next_statechange))
++		msleep(5);
++	ohci->next_statechange = jiffies;
++
++	return 0;
++}
++
++static int ohci_hcd_ambarella_drv_resume(struct device *dev)
++{
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++	if (time_before(jiffies, ohci->next_statechange))
++		msleep(5);
++	ohci->next_statechange = jiffies;
++
++	ohci_resume(hcd, false);
++
++	return 0;
++}
++
++static struct dev_pm_ops ambarella_ohci_pmops = {
++	.suspend	= ohci_hcd_ambarella_drv_suspend,
++	.resume		= ohci_hcd_ambarella_drv_resume,
++	.freeze		= ohci_hcd_ambarella_drv_suspend,
++	.thaw		= ohci_hcd_ambarella_drv_resume,
++};
++
++#define AMBARELLA_OHCI_PMOPS &ambarella_ohci_pmops
++
++#else
++#define AMBARELLA_OHCI_PMOPS NULL
++#endif
++
++static const struct of_device_id ambarella_ohci_dt_ids[] = {
++	{ .compatible = "ambarella,ohci", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_ohci_dt_ids);
++
++static struct platform_driver ohci_hcd_ambarella_driver = {
++	.probe		= ohci_hcd_ambarella_drv_probe,
++	.remove		= ohci_hcd_ambarella_drv_remove,
++	.shutdown	= usb_hcd_platform_shutdown,
++	.driver		= {
++		.name	= "ambarella-ohci",
++		.owner	= THIS_MODULE,
++		.pm	= AMBARELLA_OHCI_PMOPS,
++		.of_match_table = of_match_ptr(ambarella_ohci_dt_ids),
++	},
++};
++
++MODULE_ALIAS("platform:ambarella-ohci");
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index 865946cd..93ecd114 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -1151,6 +1151,11 @@ MODULE_LICENSE ("GPL");
+ #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
+ #endif
+ 
++#ifdef CONFIG_USB_OHCI_AMBARELLA
++#include "ohci-ambarella.c"
++#define AMBARELLA_PLATFORM_DRIVER		ohci_hcd_ambarella_driver
++#endif
++
+ #ifdef CONFIG_USB_OHCI_HCD_PPC_OF
+ #include "ohci-ppc-of.c"
+ #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
+@@ -1211,6 +1216,7 @@ MODULE_LICENSE ("GPL");
+ 	!defined(AT91_PLATFORM_DRIVER) && \
+ 	!defined(NXP_PLATFORM_DRIVER) && \
+ 	!defined(DAVINCI_PLATFORM_DRIVER) && \
++	!defined(AMBARELLA_PLATFORM_DRIVER) && \
+ 	!defined(SPEAR_PLATFORM_DRIVER)
+ #error "missing bus glue for ohci-hcd"
+ #endif
+@@ -1247,6 +1253,12 @@ static int __init ohci_hcd_mod_init(void)
+ 		goto error_platform;
+ #endif
+ 
++#ifdef AMBARELLA_PLATFORM_DRIVER
++	retval = platform_driver_register(&AMBARELLA_PLATFORM_DRIVER);
++	if (retval < 0)
++		goto error_ambarella_platform;
++#endif
++
+ #ifdef OMAP1_PLATFORM_DRIVER
+ 	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
+ 	if (retval < 0)
+@@ -1394,6 +1406,10 @@ static int __init ohci_hcd_mod_init(void)
+ 	platform_driver_unregister(&PLATFORM_DRIVER);
+  error_platform:
+ #endif
++#ifdef AMBARELLA_PLATFORM_DRIVER
++	platform_driver_unregister(&AMBARELLA_PLATFORM_DRIVER);
++ error_ambarella_platform:
++#endif
+ #ifdef PS3_SYSTEM_BUS_DRIVER
+ 	ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+  error_ps3:
+@@ -1456,6 +1472,9 @@ static void __exit ohci_hcd_mod_exit(void)
+ #ifdef PLATFORM_DRIVER
+ 	platform_driver_unregister(&PLATFORM_DRIVER);
+ #endif
++#ifdef AMBARELLA_PLATFORM_DRIVER
++	platform_driver_unregister(&AMBARELLA_PLATFORM_DRIVER);
++#endif
+ #ifdef PS3_SYSTEM_BUS_DRIVER
+ 	ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+ #endif
+diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
+index a51e7d6a..ca91420f 100644
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -200,6 +200,19 @@ config USB_TEST
+ 	  See <http://www.linux-usb.org/usbtest/> for more information,
+ 	  including sample test device firmware and "how to use it".
+ 
++config USB_EHSET_TEST_FIXTURE
++        tristate "USB EHSET Test Fixture driver"
++        help
++	  Say Y here if you want to support the special test fixture device
++	  used for the USB-IF Embedded Host High-Speed Electrical Test procedure.
++
++	  When the test fixture is connected, it can enumerate as one of several
++	  VID/PID pairs. This driver then initiates a corresponding test mode on
++	  the downstream port to which the test fixture is attached.
++
++	  See <http://www.usb.org/developers/onthego/EHSET_v1.01.pdf> for more
++	  information.
++
+ config USB_ISIGHTFW
+ 	tristate "iSight firmware loading support"
+ 	select FW_LOADER
+diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
+index 3e1bd70b..c9eafdfc 100644
+--- a/drivers/usb/misc/Makefile
++++ b/drivers/usb/misc/Makefile
+@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_LED)			+= usbled.o
+ obj-$(CONFIG_USB_LEGOTOWER)		+= legousbtower.o
+ obj-$(CONFIG_USB_RIO500)		+= rio500.o
+ obj-$(CONFIG_USB_TEST)			+= usbtest.o
++obj-$(CONFIG_USB_EHSET_TEST_FIXTURE)    += ehset.o
+ obj-$(CONFIG_USB_TRANCEVIBRATOR)	+= trancevibrator.o
+ obj-$(CONFIG_USB_USS720)		+= uss720.o
+ obj-$(CONFIG_USB_SEVSEG)		+= usbsevseg.o
+diff --git a/drivers/usb/misc/ehset.c b/drivers/usb/misc/ehset.c
+new file mode 100644
+index 00000000..c31b4a33
+--- /dev/null
++++ b/drivers/usb/misc/ehset.c
+@@ -0,0 +1,152 @@
++/*
++ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 and
++ * only version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/usb.h>
++#include <linux/usb/ch11.h>
++
++#define TEST_SE0_NAK_PID			0x0101
++#define TEST_J_PID				0x0102
++#define TEST_K_PID				0x0103
++#define TEST_PACKET_PID				0x0104
++#define TEST_HS_HOST_PORT_SUSPEND_RESUME	0x0106
++#define TEST_SINGLE_STEP_GET_DEV_DESC		0x0107
++#define TEST_SINGLE_STEP_SET_FEATURE		0x0108
++
++static int ehset_probe(struct usb_interface *intf,
++		       const struct usb_device_id *id)
++{
++	int ret = -EINVAL;
++	struct usb_device *dev = interface_to_usbdev(intf);
++	struct usb_device *hub_udev = dev->parent;
++	struct usb_device_descriptor *buf;
++	u8 portnum = dev->portnum;
++	u16 test_pid = le16_to_cpu(dev->descriptor.idProduct);
++
++	switch (test_pid) {
++	case TEST_SE0_NAK_PID:
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_SET_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_TEST,
++					(TEST_SE0_NAK << 8) | portnum,
++					NULL, 0, 1000);
++		break;
++	case TEST_J_PID:
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_SET_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_TEST,
++					(TEST_J << 8) | portnum,
++					NULL, 0, 1000);
++		break;
++	case TEST_K_PID:
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_SET_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_TEST,
++					(TEST_K << 8) | portnum,
++					NULL, 0, 1000);
++		break;
++	case TEST_PACKET_PID:
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_SET_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_TEST,
++					(TEST_PACKET << 8) | portnum,
++					NULL, 0, 1000);
++		break;
++	case TEST_HS_HOST_PORT_SUSPEND_RESUME:
++		/* Test: wait for 15secs -> suspend -> 15secs delay -> resume */
++		msleep(15 * 1000);
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_SET_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_SUSPEND, portnum,
++					NULL, 0, 1000);
++		if (ret < 0)
++			break;
++
++		msleep(15 * 1000);
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_CLEAR_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_SUSPEND, portnum,
++					NULL, 0, 1000);
++		break;
++	case TEST_SINGLE_STEP_GET_DEV_DESC:
++		/* Test: wait for 15secs -> GetDescriptor request */
++		msleep(15 * 1000);
++		buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
++		if (!buf)
++			return -ENOMEM;
++
++		ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
++					USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
++					USB_DT_DEVICE << 8, 0,
++					buf, USB_DT_DEVICE_SIZE,
++					USB_CTRL_GET_TIMEOUT);
++		kfree(buf);
++		break;
++	case TEST_SINGLE_STEP_SET_FEATURE:
++		/*
++		 * GetDescriptor SETUP request -> 15secs delay -> IN & STATUS
++		 *
++		 * Note, this test is only supported on root hubs since the
++		 * SetPortFeature handling can only be done inside the HCD's
++		 * hub_control callback function.
++		 */
++		if (hub_udev != dev->bus->root_hub) {
++			dev_err(&intf->dev, "SINGLE_STEP_SET_FEATURE test only supported on root hub\n");
++			break;
++		}
++
++		ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
++					USB_REQ_SET_FEATURE, USB_RT_PORT,
++					USB_PORT_FEAT_TEST,
++					(6 << 8) | portnum,
++					NULL, 0, 60 * 1000);
++
++		break;
++	default:
++		dev_err(&intf->dev, "%s: unsupported PID: 0x%x\n",
++			__func__, test_pid);
++	}
++
++	return (ret < 0) ? ret : 0;
++}
++
++static void ehset_disconnect(struct usb_interface *intf)
++{
++}
++
++static const struct usb_device_id ehset_id_table[] = {
++	{ USB_DEVICE(0x1a0a, TEST_SE0_NAK_PID) },
++	{ USB_DEVICE(0x1a0a, TEST_J_PID) },
++	{ USB_DEVICE(0x1a0a, TEST_K_PID) },
++	{ USB_DEVICE(0x1a0a, TEST_PACKET_PID) },
++	{ USB_DEVICE(0x1a0a, TEST_HS_HOST_PORT_SUSPEND_RESUME) },
++	{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_GET_DEV_DESC) },
++	{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_SET_FEATURE) },
++	{ }			/* Terminating entry */
++};
++MODULE_DEVICE_TABLE(usb, ehset_id_table);
++
++static struct usb_driver ehset_driver = {
++	.name =		"usb_ehset_test",
++	.probe =	ehset_probe,
++	.disconnect =	ehset_disconnect,
++	.id_table =	ehset_id_table,
++};
++
++module_usb_driver(ehset_driver);
++
++MODULE_DESCRIPTION("USB Driver for EHSET Test Fixture");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
+index 2311b1e4..8f63a413 100644
+--- a/drivers/usb/phy/Kconfig
++++ b/drivers/usb/phy/Kconfig
+@@ -21,6 +21,13 @@ if USB_PHY
+ #
+ # USB Transceiver Drivers
+ #
++config USB_AMBARELLA_PHY
++	bool "Ambarella USB PHY support"
++	depends on ARCH_AMBARELLA
++	help
++	  Enable this to support the Ambarella USB PHY.
++	  Ambarella USB Phy is used by either UDC or EHCI/OHCI.
++
+ config AB8500_USB
+ 	tristate "AB8500 USB Transceiver Driver"
+ 	depends on AB8500_CORE
+diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
+index a9169cb1..6675f0e0 100644
+--- a/drivers/usb/phy/Makefile
++++ b/drivers/usb/phy/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_PHY)			+= phy.o
+ 
+ # transceiver drivers, keep the list sorted
+ 
++obj-$(CONFIG_USB_AMBARELLA_PHY)		+= phy-ambarella.o
+ obj-$(CONFIG_AB8500_USB)		+= phy-ab8500-usb.o
+ phy-fsl-usb2-objs			:= phy-fsl-usb.o phy-fsm-usb.o
+ obj-$(CONFIG_FSL_USB2_OTG)		+= phy-fsl-usb2.o
+diff --git a/drivers/usb/phy/phy-ambarella.c b/drivers/usb/phy/phy-ambarella.c
+new file mode 100644
+index 00000000..8a442029
+--- /dev/null
++++ b/drivers/usb/phy/phy-ambarella.c
+@@ -0,0 +1,492 @@
++/*
++* linux/drivers/usb/phy/phy-ambarella.c
++*
++* History:
++*	2014/01/28 - [Cao Rongrong] created file
++*
++* Copyright (C) 2012 by Ambarella, Inc.
++* http://www.ambarella.com
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the
++* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++* Boston, MA  02111-1307, USA.
++*/
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/usb/otg.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/io.h>
++#include <linux/of_gpio.h>
++#include <asm/uaccess.h>
++#include <plat/rct.h>
++
++#define DRIVER_NAME "ambarella_phy"
++
++/* PORT is termed as usb slot which is outside the chip, and
++ * PHY is termed as usb interface which is inside the chip */
++
++#define PHY_TO_DEVICE_PORT	0 /* rotue D+/D- signal to device port */
++#define PHY_TO_HOST_PORT	1 /* rotue D+/D- signal to host port */
++
++/* PORT_TYPE_XXX is only for the device port */
++#define PORT_TYPE_DEVICE	0 /* we should work as device */
++#define PORT_TYPE_OTG		1 /* we should work as host */
++
++struct ambarella_phy {
++	struct usb_phy phy;
++	void __iomem *pol_reg;
++	void __iomem *ana_reg;
++	void __iomem *own_reg;
++	u8 host_phy_num;
++	bool owner_invert;
++
++	int gpio_id;
++	bool id_is_otg;
++	int gpio_md;
++	bool md_host_active;
++	int gpio_hub;
++	bool hub_active;
++	u8 port_type;	/* the behavior of the device port working */
++	u8 phy_route;	/* route D+/D- signal to device or host port */
++
++#ifdef CONFIG_PM
++	u32 pol_val;
++	u32 own_val;
++#endif
++};
++
++#define to_ambarella_phy(p) container_of((p), struct ambarella_phy, phy)
++
++static inline bool ambarella_usb0_is_host(struct ambarella_phy *amb_phy)
++{
++	bool is_host;
++
++	if (amb_phy->owner_invert)
++		is_host = !(amba_rct_readl(amb_phy->own_reg) & USB0_IS_HOST_MASK);
++	else
++		is_host = !!(amba_rct_readl(amb_phy->own_reg) & USB0_IS_HOST_MASK);
++
++	return is_host;
++};
++
++static inline void ambarella_switch_to_host(struct ambarella_phy *amb_phy)
++{
++	if (amb_phy->owner_invert)
++		amba_rct_clrbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
++	else
++		amba_rct_setbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
++}
++
++static inline void ambarella_switch_to_device(struct ambarella_phy *amb_phy)
++{
++	if (amb_phy->owner_invert)
++		amba_rct_setbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
++	else
++		amba_rct_clrbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
++}
++
++static inline void ambarella_check_otg(struct ambarella_phy *amb_phy)
++{
++	/* if D+/D- is routed to device port which is working
++	 * as otg, we need to switch the phy to host mode. */
++	if (amb_phy->phy_route == PHY_TO_DEVICE_PORT) {
++		if (amb_phy->port_type == PORT_TYPE_OTG)
++			ambarella_switch_to_host(amb_phy);
++		else
++			ambarella_switch_to_device(amb_phy);
++	}
++}
++
++static void __iomem *ambarella_phy_get_reg(struct platform_device *pdev, int index)
++{
++	struct resource *mem;
++	void __iomem *reg;
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, index);
++	if (!mem) {
++		dev_err(&pdev->dev, "No mem resource: %d!\n", index);
++		return NULL;
++	}
++
++	reg = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
++	if (!reg) {
++		dev_err(&pdev->dev, "devm_ioremap() failed: %d\n", index);
++		return NULL;
++	}
++
++	return reg;
++}
++
++static int ambarella_phy_proc_show(struct seq_file *m, void *v)
++{
++	struct ambarella_phy *amb_phy = m->private;
++	const char *port_status;
++	const char *phy_status;
++	int len = 0;
++
++	if (amb_phy->phy_route == PHY_TO_HOST_PORT)
++		port_status = "HOST";
++	else
++		port_status = "DEVICE";
++
++	if (ambarella_usb0_is_host(amb_phy))
++		phy_status = "HOST";
++	else
++		phy_status = "DEVICE";
++
++	len += seq_printf(m, "Possible parameter: host device\n");
++	len += seq_printf(m, "Current status:\n");
++	len += seq_printf(m, "\tport is %s: phy is %s\n\n",
++		port_status, phy_status);
++
++	return len;
++}
++
++static int ambarella_phy_proc_write(struct file *file,
++	const char __user *buffer, size_t count, loff_t *ppos)
++{
++	struct ambarella_phy *amb_phy = PDE_DATA(file_inode(file));
++	char n, str[32];
++
++	n = (count < 32) ? count : 32;
++
++	if (copy_from_user(str, buffer, n))
++		return -EFAULT;
++
++	str[n - 1] = '\0';
++
++	if (!strcasecmp(str, "host")) {
++		if (gpio_is_valid(amb_phy->gpio_md)) {
++			amb_phy->phy_route = PHY_TO_HOST_PORT;
++			gpio_direction_output(amb_phy->gpio_md,
++						amb_phy->md_host_active);
++		}
++
++		ambarella_switch_to_host(amb_phy);
++	} else if (!strcasecmp(str, "device")) {
++		if (gpio_is_valid(amb_phy->gpio_md)) {
++			amb_phy->phy_route = PHY_TO_DEVICE_PORT;
++			gpio_direction_output(amb_phy->gpio_md,
++						!amb_phy->md_host_active);
++		}
++
++		ambarella_check_otg(amb_phy);
++	} else {
++		pr_err("Invalid argument!\n");
++	}
++
++	return count;
++}
++
++static int ambarella_phy_proc_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, ambarella_phy_proc_show, PDE_DATA(inode));
++}
++
++static const struct file_operations proc_phy_switcher_fops = {
++	.open = ambarella_phy_proc_open,
++	.read = seq_read,
++	.llseek = seq_lseek,
++	.write = ambarella_phy_proc_write,
++};
++
++static irqreturn_t ambarella_otg_detect_irq(int irq, void *dev_id)
++{
++	struct ambarella_phy *amb_phy = dev_id;
++
++	if (gpio_is_valid(amb_phy->gpio_id)) {
++		if (gpio_get_value_cansleep(amb_phy->gpio_id) == amb_phy->id_is_otg)
++			amb_phy->port_type = PORT_TYPE_OTG;
++		else
++			amb_phy->port_type = PORT_TYPE_DEVICE;
++	} else {
++		amb_phy->port_type = PORT_TYPE_DEVICE;
++	}
++
++	ambarella_check_otg(amb_phy);
++
++	return IRQ_HANDLED;
++}
++
++static int ambarella_init_phy_switcher(struct ambarella_phy *amb_phy)
++{
++	struct usb_phy *phy = &amb_phy->phy;
++	int irq, rval = 0;
++
++	/* only usb0 support to switch between host and device */
++	proc_create_data("usbphy0", S_IRUGO|S_IWUSR,
++		get_ambarella_proc_dir(), &proc_phy_switcher_fops, amb_phy);
++
++	/* request gpio for PHY HUB reset */
++	if (gpio_is_valid(amb_phy->gpio_hub)) {
++		rval = devm_gpio_request(phy->dev, amb_phy->gpio_hub, "hub reset");
++		if (rval < 0) {
++			dev_err(phy->dev, "Failed to request hub reset pin %d\n", rval);
++			return rval;
++		}
++		gpio_direction_output(amb_phy->gpio_hub, !amb_phy->hub_active);
++	}
++
++	if (gpio_is_valid(amb_phy->gpio_id)) {
++		rval = devm_gpio_request_one(phy->dev,
++			amb_phy->gpio_id, GPIOF_DIR_IN, "otg_id");
++		if (rval < 0){
++			dev_err(phy->dev, "Failed to request id pin %d\n", rval);
++			return rval;
++		}
++
++		if (gpio_get_value_cansleep(amb_phy->gpio_id) == amb_phy->id_is_otg)
++			amb_phy->port_type = PORT_TYPE_OTG;
++		else
++			amb_phy->port_type = PORT_TYPE_DEVICE;
++
++		irq = gpio_to_irq(amb_phy->gpio_id);
++
++		rval = devm_request_threaded_irq(phy->dev, irq, NULL,
++			ambarella_otg_detect_irq,
++			IRQ_TYPE_EDGE_BOTH | IRQF_ONESHOT,
++			"usb_otg_id", amb_phy);
++		if (rval) {
++			dev_err(phy->dev, "request usb_otg_id irq failed: %d\n", rval);
++			return rval;
++		}
++
++	} else {
++		amb_phy->port_type = PORT_TYPE_DEVICE;
++	}
++
++	/* rotue D+/D- signal to host or device port if control gpio existed */
++	if (gpio_is_valid(amb_phy->gpio_md)) {
++		rval = devm_gpio_request(phy->dev,
++				amb_phy->gpio_md, "phy_switcher");
++		if (rval) {
++			dev_err(phy->dev, "request phy_switcher gpio failed\n");
++			return rval;
++		}
++
++		/* if usb0 is configured as host, route D+/D- signal to
++		 * host port, otherwise route them to device port. */
++		if (ambarella_usb0_is_host(amb_phy)) {
++			amb_phy->phy_route = PHY_TO_HOST_PORT;
++			gpio_direction_output(amb_phy->gpio_md,
++						amb_phy->md_host_active);
++		} else {
++			amb_phy->phy_route = PHY_TO_DEVICE_PORT;
++			gpio_direction_output(amb_phy->gpio_md,
++						!amb_phy->md_host_active);
++		}
++	} else {
++		amb_phy->phy_route = PHY_TO_DEVICE_PORT;
++	}
++
++	ambarella_check_otg(amb_phy);
++
++	return 0;
++}
++
++static int ambarella_init_host_phy(struct platform_device *pdev,
++			struct ambarella_phy *amb_phy)
++{
++	struct device_node *np = pdev->dev.of_node;
++	enum of_gpio_flags flags;
++	int ocp, rval;
++
++	/* get register for overcurrent polarity */
++	amb_phy->pol_reg = ambarella_phy_get_reg(pdev, 1);
++	if (!amb_phy->pol_reg)
++		return -ENXIO;
++
++	/* get register for usb phy owner configure */
++	amb_phy->own_reg = ambarella_phy_get_reg(pdev, 2);
++	if (!amb_phy->own_reg)
++		return -ENXIO;
++
++	/* see RCT Programming Guide for detailed info about ocp and owner */
++	rval = of_property_read_u32(np, "amb,ocp-polarity", &ocp);
++	if (rval == 0) {
++		amba_clrbitsl(amb_phy->pol_reg, 0x1 << 13);
++		amba_setbitsl(amb_phy->pol_reg, ocp << 13);
++	}
++
++	amb_phy->owner_invert = !!of_find_property(np, "amb,owner-invert", NULL);
++	if (of_find_property(np, "amb,owner-mask", NULL))
++		amba_setbitsl(amb_phy->own_reg, 0x1);
++
++	amb_phy->gpio_id = of_get_named_gpio_flags(np, "id-gpios", 0, &flags);
++	amb_phy->id_is_otg = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	amb_phy->gpio_md = of_get_named_gpio_flags(np, "md-gpios", 0, &flags);
++	amb_phy->md_host_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	amb_phy->gpio_hub = of_get_named_gpio_flags(np, "hub-gpios", 0, &flags);
++	amb_phy->hub_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	ambarella_init_phy_switcher(amb_phy);
++
++	return 0;
++}
++
++static int ambarella_phy_init(struct usb_phy *phy)
++{
++	struct ambarella_phy *amb_phy = to_ambarella_phy(phy);
++	u32 ana_val = 0x3006;
++
++	/* If there are 2 PHYs, no matter which PHY need to be initialized,
++	 * we initialize all of them at the same time */
++
++	if (!(amba_readl(amb_phy->ana_reg) & ana_val)) {
++		amba_setbitsl(amb_phy->ana_reg, ana_val);
++		mdelay(1);
++	}
++
++	return 0;
++}
++
++static int ambarella_phy_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct ambarella_phy *amb_phy;
++	int host_phy_num, rval;
++
++	amb_phy = devm_kzalloc(&pdev->dev, sizeof(*amb_phy), GFP_KERNEL);
++	if (!amb_phy) {
++		dev_err(&pdev->dev, "Failed to allocate memory!\n");
++		return -ENOMEM;
++	}
++
++	amb_phy->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
++					GFP_KERNEL);
++	if (!amb_phy->phy.otg) {
++		dev_err(&pdev->dev, "Failed to allocate memory!\n");
++		return -ENOMEM;
++	}
++
++	amb_phy->phy.dev = &pdev->dev;
++	amb_phy->phy.label = DRIVER_NAME;
++	amb_phy->phy.init = ambarella_phy_init;
++
++	/* get register for usb phy power on */
++	amb_phy->ana_reg = ambarella_phy_get_reg(pdev, 0);
++	if (!amb_phy->ana_reg)
++		return -ENXIO;
++
++	rval = of_property_read_u32(np, "amb,host-phy-num", &host_phy_num);
++	if (rval < 0)
++		amb_phy->host_phy_num = 0;
++	else
++		amb_phy->host_phy_num = host_phy_num;
++
++	if (amb_phy->host_phy_num > 0)
++		ambarella_init_host_phy(pdev, amb_phy);
++
++	platform_set_drvdata(pdev, &amb_phy->phy);
++
++	rval = usb_add_phy_dev(&amb_phy->phy);
++	if (rval < 0)
++		return rval;
++
++	return 0;
++}
++
++static int ambarella_phy_remove(struct platform_device *pdev)
++{
++	struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
++
++	usb_remove_phy(&amb_phy->phy);
++
++	return 0;
++}
++
++static void ambarella_phy_shutdown(struct platform_device *pdev)
++{
++	struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
++
++	if (amb_phy->host_phy_num && gpio_is_valid(amb_phy->gpio_md)) {
++		gpio_direction_output(amb_phy->gpio_md,
++					!amb_phy->md_host_active);
++	}
++
++}
++
++#ifdef CONFIG_PM
++static int ambarella_phy_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
++
++	amb_phy->pol_val = amba_readl(amb_phy->pol_reg);
++	amb_phy->own_val = amba_readl(amb_phy->own_reg);
++
++	return 0;
++}
++
++static int ambarella_phy_resume(struct platform_device *pdev)
++{
++	struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
++
++	amba_writel(amb_phy->pol_reg, amb_phy->pol_val);
++	amba_writel(amb_phy->own_reg, amb_phy->own_val);
++
++	return 0;
++}
++#endif
++
++static const struct of_device_id ambarella_phy_dt_ids[] = {
++	{ .compatible = "ambarella,usbphy", },
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ambarella_phy_dt_ids);
++
++static struct platform_driver ambarella_phy_driver = {
++	.probe = ambarella_phy_probe,
++	.remove = ambarella_phy_remove,
++	.shutdown = ambarella_phy_shutdown,
++#ifdef CONFIG_PM
++	.suspend = ambarella_phy_suspend,
++	.resume	 = ambarella_phy_resume,
++#endif
++	.driver = {
++		.name = DRIVER_NAME,
++		.owner	= THIS_MODULE,
++		.of_match_table = ambarella_phy_dt_ids,
++	 },
++};
++
++/* We have to call ambarella_phy_module_init() before the drives using USB PHY
++ * like EHCI/OHCI/UDC, and after GPIO drivers including external GPIO chip, so
++ * we use subsys_initcall_sync here. */
++static int __init ambarella_phy_module_init(void)
++{
++	return platform_driver_register(&ambarella_phy_driver);
++}
++subsys_initcall_sync(ambarella_phy_module_init);
++
++static void __exit ambarella_phy_module_exit(void)
++{
++	platform_driver_unregister(&ambarella_phy_driver);
++}
++module_exit(ambarella_phy_module_exit);
++
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella USB PHY driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
+index 1d55762a..74baf736 100644
+--- a/drivers/usb/serial/Kconfig
++++ b/drivers/usb/serial/Kconfig
+@@ -51,6 +51,15 @@ config USB_SERIAL_GENERIC
+ 	  support" be compiled as a module for this driver to be used
+ 	  properly.
+ 
++
++config USB_SERIAL_U1960
++	tristate "USB Serial Driver for U1960"
++	help
++	    Say Y here if you want to use U1960.
++
++	    To compile this driver as a module, choose M here: the module
++	    will be called aircable.
++
+ config USB_SERIAL_AIRCABLE
+ 	tristate "USB AIRcable Bluetooth Dongle Driver"
+ 	help
+@@ -130,7 +139,7 @@ config USB_SERIAL_CYPRESS_M8
+ 
+ 	  Supported microcontrollers in the CY4601 family are:
+ 		CY7C63741 CY7C63742 CY7C63743 CY7C64013
+-	
++
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called cypress_m8.
+ 
+diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
+index cec63fa1..b4ad309d 100644
+--- a/drivers/usb/serial/Makefile
++++ b/drivers/usb/serial/Makefile
+@@ -3,7 +3,6 @@
+ #
+ 
+ # Object file lists.
+-
+ obj-$(CONFIG_USB_SERIAL)			+= usbserial.o
+ 
+ usbserial-y := usb-serial.o generic.o bus.o
+@@ -65,3 +64,4 @@ obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL)		+= vivopay-serial.o
+ obj-$(CONFIG_USB_SERIAL_XSENS_MT)		+= xsens_mt.o
+ obj-$(CONFIG_USB_SERIAL_ZIO)			+= zio.o
+ obj-$(CONFIG_USB_SERIAL_ZTE)			+= zte_ev.o
++obj-$(CONFIG_USB_SERIAL_U1960)			+=u1960.o
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 006a2a72..9e818532 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -356,6 +356,9 @@ static void option_instat_callback(struct urb *urb);
+  */
+ #define LONGCHEER_VENDOR_ID			0x1c9e
+ 
++/***Add for LONGSUNG LTE 4G MODEM U8300***/
++#define LONGSUNG_U8300_PRODUCT_ID	0x9b05
++
+ /* 4G Systems products */
+ /* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
+  * It seems to contain a Qualcomm QSC6240/6290 chipset            */
+diff --git a/drivers/usb/serial/u1960.c b/drivers/usb/serial/u1960.c
+new file mode 100644
+index 00000000..dcf20e38
+--- /dev/null
++++ b/drivers/usb/serial/u1960.c
+@@ -0,0 +1,56 @@
++/*
++ * usb-serial driver for Quatech USB 2 devices
++ *
++ * Copyright (C) 2012 Bill Pemberton (wfp5p@virginia.edu)
++ *
++ * 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.
++ *
++ *
++ *  These devices all have only 1 bulk in and 1 bulk out that is shared
++ *  for all serial ports.
++ *
++ */
++
++#include <asm/unaligned.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/tty.h>
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++#include <linux/module.h>
++#include <linux/serial.h>
++#include <linux/usb.h>
++#include <linux/usb/serial.h>
++#include <linux/serial_reg.h>
++#include <linux/uaccess.h>
++
++#define DRIVER_DESC "u1960 USB to Serial Driver"
++
++static const struct usb_device_id id_table[] = {
++	{USB_DEVICE(0x1e89,0x1a20)},
++	{}			/* Terminating entry */
++};
++
++MODULE_DEVICE_TABLE(usb, id_table);
++
++static struct usb_serial_driver u1960_device = {
++	.driver = {
++		.owner = THIS_MODULE,
++		.name = "U1960",
++	},
++	.description	     = DRIVER_DESC,
++	.id_table	     = id_table,
++	.num_ports =		1,
++};
++
++static struct usb_serial_driver *const serial_drivers[] = {
++	&u1960_device, NULL
++};
++
++module_usb_serial_driver(serial_drivers, id_table);
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 2e937bda..af480f6b 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -2347,6 +2347,16 @@ config FB_PRE_INIT_FB
+ 	  Select this option if display contents should be inherited as set by
+ 	  the bootloader.
+ 
++config FB_AMBARELLA
++	tristate "Ambarella Framebuffer support"
++	depends on FB && PLAT_AMBARELLA
++	select FB_SYS_FILLRECT
++	select FB_SYS_COPYAREA
++	select FB_SYS_IMAGEBLIT
++	select FB_SYS_FOPS
++	help
++          Frame buffer driver for Ambarella chips.
++
+ config FB_MSM
+ 	tristate "MSM Framebuffer support"
+ 	depends on FB && ARCH_MSM
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index e8bae8dd..076d4717 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -141,6 +141,7 @@ obj-$(CONFIG_FB_SH_MOBILE_HDMI)	  += sh_mobile_hdmi.o
+ obj-$(CONFIG_FB_SH_MOBILE_MERAM)  += sh_mobile_meram.o
+ obj-$(CONFIG_FB_SH_MOBILE_LCDC)	  += sh_mobile_lcdcfb.o
+ obj-$(CONFIG_FB_OMAP)             += omap/
++obj-$(CONFIG_FB_AMBARELLA)        += ambarella/
+ obj-y                             += omap2/
+ obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
+ obj-$(CONFIG_FB_CARMINE)          += carminefb.o
+diff --git a/drivers/video/ambarella/Makefile b/drivers/video/ambarella/Makefile
+new file mode 100644
+index 00000000..0cc606b0
+--- /dev/null
++++ b/drivers/video/ambarella/Makefile
+@@ -0,0 +1,24 @@
++#
++# drivers/video/ambarella/Kconfig
++#
++# Author: Anthony Ginger <hfjiang@ambarella.com>
++#
++# Copyright (C) 2004-2009, Ambarella, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++#
++
++obj-$(CONFIG_FB_AMBARELLA) += ambarella_fb.o
++
+diff --git a/drivers/video/ambarella/ambarella_fb.c b/drivers/video/ambarella/ambarella_fb.c
+new file mode 100644
+index 00000000..3f35e944
+--- /dev/null
++++ b/drivers/video/ambarella/ambarella_fb.c
+@@ -0,0 +1,698 @@
++/*
++ * drivers/drivers/video/ambarella/ambarella_fb.c
++ *
++ *	2008/07/22 - [linnsong] Create
++ *	2009/03/03 - [Anthony Ginger] Port to 2.6.28
++ *	2009/12/15 - [Zhenwu Xue] Change fb_setcmap
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/mm.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/list.h>
++#include <linux/amba/bus.h>
++#include <linux/amba/clcd.h>
++#include <linux/clk.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++
++#include <asm/sizes.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++
++#include <mach/init.h>
++#include <plat/fb.h>
++
++/* video=amb0fb:<x_res>x<y_res>,<x_virtual>x<y_virtual>,
++   <color_format>,<conversion_buffer>[,<prealloc_start>,<prealloc_length>] */
++
++#include "ambarella_fb_tbl.c"
++
++/* ========================================================================== */
++#ifdef CONFIG_PROC_FS
++static int ambarella_fb_proc_show(struct seq_file *m, void *v)
++{
++        int len;
++        struct ambarella_platform_fb *ambfb_data;
++        struct fb_info *info;
++
++        ambfb_data = (struct ambarella_platform_fb *)m->private;
++        info = ambfb_data->proc_fb_info;
++
++        wait_event_interruptible(ambfb_data->proc_wait,
++                                 (ambfb_data->proc_wait_flag > 0));
++        ambfb_data->proc_wait_flag = 0;
++        dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__,
++                ambfb_data->proc_wait_flag);
++        len = seq_printf(m, "%04d %04d %04d %04d %04d %04d\n",
++                         info->var.xres, info->var.yres,
++                         info->fix.line_length,
++                         info->var.xoffset, info->var.yoffset,
++                         ambfb_data->color_format);
++
++        return len;
++}
++
++static int ambarella_fb_proc_open(struct inode *inode, struct file *file)
++{
++        return single_open(file, ambarella_fb_proc_show, PDE_DATA(inode));
++}
++
++static const struct file_operations ambarella_fb_fops = {
++        .open = ambarella_fb_proc_open,
++        .read = seq_read,
++        .llseek = seq_lseek,
++};
++#endif
++
++/* ========================================================================== */
++static int ambfb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
++{
++        int					errorCode = 0;
++        struct ambarella_platform_fb		*ambfb_data;
++        int					pos;
++        u16					*r, *g, *b, *t;
++        u8					*pclut_table, *pblend_table;
++
++        if (cmap == &info->cmap) {
++                errorCode = 0;
++                goto ambfb_setcmap_exit;
++        }
++
++        if (cmap->start != 0 || cmap->len != 256) {
++                dev_dbg(info->device,
++                        "%s: Incorrect parameters: start = %d, len = %d\n",
++                        __func__, cmap->start, cmap->len);
++                errorCode = -1;
++                goto ambfb_setcmap_exit;
++        }
++
++        if (!cmap->red || !cmap->green || !cmap->blue) {
++                dev_dbg(info->device, "%s: Incorrect rgb pointers!\n",
++                        __func__);
++                errorCode = -1;
++                goto ambfb_setcmap_exit;
++        }
++
++        ambfb_data = (struct ambarella_platform_fb *)info->par;
++
++        mutex_lock(&ambfb_data->lock);
++
++        r = cmap->red;
++        g = cmap->green;
++        b = cmap->blue;
++        t = cmap->transp;
++        pclut_table = ambfb_data->clut_table;
++        pblend_table = ambfb_data->blend_table;
++        for (pos = 0; pos < 256; pos++) {
++                *pclut_table++ = *r++;
++                *pclut_table++ = *g++;
++                *pclut_table++ = *b++;
++                if (t) *pblend_table++ = *t++;
++        }
++
++        if (ambfb_data->setcmap) {
++                mutex_unlock(&ambfb_data->lock);
++                errorCode = ambfb_data->setcmap(cmap, info);
++        } else {
++                mutex_unlock(&ambfb_data->lock);
++        }
++
++ambfb_setcmap_exit:
++        dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
++        return errorCode;
++}
++
++static int ambfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
++{
++        int					errorCode = 0;
++        struct ambarella_platform_fb		*ambfb_data;
++        u32					framesize = 0;
++
++        ambfb_data = (struct ambarella_platform_fb *)info->par;
++
++        mutex_lock(&ambfb_data->lock);
++        if (ambfb_data->check_var) {
++                errorCode = ambfb_data->check_var(var, info);
++        }
++        mutex_unlock(&ambfb_data->lock);
++
++        if (var->xres_virtual * var->bits_per_pixel / 8 > info->fix.line_length) {
++                errorCode = -ENOMEM;
++                dev_err(info->device, "%s: xres_virtual[%d] too big [%d]!\n",
++                        __func__, var->xres_virtual * var->bits_per_pixel / 8,
++                        info->fix.line_length);
++        }
++
++        framesize = info->fix.line_length * var->yres_virtual;
++        if (framesize > info->fix.smem_len) {
++                errorCode = -ENOMEM;
++                dev_err(info->device, "%s: framesize[%d] too big [%d]!\n",
++                        __func__, framesize, info->fix.smem_len);
++        }
++
++        dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
++
++        return errorCode;
++}
++
++static int ambfb_set_par(struct fb_info *info)
++{
++        int					errorCode = 0, i;
++        struct ambarella_platform_fb		*ambfb_data;
++        struct fb_var_screeninfo		*pvar;
++        static struct fb_var_screeninfo		*cur_var;
++        int					res_changed = 0;
++        int					color_format_changed = 0;
++        enum ambarella_fb_color_format		new_color_format;
++        const struct ambarella_fb_color_table	*pTable;
++
++        ambfb_data = (struct ambarella_platform_fb *)info->par;
++        mutex_lock(&ambfb_data->lock);
++        cur_var = &ambfb_data->screen_var;
++        pvar = &info->var;
++
++        if (!ambfb_data->set_par)
++                goto ambfb_set_par_quick_exit;
++
++        /* Resolution changed */
++        if (pvar->xres != cur_var->xres || pvar->yres != cur_var->yres) {
++                res_changed = 1;
++        }
++
++        /* Color format changed */
++        if (pvar->bits_per_pixel != cur_var->bits_per_pixel ||
++            pvar->red.offset != cur_var->red.offset ||
++            pvar->red.length != cur_var->red.length ||
++            pvar->red.msb_right != cur_var->red.msb_right ||
++            pvar->green.offset != cur_var->green.offset ||
++            pvar->green.length != cur_var->green.length ||
++            pvar->green.msb_right != cur_var->green.msb_right ||
++            pvar->blue.offset != cur_var->blue.offset ||
++            pvar->blue.length != cur_var->blue.length ||
++            pvar->blue.msb_right != cur_var->blue.msb_right ||
++            pvar->transp.offset != cur_var->transp.offset ||
++            pvar->transp.length != cur_var->transp.length ||
++            pvar->transp.msb_right != cur_var->transp.msb_right) {
++
++                color_format_changed = 1;
++        }
++
++        if (!res_changed && !color_format_changed)
++                goto ambfb_set_par_quick_exit;
++
++        /* Find color format */
++        new_color_format = ambfb_data->color_format;
++        pTable = ambarella_fb_color_format_table;
++        for (i = 0; i < ARRAY_SIZE(ambarella_fb_color_format_table); i++) {
++                if (pTable->bits_per_pixel == pvar->bits_per_pixel &&
++                    pTable->red.offset == pvar->red.offset &&
++                    pTable->red.length == pvar->red.length &&
++                    pTable->red.msb_right == pvar->red.msb_right &&
++                    pTable->green.offset == pvar->green.offset &&
++                    pTable->green.length == pvar->green.length &&
++                    pTable->green.msb_right == pvar->green.msb_right &&
++                    pTable->blue.offset == pvar->blue.offset &&
++                    pTable->blue.length == pvar->blue.length &&
++                    pTable->blue.msb_right == pvar->blue.msb_right &&
++                    pTable->transp.offset == pvar->transp.offset &&
++                    pTable->transp.length == pvar->transp.length &&
++                    pTable->transp.msb_right == pvar->transp.msb_right) {
++
++                        new_color_format = pTable->color_format;
++                        break;
++                }
++                pTable++;
++        }
++
++        ambfb_data->color_format = new_color_format;
++        memcpy(cur_var, pvar, sizeof(*pvar));
++        mutex_unlock(&ambfb_data->lock);
++
++        errorCode = ambfb_data->set_par(info);
++        goto ambfb_set_par_normal_exit;
++
++ambfb_set_par_quick_exit:
++        memcpy(cur_var, pvar, sizeof(*pvar));
++        mutex_unlock(&ambfb_data->lock);
++
++ambfb_set_par_normal_exit:
++        dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
++
++        return errorCode;
++}
++
++static int ambfb_pan_display(struct fb_var_screeninfo *var,
++                             struct fb_info *info)
++{
++        int					errorCode = 0;
++        struct ambarella_platform_fb		*ambfb_data;
++
++        ambfb_data = (struct ambarella_platform_fb *)info->par;
++
++        ambfb_data->proc_wait_flag++;
++        wake_up(&(ambfb_data->proc_wait));
++        mutex_lock(&ambfb_data->lock);
++        ambfb_data->screen_var.xoffset = var->xoffset;
++        ambfb_data->screen_var.yoffset = var->yoffset;
++        if (ambfb_data->pan_display) {
++                errorCode = ambfb_data->pan_display(var, info);
++        }
++        mutex_unlock(&ambfb_data->lock);
++
++        dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
++
++        return 0;
++}
++
++static int ambfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
++{
++        unsigned long size = vma->vm_end - vma->vm_start;
++        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
++        struct ambarella_platform_fb *ambfb_data = NULL;
++
++        ambfb_data = ambfb_data_ptr[info->dev->id];
++
++        if (offset + size > info->fix.smem_len)
++                return -EINVAL;
++
++        offset += info->fix.smem_start;
++
++        if(ambfb_data->conversion_buf.available)
++                vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++        if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
++                            size, vma->vm_page_prot))
++                return -EAGAIN;
++
++        dev_dbg(info->device, "%s: P(0x%08lx)->V(0x%08lx), size = 0x%08lx.\n",
++                __func__, offset, vma->vm_start, size);
++
++        return 0;
++}
++
++static int ambfb_blank(int blank_mode, struct fb_info *info)
++{
++        int					errorCode = 0;
++        struct ambarella_platform_fb		*ambfb_data;
++
++        ambfb_data = (struct ambarella_platform_fb *)info->par;
++
++        mutex_lock(&ambfb_data->lock);
++        if (ambfb_data->set_blank) {
++                errorCode = ambfb_data->set_blank(blank_mode, info);
++        }
++        mutex_unlock(&ambfb_data->lock);
++
++        dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
++
++        return errorCode;
++}
++
++static struct fb_ops ambfb_ops = {
++        .owner          = THIS_MODULE,
++        .fb_check_var	= ambfb_check_var,
++        .fb_set_par	= ambfb_set_par,
++        .fb_pan_display	= ambfb_pan_display,
++        .fb_fillrect	= sys_fillrect,
++        .fb_copyarea	= sys_copyarea,
++        .fb_imageblit	= sys_imageblit,
++        .fb_mmap	= ambfb_mmap,
++        .fb_setcmap	= ambfb_setcmap,
++        .fb_blank	= ambfb_blank,
++};
++
++static int ambfb_setup(struct device *dev, char *options,
++                       struct ambarella_platform_fb *ambfb_data)
++{
++        int					retval = -1;
++        int					ssret;
++        int					cl_xres;
++        int					cl_yres;
++        int					cl_xvirtual;
++        int					cl_yvirtual;
++        int					cl_format;
++        int					cl_cvs_buf;
++        unsigned int				cl_prealloc_start;
++        unsigned int				cl_prealloc_length;
++
++        if (!options || !*options) {
++                goto ambfb_setup_exit;
++        }
++
++        ssret = sscanf(options, "%dx%d,%dx%d,%d,%d,%x,%x", &cl_xres, &cl_yres,
++                       &cl_xvirtual, &cl_yvirtual, &cl_format, &cl_cvs_buf,
++                       &cl_prealloc_start, &cl_prealloc_length);
++        if (ssret == 6) {
++                ambfb_data->screen_var.xres = cl_xres;
++                ambfb_data->screen_var.yres = cl_yres;
++                ambfb_data->screen_var.xres_virtual = cl_xvirtual;
++                ambfb_data->screen_var.yres_virtual = cl_yvirtual;
++                ambfb_data->color_format = cl_format;
++                ambfb_data->conversion_buf.available = cl_cvs_buf;
++                dev_dbg(dev, "%dx%d,%dx%d,%d,%d\n", cl_xres, cl_yres,
++                        cl_xvirtual, cl_yvirtual, cl_format, cl_cvs_buf);
++                retval = 0;
++        } else if (ssret == 8) {
++                ambfb_data->screen_var.xres = cl_xres;
++                ambfb_data->screen_var.yres = cl_yres;
++                ambfb_data->screen_var.xres_virtual = cl_xvirtual;
++                ambfb_data->screen_var.yres_virtual = cl_yvirtual;
++                ambfb_data->color_format = cl_format;
++                ambfb_data->conversion_buf.available = cl_cvs_buf;
++
++                ambfb_data->screen_fix.smem_start = cl_prealloc_start;
++                ambfb_data->screen_fix.smem_len = cl_prealloc_length;
++                ambfb_data->use_prealloc = 1;
++                dev_dbg(dev, "%dx%d,%dx%d,%d,%d,%x,%x\n", cl_xres, cl_yres,
++                        cl_xvirtual, cl_yvirtual, cl_format, cl_cvs_buf,
++                        cl_prealloc_start, cl_prealloc_length);
++                retval = 0;
++        } else {
++                dev_err(dev, "Can not support %s@%d!\n", options, ssret);
++        }
++
++ambfb_setup_exit:
++        return retval;
++}
++
++static int ambfb_probe(struct platform_device *pdev)
++{
++        int                                errorCode = 0;
++        struct fb_info                     *info;
++        char                               fb_name[64];
++        char                               *option;
++        struct ambarella_platform_fb       *ambfb_data = NULL;
++        u32                                i, framesize, line_length;
++
++        ambfb_data = ambfb_data_ptr[pdev->id];
++
++        snprintf(fb_name, sizeof(fb_name), "amb%dfb", pdev->id);
++        if (fb_get_options(fb_name, &option)) {
++                dev_err(&pdev->dev, "%s: get fb options fail!\n", __func__);
++                errorCode = -ENODEV;
++                goto ambfb_probe_exit;
++        }
++        if (ambfb_setup(&pdev->dev, option, ambfb_data)) {
++                errorCode = -ENODEV;
++                goto ambfb_probe_exit;
++        }
++
++        info = framebuffer_alloc(sizeof(ambfb_data), &pdev->dev);
++        if (info == NULL) {
++                dev_err(&pdev->dev, "%s: framebuffer_alloc fail!\n", __func__);
++                errorCode = -ENOMEM;
++                goto ambfb_probe_exit;
++        }
++
++        if(get_ambarella_fbmem_size()) {
++                ambfb_data->use_prealloc = 1;
++                ambfb_data->conversion_buf.available = 1;
++                if((ambfb_data->screen_fix.smem_start == 0) ||
++                        (ambfb_data->screen_fix.smem_len == 0) ||
++                        (ambfb_data->screen_fix.smem_len > get_ambarella_fbmem_size())) {
++                        errorCode = -EINVAL;
++                        dev_err(&pdev->dev, "please set right fbmem start address in dts file\n");
++                        goto ambfb_probe_release_framebuffer;
++                }
++        } else {
++                ambfb_data->use_prealloc = 0;
++                ambfb_data->conversion_buf.available = 0;
++        }
++
++        mutex_lock(&ambfb_data->lock);
++
++        info->fbops = &ambfb_ops;
++        info->par = ambfb_data;
++        info->var = ambfb_data->screen_var;
++        info->fix = ambfb_data->screen_fix;
++        info->flags = FBINFO_FLAG_DEFAULT;
++
++        /* Fill Color-related Variables */
++        for (i = 0; i < ARRAY_SIZE(ambarella_fb_color_format_table); i++) {
++                if (ambarella_fb_color_format_table[i].color_format ==
++                    ambfb_data->color_format)
++                        break;
++        }
++        if (i < ARRAY_SIZE(ambarella_fb_color_format_table)) {
++                info->var.bits_per_pixel =
++                        ambarella_fb_color_format_table[i].bits_per_pixel;
++                info->var.red = ambarella_fb_color_format_table[i].red;
++                info->var.green = ambarella_fb_color_format_table[i].green;
++                info->var.blue = ambarella_fb_color_format_table[i].blue;
++                info->var.transp = ambarella_fb_color_format_table[i].transp;
++        } else {
++                dev_err(&pdev->dev, "%s: do not support color formate:%d!\n",
++                        __func__, ambfb_data->color_format);
++                errorCode = -EINVAL;
++                goto ambfb_probe_release_framebuffer;
++        }
++
++        /* Malloc Framebuffer Memory */
++        line_length = (info->var.xres_virtual *
++                       (info->var.bits_per_pixel / 8) + 31) & 0xffffffe0;
++        if (ambfb_data->use_prealloc == 0) {
++                info->fix.line_length = line_length;
++        } else {
++                info->fix.line_length =
++                        (line_length > ambfb_data->prealloc_line_length) ?
++                        line_length : ambfb_data->prealloc_line_length;
++        }
++
++        framesize = info->fix.line_length * info->var.yres_virtual;
++        if (framesize % PAGE_SIZE) {
++                framesize /= PAGE_SIZE;
++                framesize++;
++                framesize *= PAGE_SIZE;
++        }
++
++        if (ambfb_data->use_prealloc == 0) {
++                info->screen_base = kzalloc(framesize, GFP_KERNEL);
++                if (info->screen_base == NULL) {
++                        dev_err(&pdev->dev, "%s(%d): Can't get %d bytes fbmem!\n",
++                                __func__, __LINE__, framesize);
++                        errorCode = -ENOMEM;
++                        goto ambfb_probe_release_framebuffer;
++                }
++                info->fix.smem_start = virt_to_phys(info->screen_base);
++                info->fix.smem_len = framesize;
++        } else {
++                if ((info->fix.smem_start == 0) ||
++                    (info->fix.smem_len < framesize)) {
++                        dev_err(&pdev->dev, "%s: prealloc[0x%08x < 0x%08x]!\n",
++                                __func__, info->fix.smem_len, framesize);
++                        errorCode = -ENOMEM;
++                        goto ambfb_probe_release_framebuffer;
++                }
++
++                info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
++                memset(info->screen_base, 0, info->fix.smem_len);
++                if (!info->screen_base) {
++                        dev_err(&pdev->dev, "%s: ioremap() failed\n", __func__);
++                        errorCode = -ENOMEM;
++                        goto ambfb_probe_exit;
++                }
++
++                if (ambfb_data->conversion_buf.available) {
++                        ambfb_data->conversion_buf.base_buf_phy =
++                                ambfb_data->screen_fix.smem_start;
++                }
++        }
++
++        errorCode = fb_alloc_cmap(&info->cmap, 256, 1);
++        if (errorCode < 0) {
++                dev_err(&pdev->dev, "%s: fb_alloc_cmap fail!\n", __func__);
++                errorCode = -ENOMEM;
++                goto ambfb_probe_release_framebuffer;
++        }
++        for (i = info->cmap.start; i < info->cmap.len; i++) {
++                info->cmap.red[i] = i << 8;
++                info->cmap.green[i] = 128 << 8;
++                info->cmap.blue[i] = 128 << 8;
++                if (info->cmap.transp)
++                        info->cmap.transp[i] = 12 << 8;
++        }
++
++        platform_set_drvdata(pdev, info);
++        ambfb_data->fb_status = AMBFB_ACTIVE_MODE;
++        mutex_unlock(&ambfb_data->lock);
++
++        errorCode = register_framebuffer(info);
++        if (errorCode < 0) {
++                dev_err(&pdev->dev, "%s: register_framebuffer fail!\n",
++                        __func__);
++                errorCode = -ENOMEM;
++                mutex_lock(&ambfb_data->lock);
++                goto ambfb_probe_dealloc_cmap;
++        }
++
++        ambfb_data->proc_fb_info = info;
++
++#ifdef CONFIG_PROC_FS
++        ambfb_data->proc_file = proc_create_data(dev_name(&pdev->dev),
++                                                 (S_IRUGO | S_IWUSR), get_ambarella_proc_dir(),
++                                                 &ambarella_fb_fops, ambfb_data);
++        if (ambfb_data->proc_file == NULL) {
++                errorCode = -ENOMEM;
++                goto ambfb_probe_unregister_framebuffer;
++        }
++#endif
++
++        mutex_lock(&ambfb_data->lock);
++        ambfb_data->screen_var = info->var;
++        ambfb_data->screen_fix = info->fix;
++        mutex_unlock(&ambfb_data->lock);
++
++        dev_info(&pdev->dev,
++                 "probe p[%dx%d] v[%dx%d] c[%d] b[%d] l[%d] @ [0x%08lx:0x%08x],base:0x%p!\n",
++                 info->var.xres, info->var.yres, info->var.xres_virtual,
++                 info->var.yres_virtual, ambfb_data->color_format,
++                 ambfb_data->conversion_buf.available,
++                 info->fix.line_length,
++                 info->fix.smem_start, info->fix.smem_len, info->screen_base);
++        goto ambfb_probe_exit;
++
++ambfb_probe_unregister_framebuffer:
++        unregister_framebuffer(info);
++
++ambfb_probe_dealloc_cmap:
++        fb_dealloc_cmap(&info->cmap);
++
++ambfb_probe_release_framebuffer:
++        framebuffer_release(info);
++        ambfb_data->fb_status = AMBFB_STOP_MODE;
++        mutex_unlock(&ambfb_data->lock);
++
++ambfb_probe_exit:
++        return errorCode;
++}
++
++static int ambfb_remove(struct platform_device *pdev)
++{
++        struct fb_info				*info;
++        struct ambarella_platform_fb		*ambfb_data = NULL;
++
++        info = platform_get_drvdata(pdev);
++        if (info) {
++                ambfb_data = (struct ambarella_platform_fb *)info->par;
++
++#ifdef CONFIG_PROC_FS
++                proc_remove(ambfb_data->proc_file);
++#endif
++                unregister_framebuffer(info);
++
++                mutex_lock(&ambfb_data->lock);
++                ambfb_data->fb_status = AMBFB_STOP_MODE;
++                fb_dealloc_cmap(&info->cmap);
++                if (ambfb_data->use_prealloc == 0) {
++                        if (info->screen_base) {
++                                kfree(info->screen_base);
++                        }
++                        if (ambfb_data->conversion_buf.available) {
++                                if (ambfb_data->conversion_buf.ping_buf) {
++                                        kfree(ambfb_data->conversion_buf.ping_buf);
++                                }
++                                if (ambfb_data->conversion_buf.pong_buf) {
++                                        kfree(ambfb_data->conversion_buf.pong_buf);
++                                }
++                        }
++                        ambfb_data->screen_fix.smem_start = 0;
++                        ambfb_data->screen_fix.smem_len = 0;
++                }
++                framebuffer_release(info);
++                mutex_unlock(&ambfb_data->lock);
++        }
++
++        return 0;
++}
++
++#ifdef CONFIG_PM
++static int ambfb_suspend(struct platform_device *pdev, pm_message_t state)
++{
++        int					errorCode = 0;
++
++        dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++                __func__, errorCode, state.event);
++
++        return errorCode;
++}
++
++static int ambfb_resume(struct platform_device *pdev)
++{
++        int					errorCode = 0;
++
++        dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
++
++        return errorCode;
++}
++#endif
++
++static struct platform_driver ambfb_driver = {
++        .probe		= ambfb_probe,
++        .remove 	= ambfb_remove,
++#ifdef CONFIG_PM
++        .suspend        = ambfb_suspend,
++        .resume		= ambfb_resume,
++#endif
++        .driver = {
++                .name	= "ambarella-fb",
++        },
++};
++
++static struct platform_device ambarella_fb0 = {
++        .name			= "ambarella-fb",
++        .id			= 0,
++};
++
++static struct platform_device ambarella_fb1 = {
++        .name			= "ambarella-fb",
++        .id			= 1,
++};
++
++static int __init ambavoutfb_init(void)
++{
++        platform_device_register(&ambarella_fb0);
++        platform_device_register(&ambarella_fb1);
++        return platform_driver_register(&ambfb_driver);
++}
++
++static void __exit ambavoutfb_exit(void)
++{
++        platform_driver_unregister(&ambfb_driver);
++        platform_device_unregister(&ambarella_fb1);
++        platform_device_unregister(&ambarella_fb0);
++}
++
++MODULE_LICENSE("GPL");
++module_init(ambavoutfb_init);
++module_exit(ambavoutfb_exit);
++
+diff --git a/drivers/video/ambarella/ambarella_fb_tbl.c b/drivers/video/ambarella/ambarella_fb_tbl.c
+new file mode 100644
+index 00000000..65e88057
+--- /dev/null
++++ b/drivers/video/ambarella/ambarella_fb_tbl.c
+@@ -0,0 +1,622 @@
++
++struct ambarella_fb_color_table {
++	enum ambarella_fb_color_format	color_format;
++	int				bits_per_pixel;
++	struct fb_bitfield		red;
++	struct fb_bitfield		green;
++	struct fb_bitfield		blue;
++	struct fb_bitfield		transp;
++};
++
++static const struct ambarella_fb_color_table ambarella_fb_color_format_table[] =
++{
++	{
++		.color_format = AMBFB_COLOR_CLUT_8BPP,
++		.bits_per_pixel = 8,
++		.red =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_RGB565,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 11,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 5,
++				.length = 6,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_BGR565,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 5,
++				.length = 6,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 11,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_AGBR4444,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 0,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 8,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 4,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 12,
++				.length = 4,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_RGBA4444,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 12,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 8,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 4,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 4,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_BGRA4444,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 4,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 8,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 12,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 4,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_ABGR4444,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 0,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 4,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 8,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 12,
++				.length = 4,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_ARGB4444,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 8,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 4,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 0,
++				.length = 4,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 12,
++				.length = 4,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_AGBR1555,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 10,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 5,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 15,
++				.length = 1,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_GBR1555,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 10,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 5,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_RGBA5551,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 11,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 6,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 1,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 1,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_BGRA5551,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 1,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 6,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 11,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 1,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_ABGR1555,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 5,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 10,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 15,
++				.length = 1,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_ARGB1555,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 10,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 5,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 15,
++				.length = 1,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_AGBR8888,
++		.bits_per_pixel = 32,
++		.red =
++			{
++				.offset = 0,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 16,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 8,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 24,
++				.length = 8,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_RGBA8888,
++		.bits_per_pixel = 32,
++		.red =
++			{
++				.offset = 24,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 16,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 8,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 8,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_BGRA8888,
++		.bits_per_pixel = 32,
++		.red =
++			{
++				.offset = 8,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 16,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 24,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 8,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_ABGR8888,
++		.bits_per_pixel = 32,
++		.red =
++			{
++				.offset = 0,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 8,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 16,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 24,
++				.length = 8,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_ARGB8888,
++		.bits_per_pixel = 32,
++		.red =
++			{
++				.offset = 16,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 8,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 0,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 24,
++				.length = 8,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_AYUV8888,
++		.bits_per_pixel = 32,
++		.red =
++			{
++				.offset = 0,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 16,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 8,
++				.length = 8,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 24,
++				.length = 8,
++				.msb_right = 0,
++		},
++	},
++
++	{
++		.color_format = AMBFB_COLOR_VYU565,
++		.bits_per_pixel = 16,
++		.red =
++			{
++				.offset = 11,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.green =
++			{
++				.offset = 5,
++				.length = 6,
++				.msb_right = 0,
++			},
++		.blue =
++			{
++				.offset = 0,
++				.length = 5,
++				.msb_right = 0,
++			},
++		.transp =
++			{
++				.offset = 0,
++				.length = 0,
++				.msb_right = 0,
++		},
++	},
++};
++
+diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
+index 9e5517a3..d6f69981 100644
+--- a/drivers/video/backlight/wm831x_bl.c
++++ b/drivers/video/backlight/wm831x_bl.c
+@@ -205,6 +205,8 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	bl->props.brightness = max_isel;
++	bl->props.power = FB_BLANK_UNBLANK;
++	bl->props.fb_blank = FB_BLANK_UNBLANK;
+ 
+ 	platform_set_drvdata(pdev, bl);
+ 
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index e89fc313..60f5b635 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -115,6 +115,14 @@ config ARM_SP805_WATCHDOG
+ 	  ARM Primecell SP805 Watchdog timer. This will reboot your system when
+ 	  the timeout is reached.
+ 
++config AMBARELLA_WATCHDOG
++	tristate "Ambarella watchdog"
++	depends on PLAT_AMBARELLA
++	select WATCHDOG_CORE
++	help
++	  Watchdog timer embedded into Ambarella chips. This will reboot your
++	  system when the timeout is reached.
++
+ config AT91RM9200_WATCHDOG
+ 	tristate "AT91RM9200 watchdog"
+ 	depends on ARCH_AT91RM9200
+diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
+index a300b948..9cce2fba 100644
+--- a/drivers/watchdog/Makefile
++++ b/drivers/watchdog/Makefile
+@@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
+ 
+ # ARM Architecture
+ obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
++obj-$(CONFIG_AMBARELLA_WATCHDOG) += ambarella_wdt.o
+ obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
+ obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
+ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
+diff --git a/drivers/watchdog/ambarella_wdt.c b/drivers/watchdog/ambarella_wdt.c
+new file mode 100644
+index 00000000..8dab7e7b
+--- /dev/null
++++ b/drivers/watchdog/ambarella_wdt.c
+@@ -0,0 +1,295 @@
++/*
++ * linux/drivers/mmc/host/ambarella_sd.c
++ *
++ * Copyright (C) 2006-2007, Ambarella, Inc.
++ *  Anthony Ginger, <hfjiang@ambarella.com>
++ *
++ * Ambarella Media Processor Watch Dog Timer
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/watchdog.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <plat/wdt.h>
++#include <plat/rct.h>
++
++
++#define AMBARELLA_WDT_MAX_CYCLE		0xffffffff
++
++static int heartbeat = -1; /* -1 means get value from FDT */
++module_param(heartbeat, int, 0);
++MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
++
++static bool nowayout = WATCHDOG_NOWAYOUT;
++module_param(nowayout, bool, 0);
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
++				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
++
++struct ambarella_wdt {
++	void __iomem	 		*regbase;
++	struct clk			*clk;
++	int				irq;
++	struct watchdog_device		wdd;
++	bool				enabled;
++	u32				timeout; /* in cycle */
++};
++
++static int ambarella_wdt_start(struct watchdog_device *wdd)
++{
++	struct ambarella_wdt *ambwdt;
++	u32 ctrl_val;
++
++	ambwdt = watchdog_get_drvdata(wdd);
++	ambwdt->enabled = true;
++
++	ctrl_val = ambwdt->irq > 0 ? WDOG_CTR_INT_EN : WDOG_CTR_RST_EN;
++	ctrl_val |= WDOG_CTR_EN;
++
++	if (ambwdt->irq > 0)
++		amba_writel(ambwdt->regbase + WDOG_RST_WD_OFFSET, 0x00);
++	else
++		amba_writel(ambwdt->regbase + WDOG_RST_WD_OFFSET, 0xFF);
++
++	amba_writel(ambwdt->regbase + WDOG_CONTROL_OFFSET, ctrl_val);
++
++	return 0;
++}
++
++static int ambarella_wdt_stop(struct watchdog_device *wdd)
++{
++	struct ambarella_wdt *ambwdt;
++
++	ambwdt = watchdog_get_drvdata(wdd);
++	ambwdt->enabled = false;
++
++	amba_writel(ambwdt->regbase + WDOG_CONTROL_OFFSET, 0);
++
++	return 0;
++}
++
++static int ambarella_wdt_keepalive(struct watchdog_device *wdd)
++{
++	struct ambarella_wdt *ambwdt = watchdog_get_drvdata(wdd);
++
++	amba_writel(ambwdt->regbase + WDOG_RELOAD_OFFSET, ambwdt->timeout);
++	amba_writel(ambwdt->regbase + WDOG_RESTART_OFFSET, WDT_RESTART_VAL);
++
++	return 0;
++}
++
++static int ambarella_wdt_set_timeout(struct watchdog_device *wdd, u32 time)
++{
++	struct ambarella_wdt *ambwdt = watchdog_get_drvdata(wdd);
++	u32 freq;
++
++	wdd->timeout = time;
++
++	freq = clk_get_rate(clk_get(NULL, "gclk_apb"));
++	ambwdt->timeout = time * freq;
++	amba_writel(ambwdt->regbase + WDOG_RELOAD_OFFSET, ambwdt->timeout);
++
++	return 0;
++}
++
++static irqreturn_t ambarella_wdt_irq(int irq, void *devid)
++{
++	struct ambarella_wdt *ambwdt = devid;
++
++	amba_writel(ambwdt->regbase + WDOG_CLR_TMO_OFFSET, 0x01);
++
++	dev_info(ambwdt->wdd.dev, "Watchdog timer expired!\n");
++
++	return IRQ_HANDLED;
++}
++
++static const struct watchdog_info ambwdt_info = {
++	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
++	.identity = "Ambarella Watchdog",
++};
++
++static const struct watchdog_ops ambwdt_ops = {
++	.owner		= THIS_MODULE,
++	.start		= ambarella_wdt_start,
++	.stop		= ambarella_wdt_stop,
++	.ping		= ambarella_wdt_keepalive,
++	.set_timeout	= ambarella_wdt_set_timeout,
++};
++
++static int ambarella_wdt_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct ambarella_wdt *ambwdt;
++	struct resource *mem;
++	void __iomem *reg;
++	int max_timeout, rval = 0;
++
++	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "Get WDT mem resource failed!\n");
++		return -ENXIO;
++	}
++
++	reg = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
++	if (!reg) {
++		dev_err(&pdev->dev, "devm_ioremap() failed\n");
++		return -ENOMEM;
++	}
++
++	ambwdt = devm_kzalloc(&pdev->dev, sizeof(*ambwdt), GFP_KERNEL);
++	if (ambwdt == NULL) {
++		dev_err(&pdev->dev, "Out of memory!\n");
++		return -ENOMEM;
++	}
++
++	ambwdt->regbase = reg;
++
++	/* irq < 0 means to disable interrupt mode */
++	ambwdt->irq = platform_get_irq(pdev, 0);
++	if (ambwdt->irq > 0) {
++		rval = devm_request_irq(&pdev->dev, ambwdt->irq,
++					ambarella_wdt_irq, IRQF_TRIGGER_RISING,
++					dev_name(&pdev->dev), ambwdt);
++		if (rval < 0) {
++			dev_err(&pdev->dev, "Request IRQ failed!\n");
++			return -ENXIO;
++		}
++	}
++
++	ambwdt->clk = clk_get(NULL, "gclk_apb");
++	if (IS_ERR(ambwdt->clk)) {
++		dev_err(&pdev->dev, "no clk for wdt!\n");
++		return -ENODEV;
++	}
++
++	max_timeout = AMBARELLA_WDT_MAX_CYCLE / clk_get_rate(ambwdt->clk);
++
++	ambwdt->wdd.info = &ambwdt_info;
++	ambwdt->wdd.ops = &ambwdt_ops;
++	ambwdt->wdd.min_timeout = 0;
++	ambwdt->wdd.max_timeout = max_timeout;
++	ambwdt->wdd.bootstatus = amba_readl(WDT_RST_L_REG) ? 0 : WDIOF_CARDRESET;
++
++	if (!of_find_property(np, "amb,non-bootstatus", NULL)) {
++		/* WDT_RST_L_REG cannot be restored by "reboot" command,
++		 * so reset it manually */
++		amba_setbitsl(UNLOCK_WDT_RST_L_REG, UNLOCK_WDT_RST_L_VAL);
++		amba_writel(WDT_RST_L_REG, 0x1);
++		amba_clrbitsl(UNLOCK_WDT_RST_L_REG, UNLOCK_WDT_RST_L_VAL);
++	}
++
++	watchdog_init_timeout(&ambwdt->wdd, heartbeat, &pdev->dev);
++	watchdog_set_nowayout(&ambwdt->wdd, nowayout);
++	watchdog_set_drvdata(&ambwdt->wdd, ambwdt);
++
++	ambarella_wdt_set_timeout(&ambwdt->wdd, ambwdt->wdd.timeout);
++	ambarella_wdt_stop(&ambwdt->wdd);
++
++	rval = watchdog_register_device(&ambwdt->wdd);
++	if (rval < 0) {
++		dev_err(&pdev->dev, "failed to register wdt!\n");
++		return rval;
++	}
++
++	platform_set_drvdata(pdev, ambwdt);
++
++	dev_notice(&pdev->dev, "Ambarella Watchdog Timer Probed.\n");
++
++	return 0;
++}
++
++static int ambarella_wdt_remove(struct platform_device *pdev)
++{
++	struct ambarella_wdt *ambwdt;
++	int rval = 0;
++
++	ambwdt = platform_get_drvdata(pdev);
++
++	ambarella_wdt_stop(&ambwdt->wdd);
++	watchdog_unregister_device(&ambwdt->wdd);
++
++	dev_notice(&pdev->dev, "Remove Ambarella Watchdog Timer.\n");
++
++	return rval;
++}
++
++static void ambarella_wdt_shutdown(struct platform_device *pdev)
++{
++	struct ambarella_wdt *ambwdt;
++
++	ambwdt = platform_get_drvdata(pdev);
++	ambarella_wdt_stop(&ambwdt->wdd);
++
++	dev_info(&pdev->dev, "%s @ %d.\n", __func__, system_state);
++}
++
++#ifdef CONFIG_PM
++
++static int ambarella_wdt_suspend(struct platform_device *pdev,
++			pm_message_t state)
++{
++	struct ambarella_wdt *ambwdt;
++	int rval = 0;
++
++	ambwdt = platform_get_drvdata(pdev);
++
++	if (watchdog_active(&ambwdt->wdd))
++		ambarella_wdt_stop(&ambwdt->wdd);
++
++	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
++				__func__, rval, state.event);
++
++	return rval;
++}
++
++static int ambarella_wdt_resume(struct platform_device *pdev)
++{
++	struct ambarella_wdt *ambwdt;
++	int rval = 0;
++
++	ambwdt = platform_get_drvdata(pdev);
++
++	if (watchdog_active(&ambwdt->wdd)) {
++		ambarella_wdt_start(&ambwdt->wdd);
++		ambarella_wdt_keepalive(&ambwdt->wdd);
++	}
++
++	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, rval);
++
++	return rval;
++}
++#endif
++
++static const struct of_device_id ambarella_wdt_dt_ids[] = {
++	{.compatible = "ambarella,wdt", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambarella_wdt_dt_ids);
++
++static struct platform_driver ambarella_wdt_driver = {
++	.probe		= ambarella_wdt_probe,
++	.remove		= ambarella_wdt_remove,
++	.shutdown	= ambarella_wdt_shutdown,
++#ifdef CONFIG_PM
++	.suspend	= ambarella_wdt_suspend,
++	.resume		= ambarella_wdt_resume,
++#endif
++	.driver		= {
++		.owner	= THIS_MODULE,
++		.name	= "ambarella-wdt",
++		.of_match_table = ambarella_wdt_dt_ids,
++	},
++};
++
++module_platform_driver(ambarella_wdt_driver);
++
++MODULE_DESCRIPTION("Ambarella Media Processor Watch Dog Timer");
++MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
+index 9dcb6d08..98fcb249 100644
+--- a/drivers/watchdog/wm831x_wdt.c
++++ b/drivers/watchdog/wm831x_wdt.c
+@@ -283,6 +283,11 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
+ 
+ 	dev_set_drvdata(&pdev->dev, driver_data);
+ 
++	dev_notice(&pdev->dev,
++		"Wm831x PMIC Watch Dog Timer[%s].\n",
++		dev_name(&pdev->dev));
++
++
+ 	return 0;
+ 
+ err_gpio:
+diff --git a/include/linux/ambbus.h b/include/linux/ambbus.h
+new file mode 100644
+index 00000000..02050174
+--- /dev/null
++++ b/include/linux/ambbus.h
+@@ -0,0 +1,29 @@
++/*
++ * AMB bus.
++ */
++
++#ifndef __LINUX_AMBBUS_H
++#define __LINUX_AMBBUS_H
++
++#include <linux/device.h>
++#include <linux/kernel.h>
++
++struct amb_driver {
++	int (*match)(struct device *);
++	int (*probe)(struct device *);
++	int (*remove)(struct device *);
++	void (*shutdown)(struct device *);
++	int (*suspend)(struct device *, pm_message_t);
++	int (*resume)(struct device *);
++
++	struct device_driver driver;
++	struct device *devices;
++};
++
++#define to_amb_driver(x) container_of((x), struct amb_driver, driver)
++
++
++int amb_register_driver(struct amb_driver *);
++void amb_unregister_driver(struct amb_driver *);
++
++#endif /* __LINUX_AMBBUS_H */
+diff --git a/include/linux/ambpriv_device.h b/include/linux/ambpriv_device.h
+new file mode 100644
+index 00000000..6f1c70aa
+--- /dev/null
++++ b/include/linux/ambpriv_device.h
+@@ -0,0 +1,71 @@
++/*
++ * ambpriv_device.h
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Copyright (C) 2012-2016, Ambarella, Inc.
++ *
++ */
++
++#ifndef _AMBPRIV_DEVICE_H_
++#define _AMBPRIV_DEVICE_H_
++
++#include <linux/device.h>
++
++struct ambpriv_device {
++	const char	* name;
++	int		id;
++	struct device	dev;
++	u32		num_resources;
++	struct resource	* resource;
++
++	/* arch specific additions */
++	struct pdev_archdata	archdata;
++};
++
++#define to_ambpriv_device(x) container_of((x), struct ambpriv_device, dev)
++
++extern int ambpriv_device_register(struct ambpriv_device *);
++extern void ambpriv_device_unregister(struct ambpriv_device *);
++
++extern struct bus_type ambpriv_bus_type;
++extern struct device ambpriv_bus;
++
++extern int ambpriv_add_devices(struct ambpriv_device **, int);
++extern struct ambpriv_device *ambpriv_device_alloc(const char *name, int id);
++extern int ambpriv_device_add_resources(struct ambpriv_device *pdev,
++					 const struct resource *res,
++					 unsigned int num);
++extern int ambpriv_device_add_data(struct ambpriv_device *pdev, const void *data, size_t size);
++extern int ambpriv_device_add(struct ambpriv_device *pdev);
++extern void ambpriv_device_del(struct ambpriv_device *pdev);
++extern void ambpriv_device_put(struct ambpriv_device *pdev);
++
++extern struct ambpriv_device *of_find_ambpriv_device_by_match(struct of_device_id *match);
++extern struct ambpriv_device *of_find_ambpriv_device_by_node(struct device_node *np);
++extern int ambpriv_get_irq(struct ambpriv_device *dev, unsigned int num);
++extern int ambpriv_get_irq_by_name(struct ambpriv_device *dev, const char *name);
++
++struct ambpriv_driver {
++	int (*probe)(struct ambpriv_device *);
++	int (*remove)(struct ambpriv_device *);
++	void (*shutdown)(struct ambpriv_device *);
++	int (*suspend)(struct ambpriv_device *, pm_message_t state);
++	int (*resume)(struct ambpriv_device *);
++	struct device_driver driver;
++};
++
++extern int ambpriv_driver_register(struct ambpriv_driver *);
++extern void ambpriv_driver_unregister(struct ambpriv_driver *);
++
++#define ambpriv_get_drvdata(_dev)	dev_get_drvdata(&(_dev)->dev)
++#define ambpriv_set_drvdata(_dev,data)	dev_set_drvdata(&(_dev)->dev, (data))
++
++extern struct ambpriv_device *ambpriv_create_bundle(struct ambpriv_driver *driver,
++					struct resource *res, unsigned int n_res,
++					const void *data, size_t size);
++
++extern int ambpriv_i2c_update_addr(const char *name, int bus, int addr);
++
++#endif /* _PLATFORM_DEVICE_H_ */
++
+diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h
+index 7ffe03f4..12740525 100644
+--- a/include/linux/bitrev.h
++++ b/include/linux/bitrev.h
+@@ -5,11 +5,12 @@
+ 
+ extern u8 const byte_rev_table[256];
+ 
+-static inline u8 bitrev8(u8 byte)
++static inline u8 bitrev_by_table(u8 in)
+ {
+-	return byte_rev_table[byte];
++	return byte_rev_table[in];
+ }
+ 
++extern u8 bitrev8(u8 in);
+ extern u16 bitrev16(u16 in);
+ extern u32 bitrev32(u32 in);
+ 
+diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
+index 7a13848d..38eb5dbb 100644
+--- a/include/linux/ftrace.h
++++ b/include/linux/ftrace.h
+@@ -611,25 +611,27 @@ static inline void __ftrace_enabled_restore(int enabled)
+ #endif
+ }
+ 
+-#ifndef HAVE_ARCH_CALLER_ADDR
++/* All archs should have this, but we define it for consistency */
++#ifndef ftrace_return_address0
++# define ftrace_return_address0 __builtin_return_address(0)
++#endif
++
++/* Archs may use other ways for ADDR1 and beyond */
++#ifndef ftrace_return_address
+ # ifdef CONFIG_FRAME_POINTER
+-#  define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+-#  define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
+-#  define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
+-#  define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
+-#  define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
+-#  define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
+-#  define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
++#  define ftrace_return_address(n) __builtin_return_address(n)
+ # else
+-#  define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+-#  define CALLER_ADDR1 0UL
+-#  define CALLER_ADDR2 0UL
+-#  define CALLER_ADDR3 0UL
+-#  define CALLER_ADDR4 0UL
+-#  define CALLER_ADDR5 0UL
+-#  define CALLER_ADDR6 0UL
++#  define ftrace_return_address(n) 0UL
+ # endif
+-#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
++#endif
++
++#define CALLER_ADDR0 ((unsigned long)ftrace_return_address0)
++#define CALLER_ADDR1 ((unsigned long)ftrace_return_address(1))
++#define CALLER_ADDR2 ((unsigned long)ftrace_return_address(2))
++#define CALLER_ADDR3 ((unsigned long)ftrace_return_address(3))
++#define CALLER_ADDR4 ((unsigned long)ftrace_return_address(4))
++#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
++#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
+ 
+ #ifdef CONFIG_IRQSOFF_TRACER
+   extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
+diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
+index 68391116..0d908f49 100644
+--- a/include/linux/iio/iio.h
++++ b/include/linux/iio/iio.h
+@@ -13,6 +13,16 @@
+ #include <linux/device.h>
+ #include <linux/cdev.h>
+ #include <linux/iio/types.h>
++
++/**
++ * struct iio_mount_matrix - iio mounting matrix
++ * @rotation: 3 dimensional space rotation matrix defining sensor alignment with
++ *            main hardware
++ */
++struct iio_mount_matrix {
++	const char *rotation[9];
++};
++
+ /* IIO TODO LIST */
+ /*
+  * Provide means of adjusting timer accuracy.
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+index 5f4554b8..e36ae104 100644
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -103,6 +103,18 @@
+ 		(((__x) - ((__d) / 2)) / (__d));	\
+ }							\
+ )
++/*
++ * Same as above but for u64 dividends. divisor must be a 32-bit
++ * number.
++ */
++#define DIV_ROUND_CLOSEST_ULL(x, divisor)(		\
++{							\
++	typeof(divisor) __d = divisor;			\
++	unsigned long long _tmp = (x) + (__d) / 2;	\
++	do_div(_tmp, __d);				\
++	_tmp;						\
++}							\
++)
+ 
+ /*
+  * Multiplies an integer by a fraction, while avoiding unnecessary
+diff --git a/include/linux/mdio-gpio.h b/include/linux/mdio-gpio.h
+index 7c9fe3c2..fd43597c 100644
+--- a/include/linux/mdio-gpio.h
++++ b/include/linux/mdio-gpio.h
+@@ -17,6 +17,9 @@ struct mdio_gpio_platform_data {
+ 	/* GPIO numbers for bus pins */
+ 	unsigned int mdc;
+ 	unsigned int mdio;
++	unsigned int rst;
++
++	bool rst_active_low;
+ 
+ 	unsigned int phy_mask;
+ 	int irqs[PHY_MAX_ADDR];
+diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
+index 76c22648..c93d1e01 100644
+--- a/include/linux/mfd/wm831x/core.h
++++ b/include/linux/mfd/wm831x/core.h
+@@ -238,6 +238,18 @@
+ #define WM831X_ON_PIN_TO_SHIFT                       0  /* ON_PIN_TO - [1:0] */
+ #define WM831X_ON_PIN_TO_WIDTH                       2  /* ON_PIN_TO - [1:0] */
+ 
++/*
++ * R16398 (0x400E) - ON Source
++ */
++#define WM831X_ON_SOURCE_ALARM                  0x0020  /* ON_SOURCE_ALARM */
++#define WM831X_ON_SOURCE_ALARM_MASK				0x0020  /* ON_SOURCE_ALARM */
++#define WM831X_ON_SOURCE_ALARM_SHIFT				5  /* ON_SOURCE_ALARM */
++#define WM831X_ON_SOURCE_ALARM_WIDTH				1  /* ON_SOURCE_ALARM */
++#define WM831X_ON_SOURCE_ON_PIN					0x0010  /* ON_SOURCE_ON_PIN */
++#define WM831X_ON_SOURCE_ON_PIN_MASK			0x0010  /* ON_SOURCE_ON_PIN */
++#define WM831X_ON_SOURCE_ON_PIN_SHIFT				4  /* ON_SOURCE_ON_PIN */
++#define WM831X_ON_SOURCE_ON_PIN_WIDTH				1  /* ON_SOURCE_ON_PIN */
++
+ /*
+  * R16528 (0x4090) - Clock Control 1
+  */
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index ab636344..8152ba7f 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -549,6 +549,7 @@ struct nand_chip {
+ #define NAND_MFR_AMD		0x01
+ #define NAND_MFR_MACRONIX	0xc2
+ #define NAND_MFR_EON		0x92
++#define NAND_MFR_GD			0xc8
+ 
+ /* The maximum expected count of bytes in the NAND ID sequence */
+ #define NAND_MAX_ID_LEN 8
+diff --git a/include/linux/net.h b/include/linux/net.h
+index 65545ac6..d00f1f74 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -291,4 +291,17 @@ extern int kernel_sock_shutdown(struct socket *sock,
+ #define MODULE_ALIAS_NET_PF_PROTO_NAME(pf, proto, name) \
+ 	MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
+ 		     name)
++
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++#define SOCK_SEQ_UPDATE  	0xBADBEEF
++struct sock_sequence_update
++{
++	struct sock *sock;
++	unsigned short ident;
++	unsigned int seq;
++	unsigned int ack;
++	unsigned int seq_offset;
++	unsigned int ack_offset;
++};
++#endif
+ #endif	/* _LINUX_NET_H */
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 9e11039d..13048f9a 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -337,6 +337,7 @@ struct phy_device {
+ 	 * -1 means no interrupt
+ 	 */
+ 	int irq;
++	int irq_flags;
+ 
+ 	/* private data pointer */
+ 	/* For use by PHYs to maintain extra state */
+diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
+index f1b0dca6..942ef5e0 100644
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -22,6 +22,7 @@
+ #include <linux/slab.h>
+ #include <linux/scatterlist.h>
+ #include <linux/types.h>
++#include <linux/workqueue.h>
+ #include <linux/usb/ch9.h>
+ 
+ struct usb_ep;
+@@ -475,6 +476,7 @@ struct usb_gadget_ops {
+ 
+ /**
+  * struct usb_gadget - represents a usb slave device
++ * @work: (internal use) Workqueue to be used for sysfs_notify()
+  * @ops: Function pointers used to access hardware-specific operations.
+  * @ep0: Endpoint zero, used when reading or writing responses to
+  *	driver setup() requests
+@@ -520,6 +522,7 @@ struct usb_gadget_ops {
+  * device is acting as a B-Peripheral (so is_a_peripheral is false).
+  */
+ struct usb_gadget {
++	struct work_struct		work;
+ 	/* readonly to gadget driver */
+ 	const struct usb_gadget_ops	*ops;
+ 	struct usb_ep			*ep0;
+@@ -538,6 +541,7 @@ struct usb_gadget {
+ 	unsigned			out_epnum;
+ 	unsigned			in_epnum;
+ };
++#define work_to_gadget(w)	(container_of((w), struct usb_gadget, work))
+ 
+ static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
+ 	{ dev_set_drvdata(&gadget->dev, data); }
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 2317d122..1dbd6fac 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1661,8 +1661,15 @@ static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
+ /* Ungrab socket and destroy it, if it was the last reference. */
+ static inline void sock_put(struct sock *sk)
+ {
+-	if (atomic_dec_and_test(&sk->sk_refcnt))
++	if (atomic_dec_and_test(&sk->sk_refcnt)){
++		#ifdef CONFIG_WLAN_UPDATE_SEQ
++		extern struct sock_sequence_update ipv4_update;
++		if(ipv4_update.sock == sk){
++			ipv4_update.sock = NULL;
++		}
++		#endif
+ 		sk_free(sk);
++    }
+ }
+ 
+ extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+diff --git a/include/sound/ak7755_pdata.h b/include/sound/ak7755_pdata.h
+new file mode 100644
+index 00000000..1350b1db
+--- /dev/null
++++ b/include/sound/ak7755_pdata.h
+@@ -0,0 +1,19 @@
++/*
++ * ak7755_pdata.h  --  audio driver for ak4482
++ *
++ * Copyright (C) 2015 Asahi Kasei Microdevices Corporation
++ *  Author                Date        Revision
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *                      15/06/15	    1.0
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
++ */
++
++#ifndef _AK7755_PDADA_H
++#define _AK7755_PDADA_H
++
++struct ak7755_platform_data {
++	int pdn_gpio;
++};
++
++#endif
++
+diff --git a/include/sound/es8328.h b/include/sound/es8328.h
+new file mode 100644
+index 00000000..fdfc9461
+--- /dev/null
++++ b/include/sound/es8328.h
+@@ -0,0 +1,22 @@
++/*
++ * es8328.h  --  ES8328 Soc Audio driver
++ *
++ * Copyright 2011 Ambarella Ltd.
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++#ifndef __SOUND_ES8328_H
++#define __SOUND_ES8328_H
++
++struct es8328_platform_data {
++	unsigned int	power_pin;
++	unsigned int 	power_delay;
++};
++
++#endif
++
+diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
+index 1634dc6e..86c01011 100644
+--- a/kernel/power/hibernate.c
++++ b/kernel/power/hibernate.c
+@@ -678,7 +678,13 @@ int hibernate(void)
+ 		        flags |= SF_CRC32_MODE;
+ 
+ 		pr_debug("PM: writing image.\n");
++#ifdef CONFIG_ARCH_AMBARELLA
++		error = swsusp_write_mtd(flags);
++		if (error)
++			outer_resume();
++#else
+ 		error = swsusp_write(flags);
++#endif
+ 		swsusp_free();
+ 		if (!error)
+ 			power_down();
+diff --git a/kernel/power/power.h b/kernel/power/power.h
+index f770cad3..70db88d1 100644
+--- a/kernel/power/power.h
++++ b/kernel/power/power.h
+@@ -11,8 +11,19 @@ struct swsusp_info {
+ 	unsigned long		image_pages;
+ 	unsigned long		pages;
+ 	unsigned long		size;
++#ifdef CONFIG_ARCH_AMBARELLA
++	unsigned long		magic;
++	unsigned long		addr;
++	unsigned long		lzo_enable;
++	unsigned long		crc32;
++#endif
+ } __attribute__((aligned(PAGE_SIZE)));
+ 
++#ifdef CONFIG_ARCH_AMBARELLA
++int swsusp_write_mtd(int flags);
++#endif
++
++
+ #ifdef CONFIG_HIBERNATION
+ /* kernel/power/snapshot.c */
+ extern void __init hibernate_reserved_size_init(void);
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+index 91c04f16..655eff1f 100644
+--- a/kernel/power/snapshot.c
++++ b/kernel/power/snapshot.c
+@@ -1660,6 +1660,10 @@ static int init_header(struct swsusp_info *info)
+ 	info->pages = snapshot_get_image_size();
+ 	info->size = info->pages;
+ 	info->size <<= PAGE_SHIFT;
++#ifdef CONFIG_ARCH_AMBARELLA
++	info->magic = 0x0badbeef;
++	info->addr  = virt_to_phys(ambarella_cpu_resume);
++#endif
+ 	return init_header_complete(info);
+ }
+ 
+@@ -1677,6 +1681,10 @@ pack_pfns(unsigned long *buf, struct memory_bitmap *bm)
+ 		buf[j] = memory_bm_next_pfn(bm);
+ 		if (unlikely(buf[j] == BM_END_OF_MAP))
+ 			break;
++
++#ifdef CONFIG_ARCH_AMBARELLA
++		buf[j] = __pfn_to_phys(buf[j]);
++#endif
+ 		/* Save page key for data page (s390 only). */
+ 		page_key_read(buf + j);
+ 	}
+@@ -2353,3 +2361,8 @@ int restore_highmem(void)
+ 	return 0;
+ }
+ #endif /* CONFIG_HIGHMEM */
++
++
++#ifdef CONFIG_ARCH_AMBARELLA
++#include "../../arch/arm/mach-ambarella/hibernate.c"
++#endif
+diff --git a/lib/bitrev.c b/lib/bitrev.c
+index 39562034..9001fafa 100644
+--- a/lib/bitrev.c
++++ b/lib/bitrev.c
+@@ -42,9 +42,15 @@ const u8 byte_rev_table[256] = {
+ };
+ EXPORT_SYMBOL_GPL(byte_rev_table);
+ 
++u8 bitrev8(u8 byte)
++{
++	return bitrev_by_table(byte);
++}
++EXPORT_SYMBOL(bitrev8);
++
+ u16 bitrev16(u16 x)
+ {
+-	return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
++	return (bitrev_by_table(x & 0xff) << 8) | bitrev_by_table(x >> 8);
+ }
+ EXPORT_SYMBOL(bitrev16);
+ 
+@@ -57,3 +63,4 @@ u32 bitrev32(u32 x)
+ 	return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
+ }
+ EXPORT_SYMBOL(bitrev32);
++
+diff --git a/make.inc b/make.inc
+new file mode 100644
+index 00000000..5bc285f9
+--- /dev/null
++++ b/make.inc
+@@ -0,0 +1,125 @@
++##
++## kernel/linux/make.inc
++##
++## History:
++##    2012/06/01 - [Cao Rongrong] Created file
++##
++## Copyright 2008-2015 Ambarella Inc.  All Rights Reserved.
++##
++## This program is free software; you can redistribute it and/or
++## modify it under the terms of the GNU General Public License
++## as published by the Free Software Foundation; either version 2
++## of the License, or (at your option) any later version.
++## This program is distributed in the hope that it will be useful,
++## but WITHOUT ANY WARRANTY; without even the implied warranty of
++## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++## GNU General Public License for more details.
++##
++
++ifeq ($(CONFIG_LINUX_KERNEL_VERSION),"3.10")
++
++ARCH := arm
++export ARCH
++
++LOCAL_PATH:=$(call my-dir)
++
++#####
++
++.PHONY: linux
++
++linux: $(DOT_CONFIG)
++	@mkdir -p $(LINUX_OUT_DIR)
++	@if [ -f $(LINUX_OUT_DIR)/.config ]; then \
++		echo "Build Linux-$(CONFIG_LINUX_KERNEL_VERSION) with previous configuration ..."; \
++	else \
++		$(MAKE) $(AMBA_MAKE_PARA) defconfig_public_linux; \
++	fi
++	$(AMBA_MAKEFILE_V)$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) all
++	@if [ -n "$(KERNEL_INSTALL_PATH)" ]; then \
++		echo "Install Linux modules to $(KERNEL_INSTALL_PATH) ..."; \
++		mkdir -p $(KERNEL_INSTALL_PATH); \
++		$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) \
++			$(LINUX_INSTALL_FLAG) modules_install; \
++		find $(KERNEL_INSTALL_PATH)/lib/modules/ -name build | xargs -l1 rm -rf; \
++		find $(KERNEL_INSTALL_PATH)/lib/modules/ -name source | xargs -l1 rm -rf; \
++	fi
++	@cp -dpRf $(LINUX_OUT_DIR)/arch/arm/boot/Image $(KERNEL_OUT_DIR)/Image
++	@cp -dpRf $(LINUX_OUT_DIR)/arch/arm/boot/zImage $(KERNEL_OUT_DIR)/zImage
++	@echo "Build $@ Done."
++
++$(call add-target-into-build, linux)
++
++###
++
++.PHONY: menuconfig_public_linux
++
++menuconfig_public_linux: $(DOT_CONFIG)
++	@mkdir -p $(LINUX_OUT_DIR)
++	@$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) menuconfig
++
++###
++
++.PHONY: defconfig_public_linux
++
++defconfig_public_linux: $(DOT_CONFIG)
++	@echo "Build Linux-$(CONFIG_LINUX_KERNEL_VERSION) with $(KERNEL_DEFCONFIG) ..."
++	@mkdir -p $(LINUX_OUT_DIR)
++	@if [ -f $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_DEFCONFIG) ]; then \
++		cp -dpRf $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_DEFCONFIG) $(LINUX_OUT_DIR)/.config; \
++		$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) olddefconfig; \
++	else \
++		$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) $(KERNEL_DEFCONFIG); \
++	fi
++
++
++#####
++
++ifeq ($(CONFIG_KERNEL_DUAL_CPU),y)
++
++KERNEL_2NDCONFIG	:= $(shell echo $(CONFIG_KERNEL_2NDCONFIG_STRING))
++LINUX_OUT_DIR_2		:= $(KERNEL_OUT_DIR)/linux_$(strip \
++				$(shell echo $(KERNEL_2NDCONFIG) | \
++				sed -e s/ambarella_// -e s/_defconfig//))
++
++.PHONY: linux_2
++
++linux_2: $(DOT_CONFIG)
++	@mkdir -p $(LINUX_OUT_DIR_2)
++	@if [ -f $(LINUX_OUT_DIR_2)/.config ]; then \
++		echo "Build Linux_2 with previous configuration ..."; \
++	else \
++		$(MAKE) $(AMBA_MAKE_PARA) defconfig_public_linux_2; \
++	fi
++	$(AMBA_MAKEFILE_V)$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR_2) all
++	@cp -dpRf $(LINUX_OUT_DIR_2)/arch/arm/boot/Image $(KERNEL_OUT_DIR)/Image_2
++	@echo "Build $@ Done."
++
++$(call add-target-into-build, linux_2)
++
++###
++
++.PHONY: menuconfig_public_linux_2
++
++menuconfig_public_linux_2: $(DOT_CONFIG)
++	@mkdir -p $(LINUX_OUT_DIR_2)
++	@$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR_2) menuconfig
++
++###
++
++.PHONY: defconfig_public_linux_2
++
++defconfig_public_linux_2: $(DOT_CONFIG)
++	@echo "Build Linux_2 with $(KERNEL_2NDCONFIG) ..."
++	@mkdir -p $(LINUX_OUT_DIR_2)
++	@if [ -f $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_2NDCONFIG) ]; then \
++		cp -dpRf $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_2NDCONFIG) $(LINUX_OUT_DIR_2)/.config; \
++	else \
++		$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR_2) $(KERNEL_2NDCONFIG); \
++	fi
++
++endif
++
++#####
++
++endif
++
+diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
+index 0a327b66..417d98da 100644
+--- a/net/core/sysctl_net_core.c
++++ b/net/core/sysctl_net_core.c
+@@ -21,7 +21,8 @@
+ #include <net/net_ratelimit.h>
+ 
+ static int zero = 0;
+-static int one = 1;
++//to cease compile warning 
++//static int one = 1;
+ static int ushort_max = USHRT_MAX;
+ static int min_sndbuf = SOCK_MIN_SNDBUF;
+ static int min_rcvbuf = SOCK_MIN_RCVBUF;
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index 8603ca82..3d556791 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -639,3 +639,5 @@ config TCP_MD5SIG
+ 	  on the Internet.
+ 
+ 	  If unsure, say N.
++config WLAN_UPDATE_SEQ
++	bool "Ambarella cooperate with wlan to update socket sequence"
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index ea78ef5a..af88080f 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -211,17 +211,22 @@ static struct sock *icmp_sk(struct net *net)
+ static inline struct sock *icmp_xmit_lock(struct net *net)
+ {
+ 	struct sock *sk;
++	int counter = 0;
+ 
+ 	local_bh_disable();
+ 
+ 	sk = icmp_sk(net);
+ 
+-	if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
++	while (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
+ 		/* This can happen if the output path signals a
+ 		 * dst_link_failure() for an outgoing ICMP packet.
+ 		 */
+-		local_bh_enable();
+-		return NULL;
++		if (counter > 3) {
++			local_bh_enable();
++			pr_debug("%s = %d\n", __func__, counter);
++			return NULL;
++		}
++		counter++;
+ 	}
+ 	return sk;
+ }
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 57e74508..e4f3f054 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -80,6 +80,10 @@
+ #include <linux/netlink.h>
+ #include <linux/tcp.h>
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++extern int iphdr_updatebywlan(struct sock *sk, struct iphdr *iph);
++#endif
++
+ int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
+ EXPORT_SYMBOL(sysctl_ip_default_ttl);
+ 
+@@ -395,6 +399,9 @@ packet_routed:
+ 	}
+ 
+ 	ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1);
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	iphdr_updatebywlan(sk, iph);
++#endif
+ 
+ 	skb->priority = sk->sk_priority;
+ 	skb->mark = sk->sk_mark;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 5d4bd6ca..9e303857 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -302,6 +302,11 @@ EXPORT_SYMBOL(tcp_memory_allocated);
+ struct percpu_counter tcp_sockets_allocated;
+ EXPORT_SYMBOL(tcp_sockets_allocated);
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++struct sock_sequence_update ipv4_update = {0};
++EXPORT_SYMBOL(ipv4_update);
++#endif
++
+ /*
+  * TCP splice context
+  */
+@@ -532,6 +537,9 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 	int answ;
+ 	bool slow;
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	unsigned int sequence[3];
++#endif
+ 
+ 	switch (cmd) {
+ 	case SIOCINQ:
+@@ -576,6 +584,20 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+ 		else
+ 			answ = tp->write_seq - tp->snd_nxt;
+ 		break;
++
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	case SOCK_SEQ_UPDATE:
++		if (copy_from_user(sequence, (int __user *)arg, sizeof(sequence)))
++			return -EFAULT;
++
++
++		ipv4_update.sock = sk;
++		ipv4_update.ident = (u16)sequence[0];
++		ipv4_update.seq = sequence[1];
++		ipv4_update.ack = sequence[2];
++
++		return 0;
++#endif
+ 	default:
+ 		return -ENOIOCTLCMD;
+ 	}
+@@ -584,6 +606,44 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+ }
+ EXPORT_SYMBOL(tcp_ioctl);
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++int tcphr_updatebywlan(struct sock *sk, struct tcphdr *th, struct sk_buff *skb)
++{
++	if (ipv4_update.sock != sk)
++		return 0;
++
++	if (ipv4_update.seq > 0){
++		ipv4_update.seq_offset = ipv4_update.seq - ntohl(th->seq);
++		ipv4_update.seq = 0;
++	}
++
++	if (ipv4_update.ack > 0){
++		ipv4_update.ack_offset = ipv4_update.ack - ntohl(th->ack_seq);
++		ipv4_update.ack = 0;
++	}
++
++	th->seq = htonl(ipv4_update.seq_offset + ntohl(th->seq));
++	th->ack_seq = htonl(ipv4_update.ack_offset + ntohl(th->ack_seq));
++
++	return 0;
++}
++
++EXPORT_SYMBOL(tcphr_updatebywlan);
++
++int iphdr_updatebywlan(struct sock *sk, struct iphdr *iph)
++{
++	if (ipv4_update.sock != sk)
++		return 0;
++
++	if (ipv4_update.ident > 0) {
++		iph->id = htons(ipv4_update.ident);
++		ipv4_update.ident = 0;
++	}
++	return 0;
++}
++EXPORT_SYMBOL(iphdr_updatebywlan);
++#endif
++
+ static inline void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb)
+ {
+ 	TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
+diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
+index 894b7cea..872b3a07 100644
+--- a/net/ipv4/tcp_cubic.c
++++ b/net/ipv4/tcp_cubic.c
+@@ -153,6 +153,27 @@ static void bictcp_init(struct sock *sk)
+ 		tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
+ }
+ 
++static void bictcp_cwnd_event(struct sock *sk, enum tcp_ca_event event)
++{
++	if (event == CA_EVENT_TX_START) {
++		struct bictcp *ca = inet_csk_ca(sk);
++		u32 now = tcp_time_stamp;
++		s32 delta;
++
++		delta = now - tcp_sk(sk)->lsndtime;
++
++		/* We were application limited (idle) for a while.
++		 * Shift epoch_start to keep cwnd growth to cubic curve.
++		 */
++		if (ca->epoch_start && delta > 0) {
++			ca->epoch_start += delta;
++			if (after(ca->epoch_start, now))
++				ca->epoch_start = now;
++		}
++		return;
++	}
++}
++
+ /* calculate the cubic root of x using a table lookup followed by one
+  * Newton-Raphson iteration.
+  * Avg err ~= 0.195%
+@@ -439,6 +460,7 @@ static struct tcp_congestion_ops cubictcp __read_mostly = {
+ 	.cong_avoid	= bictcp_cong_avoid,
+ 	.set_state	= bictcp_state,
+ 	.undo_cwnd	= bictcp_undo_cwnd,
++	.cwnd_event	= bictcp_cwnd_event,
+ 	.pkts_acked     = bictcp_acked,
+ 	.owner		= THIS_MODULE,
+ 	.name		= "cubic",
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index f3b15bb7..d78de1b6 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -76,6 +76,11 @@
+ #include <asm/unaligned.h>
+ #include <net/netdma.h>
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++extern struct sock_sequence_update ipv4_update;
++struct tcphdr th_copy;
++#endif
++
+ int sysctl_tcp_timestamps __read_mostly = 1;
+ int sysctl_tcp_window_scaling __read_mostly = 1;
+ int sysctl_tcp_sack __read_mostly = 1;
+@@ -5114,13 +5119,29 @@ discard:
+  *	the rest is checked inline. Fast processing is turned on in
+  *	tcp_data_queue when everything is OK.
+  */
++
++#ifndef CONFIG_WLAN_UPDATE_SEQ
+ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
+ 			const struct tcphdr *th, unsigned int len)
++#else
++int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
++			const struct tcphdr *t, unsigned int len)
++#endif
+ {
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	struct tcphdr *th = &th_copy;
++	memcpy(th, t, sizeof(struct tcphdr));
++	if (sk == ipv4_update.sock) {
++		th->seq -= ipv4_update.ack_offset;
++		th->ack_seq -= ipv4_update.seq_offset;
++	}
++#endif
++
+ 	if (unlikely(sk->sk_rx_dst == NULL))
+ 		inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb);
++
+ 	/*
+ 	 *	Header prediction.
+ 	 *	The code loosely follows the one in the famous
+@@ -5639,14 +5660,28 @@ reset_and_undo:
+  *	address independent.
+  */
+ 
++#ifndef CONFIG_WLAN_UPDATE_SEQ
+ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
+ 			  const struct tcphdr *th, unsigned int len)
++#else
++int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
++			  const struct tcphdr *t, unsigned int len)
++#endif
+ {
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 	struct inet_connection_sock *icsk = inet_csk(sk);
+ 	struct request_sock *req;
+ 	int queued = 0;
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	struct tcphdr *th = &th_copy;
++	memcpy(th, t, sizeof(struct tcphdr));
++	if (sk == ipv4_update.sock) {
++		th->seq -= ipv4_update.ack_offset;
++		th->ack_seq -= ipv4_update.seq_offset;
++	}
++#endif
++
+ 	tp->rx_opt.saw_tstamp = 0;
+ 
+ 	switch (sk->sk_state) {
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 11f27a45..6c33acb8 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -89,6 +89,9 @@ int sysctl_tcp_tw_reuse __read_mostly;
+ int sysctl_tcp_low_latency __read_mostly;
+ EXPORT_SYMBOL(sysctl_tcp_low_latency);
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++extern struct sock_sequence_update ipv4_update;
++#endif
+ 
+ #ifdef CONFIG_TCP_MD5SIG
+ static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
+@@ -2007,6 +2010,16 @@ int tcp_v4_rcv(struct sk_buff *skb)
+ 	if (!sk)
+ 		goto no_tcp_socket;
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	if (ipv4_update.sock && sk == ipv4_update.sock){
++
++		TCP_SKB_CB(skb)->seq = ntohl(th->seq) - ipv4_update.ack_offset;
++		TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
++				skb->len - th->doff * 4);
++		TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq) - ipv4_update.seq_offset;
++	}
++#endif
++
+ process:
+ 	if (sk->sk_state == TCP_TIME_WAIT)
+ 		goto do_time_wait;
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 276b2830..5eb597c1 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -42,6 +42,10 @@
+ #include <linux/gfp.h>
+ #include <linux/module.h>
+ 
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++extern int tcphr_updatebywlan(struct sock *sk, struct tcphdr *th, struct sk_buff *skb);
++#endif
++
+ /* People can turn this off for buggy TCP's found in printers etc. */
+ int sysctl_tcp_retrans_collapse __read_mostly = 1;
+ 
+@@ -909,6 +913,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
+ 	th->dest		= inet->inet_dport;
+ 	th->seq			= htonl(tcb->seq);
+ 	th->ack_seq		= htonl(tp->rcv_nxt);
++
++#ifdef CONFIG_WLAN_UPDATE_SEQ
++	tcphr_updatebywlan(sk, th, skb);
++#endif
+ 	*(((__be16 *)th) + 6)	= htons(((tcp_header_size >> 2) << 12) |
+ 					tcb->tcp_flags);
+ 
+diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
+index 9e675c76..625926c6 100644
+--- a/sound/soc/Kconfig
++++ b/sound/soc/Kconfig
+@@ -34,6 +34,7 @@ config SND_SOC_GENERIC_DMAENGINE_PCM
+ 	select SND_SOC_DMAENGINE_PCM
+ 
+ # All the supported SoCs
++source "sound/soc/ambarella/Kconfig"
+ source "sound/soc/atmel/Kconfig"
+ source "sound/soc/au1x/Kconfig"
+ source "sound/soc/blackfin/Kconfig"
+diff --git a/sound/soc/Makefile b/sound/soc/Makefile
+index 197b6ae5..af5c265c 100644
+--- a/sound/soc/Makefile
++++ b/sound/soc/Makefile
+@@ -10,6 +10,7 @@ snd-soc-core-objs += soc-generic-dmaengine-pcm.o
+ endif
+ 
+ obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
++obj-$(CONFIG_SND_SOC)	+= ambarella/
+ obj-$(CONFIG_SND_SOC)	+= codecs/
+ obj-$(CONFIG_SND_SOC)	+= generic/
+ obj-$(CONFIG_SND_SOC)	+= atmel/
+diff --git a/sound/soc/ambarella/Kconfig b/sound/soc/ambarella/Kconfig
+new file mode 100644
+index 00000000..85fc1a68
+--- /dev/null
++++ b/sound/soc/ambarella/Kconfig
+@@ -0,0 +1,109 @@
++config SND_AMBARELLA_SOC
++	tristate "SoC Audio for the Ambarella chips"
++	depends on PLAT_AMBARELLA && SND_SOC
++	select SND_SOC_GENERIC_DMAENGINE_PCM
++	help
++	  Say Y or M if you want to add support for codecs attached to
++	  the AMBARELLA I2S interface. You will also need
++	  to select the audio interfaces to support below.
++
++config SND_AMBARELLA_SOC_I2S
++	tristate
++
++menuconfig SND_AMBARELLA_BOARD
++	tristate "Ambarella Board Type"
++	depends on SND_AMBARELLA_SOC
++	help
++	  Say Y or M to select specific ambarella board.
++
++if SND_AMBARELLA_BOARD
++
++config AMBA_BOARD
++	tristate "Ambarella General Board"
++	depends on SND_AMBARELLA_SOC
++	select SND_AMBARELLA_SOC_I2S
++	select SND_SOC_AMBARELLA_DUMMY
++	help
++	  Say Y if you want to use ALSA driver on Ambarella General Board.
++
++endif
++
++menuconfig SND_AMBARELLA_CODEC
++	tristate "Select Codec for Ambarella Platform"
++	depends on SND_AMBARELLA_SOC
++	help
++	  Say Y or M to select specific Codec for Ambarella Platform.
++
++if SND_AMBARELLA_CODEC
++
++config SND_SOC_AK4642_AMB
++	tristate "AK4642 for Ambarella Platform"
++	help
++		Support AK4642 for Ambarella Platform.
++
++config SND_SOC_AK4951_AMB
++	tristate "AK4951 for Ambarella Platform"
++	help
++		Support AK4951 for Ambarella Platform.
++
++config SND_SOC_AK4954_AMB
++	tristate "AK4954 for Ambarella Platform"
++	help
++		Support AK4951 for Ambarella Platform.
++
++config SND_SOC_AK7719_DSP
++	tristate "AK7719_DSP for Ambarella Platform"
++	depends on SND_AMBARELLA_SOC && (SND_SOC_AK4954_AMB || SND_SOC_AK4951_AMB)
++	help
++	  Say Y if you want to add AK7719 DSP support for
++	  SoC audio on Ambarella Board.
++	  and the AK7719_DSP should be modprobed before AK4954/AK4951.
++
++config SND_SOC_AK7755
++	tristate "AK7755 for Ambarella Platform"
++	help
++		Support AK7755 for Ambarella Platform.
++
++config SND_SOC_TLV320ADC3xxx
++	tristate "TLV320ADC3xxx for Ambarella Platform"
++	help
++		Support TLV320ADC3xxx for Ambarella Platform.
++
++config SND_SOC_ES8388
++	tristate "ES8388 for Ambarella Platform"
++	help
++		Support ES8388 Audio Codec for Ambarella Platform.
++
++config SND_SOC_ES8374
++	tristate "ES8374 for Ambarella Platform"
++	help
++		ES8374 Audio Codec for Ambarella Platform.
++
++config SND_SOC_WM8974_AMB
++	tristate "WM8974 for Ambarella Platform"
++	help
++		Support WM8974 Audio Codec for Ambarella Platform.
++
++config SND_SOC_WM8940_AMB
++	tristate "WM8940 for Ambarella Platform"
++	help
++		Support WM8940 Audio Codec for Ambarella Platform
++
++config SND_SOC_ZL380TW
++	tristate "ZL380XX for Ambarella Platform"
++	help
++		Support ZL380XX Audio Codec for Ambarella Platform
++
++config SND_SOC_RT5670
++	tristate "RT5670 for Ambarella Platform"
++	help
++		Support RT5670 Audio Codec for Ambarella Platform
++
++config SND_SOC_AMBARELLA_DUMMY
++	tristate "Dummy Codec for Ambarella Platform"
++	help
++		Support Dummy Codec for Ambarella Platform
++
++endif
++
++
+diff --git a/sound/soc/ambarella/Makefile b/sound/soc/ambarella/Makefile
+new file mode 100644
+index 00000000..36528a58
+--- /dev/null
++++ b/sound/soc/ambarella/Makefile
+@@ -0,0 +1,11 @@
++# AMBARELLA Platform Support
++snd-soc-ambarella-objs := ambarella_pcm.o
++snd-soc-ambarella-i2s-objs := ambarella_i2s.o
++
++obj-$(CONFIG_SND_AMBARELLA_SOC)		+= snd-soc-ambarella.o
++obj-$(CONFIG_SND_AMBARELLA_SOC_I2S)	+= snd-soc-ambarella-i2s.o
++
++# AMBARELLA Machine Support
++snd-soc-amba-board-objs := ambarella_board.o
++
++obj-$(CONFIG_AMBA_BOARD)		+= snd-soc-amba-board.o
+diff --git a/sound/soc/ambarella/ambarella_board.c b/sound/soc/ambarella/ambarella_board.c
+new file mode 100644
+index 00000000..e493e8b2
+--- /dev/null
++++ b/sound/soc/ambarella/ambarella_board.c
+@@ -0,0 +1,424 @@
++/*
++ * sound/soc/ambarella_board.c
++ *
++ * Author: XianqingZheng <xqzheng@ambarella.com>
++ *
++ * History:
++ *	2015/04/28 - [XianqingZheng] Created file
++ *
++ * Copyright (C) 2014-2018, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/of.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <plat/audio.h>
++#include <linux/slab.h>
++#include <sound/pcm_params.h>
++
++static int fast_boot = 0;
++module_param(fast_boot, uint, 0664);
++
++static unsigned int dai_fmt;
++module_param(dai_fmt, uint, 0644);
++MODULE_PARM_DESC(dai_fmt, "DAI format.");
++/* clk_fmt :
++* 0 : mclk, bclk provided by cpu
++* 1 : bclk provide by cpu, mclk is not used
++* 2 : mclk provided by cpu, bclk is provided by codec
++* There are four type of connection:
++* clk_fmt=0:
++* cpu :                   codec:
++*     MCLK    ------>  MCKI
++*     BCLK    ------>  BICK
++*     LRCK    ------>  LRCK
++*                   ...
++* clk_fmt=1:
++* cpu :                   codec:
++*     MCLK   is not used
++*     BCLK    ------> BICK
++*     LRCK    ------> LRCK
++*                    ...
++* clk_fmt=2:
++* cpu :                   codec:
++*     MCLK   ------> MCKI
++*     BCLK   <------ BICK
++*     LRCK   <------ LRCK
++* There are one connection we are not used, it is like clk_fmt=0,but power on the codec PLL.
++* It is a waster of power, so we do not use it.
++*/
++static unsigned int dummy_dai_fmt;
++module_param(dummy_dai_fmt, uint, 0644);
++
++static unsigned int clk_fmt;
++module_param(clk_fmt, uint, 0664);
++
++struct amb_clk {
++	int mclk;
++	int i2s_div;
++	int bclk;
++};
++
++static int amba_clk_config(struct snd_pcm_hw_params *params, struct amb_clk *clk)
++{
++	u32 channels, sample_bits, rate;
++
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S24_LE:
++	case SNDRV_PCM_FORMAT_S32_LE:
++		sample_bits = 32;
++		break;
++	case SNDRV_PCM_FORMAT_S16_LE:
++	default:
++		sample_bits = 16;
++		break;
++	}
++
++	channels = params_channels(params);
++	rate = params_rate(params);
++
++	clk->mclk = 12288000;
++	clk->bclk = channels * rate * sample_bits;
++
++	clk->i2s_div = (clk->mclk / ( 2 * clk->bclk)) - 1;
++
++	return 0;
++}
++
++static int amba_general_board_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_dai *codec_dai = rtd->codec_dai;
++	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++	int rval = 0;
++	int i2s_mode;
++	struct amb_clk clk={0};
++
++	rval = amba_clk_config(params, &clk);
++	if (rval < 0) {
++		pr_err("amba can not support the sample rate\n");
++		goto hw_params_exit;
++	}
++
++	if (dai_fmt == 0)
++		i2s_mode = SND_SOC_DAIFMT_I2S;
++	else
++		i2s_mode = SND_SOC_DAIFMT_DSP_A;
++
++	/* set the I2S system data format*/
++	if (clk_fmt == 2) {
++		rval = snd_soc_dai_set_fmt(codec_dai,
++			i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++		if (rval < 0) {
++			pr_err("can't set codec DAI configuration\n");
++			goto hw_params_exit;
++		}
++
++		rval = snd_soc_dai_set_fmt(cpu_dai,
++			i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++		if (rval < 0) {
++			pr_err("can't set cpu DAI configuration\n");
++			goto hw_params_exit;
++		}
++	} else {
++
++		rval = snd_soc_dai_set_fmt(codec_dai,
++			i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
++		if (rval < 0) {
++			pr_err("can't set codec DAI configuration\n");
++			goto hw_params_exit;
++		}
++
++		rval = snd_soc_dai_set_fmt(cpu_dai,
++			i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
++		if (rval < 0) {
++			pr_err("can't set cpu DAI configuration\n");
++			goto hw_params_exit;
++		}
++	}
++
++	/* set the I2S system clock*/
++	switch(clk_fmt) {
++	case 0:
++		rval = snd_soc_dai_set_sysclk(codec_dai, clk_fmt, clk.mclk, 0);
++		break;
++	case 1:
++		rval = snd_soc_dai_set_sysclk(codec_dai, clk_fmt, clk.bclk, 0);
++		break;
++	case 2:
++		rval = snd_soc_dai_set_sysclk(codec_dai, clk_fmt, clk.mclk, 0);
++		break;
++	default:
++		pr_err("clk_fmt is wrong, just 0, 1, 2 is available!\n");
++		goto hw_params_exit;
++	}
++
++	if (rval < 0) {
++		pr_err("can't set codec MCLK configuration\n");
++		goto hw_params_exit;
++	}
++
++
++	rval = snd_soc_dai_set_sysclk(cpu_dai, AMBARELLA_CLKSRC_ONCHIP, clk.mclk, 0);
++	if (rval < 0) {
++		pr_err("can't set cpu MCLK configuration\n");
++		goto hw_params_exit;
++	}
++
++	rval = snd_soc_dai_set_clkdiv(cpu_dai, AMBARELLA_CLKDIV_LRCLK, clk.i2s_div);
++	if (rval < 0) {
++		pr_err("can't set cpu MCLK/SF ratio\n");
++		goto hw_params_exit;
++	}
++
++hw_params_exit:
++	return rval;
++}
++
++static int amba_dummy_board_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++	int i2s_mode, rval = 0;
++	struct amb_clk clk={0};
++
++	if (fast_boot)
++		return 0;
++	rval = amba_clk_config(params, &clk);
++	if (rval < 0) {
++		pr_err("amba can not support the sample rate\n");
++		goto hw_params_exit;
++	}
++
++	if (dummy_dai_fmt == 0)
++		i2s_mode = SND_SOC_DAIFMT_I2S;
++	else
++		i2s_mode = SND_SOC_DAIFMT_DSP_A;
++
++	/* set the I2S system data format*/
++	if(clk_fmt == 2) {
++		rval = snd_soc_dai_set_fmt(cpu_dai,
++			i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++	} else {
++		rval = snd_soc_dai_set_fmt(cpu_dai,
++			i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
++	}
++
++	if (rval < 0) {
++		printk(KERN_ERR "can't set cpu DAI configuration\n");
++		goto hw_params_exit;
++	}
++
++	/* set the I2S system clock*/
++	rval = snd_soc_dai_set_sysclk(cpu_dai, AMBARELLA_CLKSRC_ONCHIP, clk.mclk, 0);
++	if (rval < 0) {
++		printk(KERN_ERR "can't set cpu MCLK configuration\n");
++		goto hw_params_exit;
++	}
++
++	rval = snd_soc_dai_set_clkdiv(cpu_dai, AMBARELLA_CLKDIV_LRCLK, clk.i2s_div);
++	if (rval < 0) {
++		printk(KERN_ERR "can't set cpu MCLK/SF ratio\n");
++		goto hw_params_exit;
++	}
++
++hw_params_exit:
++	return rval;
++}
++
++static struct snd_soc_ops amba_general_board_ops = {
++	.hw_params = amba_general_board_hw_params,
++};
++
++static struct snd_soc_ops amba_dummy_board_ops = {
++	.hw_params = amba_dummy_board_hw_params,
++};
++
++/* ambevk machine dapm widgets */
++static const struct snd_soc_dapm_widget amba_dapm_widgets[] = {
++	SND_SOC_DAPM_MIC("Mic internal", NULL),
++	SND_SOC_DAPM_MIC("Mic external", NULL),
++	SND_SOC_DAPM_LINE("Line In", NULL),
++	SND_SOC_DAPM_LINE("Line Out", NULL),
++	SND_SOC_DAPM_HP("HP Jack", NULL),
++	SND_SOC_DAPM_SPK("Speaker", NULL),
++};
++
++static int amba_codec_init(struct snd_soc_pcm_runtime *rtd)
++{
++	return 0;
++}
++
++/* ambevk audio machine driver */
++static struct snd_soc_card snd_soc_card_amba = {
++	.owner = THIS_MODULE,
++	.dapm_widgets = amba_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(amba_dapm_widgets),
++};
++
++static int amba_soc_snd_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct device_node *cpup_np, *codec_np, *dummy_codec_np;
++	struct snd_soc_dai_link *amba_dai_link;
++	struct snd_soc_card *card = &snd_soc_card_amba;
++	int rval = 0;
++
++	card->dev = &pdev->dev;
++
++	if (snd_soc_of_parse_card_name(card, "amb,model")) {
++		dev_err(&pdev->dev, "Card name is not provided\n");
++		return -ENODEV;
++	}
++
++	cpup_np = of_parse_phandle(np, "amb,i2s-controllers", 0);
++	if (fast_boot)
++		codec_np = NULL;
++	else
++		codec_np = of_parse_phandle(np, "amb,audio-codec", 0);
++	dummy_codec_np = of_parse_phandle(np, "amb,dummy-codec", 0);
++	if (!cpup_np || !dummy_codec_np) {
++		dev_err(&pdev->dev, "phandle missing or invalid\n");
++		return -EINVAL;
++	}
++
++	if(codec_np) {
++		rval = snd_soc_of_parse_audio_routing(card,
++		"amb,audio-routing");
++		if(rval) {
++			dev_err(&pdev->dev, "amb,audio-routing is not specified, please doube check\n");
++		}
++
++		/*alloc two amba_dai_link for audio codec and dummy codec*/
++		amba_dai_link = devm_kzalloc(&pdev->dev, 2 * sizeof(*amba_dai_link), GFP_KERNEL);
++		if (amba_dai_link == NULL) {
++			dev_err(&pdev->dev, "alloc memory for amba_dai_link fail!\n");
++			return -ENOMEM;
++		}
++
++		amba_dai_link[0].codec_of_node = codec_np;
++		amba_dai_link[0].cpu_of_node = cpup_np;
++		amba_dai_link[0].platform_of_node = cpup_np;
++		amba_dai_link[0].init = amba_codec_init;
++		amba_dai_link[0].ops = &amba_general_board_ops;
++
++		amba_dai_link[1].codec_of_node = dummy_codec_np;
++		amba_dai_link[1].cpu_of_node = cpup_np;
++		amba_dai_link[1].platform_of_node = cpup_np;
++		amba_dai_link[1].init = amba_codec_init;
++		amba_dai_link[1].ops = &amba_dummy_board_ops;
++
++		card->dai_link = amba_dai_link;
++		card->num_links = 2;
++
++		/*get parameter from code_np to fill struct snd_soc_dai_link*/
++		rval = of_property_read_string_index(np, "amb,codec-name", 0, &card->dai_link[0].name);
++		if(rval < 0) {
++			dev_err(&pdev->dev, "codec-name got from device tree is invalid\n");
++			return -EINVAL;
++		}
++
++		rval = of_property_read_string_index(np, "amb,stream-name", 0, &card->dai_link[0].stream_name);
++		if(rval < 0) {
++			dev_err(&pdev->dev, "stream-name got from device tree is invalid\n");
++			return -EINVAL;
++		}
++
++		rval = of_property_read_string_index(np, "amb,codec-dai-name", 0, &card->dai_link[0].codec_dai_name);
++		if(rval < 0) {
++			dev_err(&pdev->dev, "codec-dai-name got from device tree is invalid\n");
++			return -EINVAL;
++		}
++
++		card->dai_link[1].name = "AMB-DUMMY";
++		card->dai_link[1].stream_name = "AMB-DUMMY-STREAM";
++		card->dai_link[1].codec_dai_name = "AMBARELLA_DUMMY_CODEC";
++
++	} else {
++		/*alloc only one amba_dai_link for dummy codec*/
++		amba_dai_link = devm_kzalloc(&pdev->dev, sizeof(*amba_dai_link), GFP_KERNEL);
++		if (amba_dai_link == NULL) {
++			dev_err(&pdev->dev, "alloc memory for amba_dai_link fail!\n");
++			return -ENOMEM;
++		}
++
++		amba_dai_link[0].codec_of_node = dummy_codec_np;
++		amba_dai_link[0].cpu_of_node = cpup_np;
++		amba_dai_link[0].platform_of_node = cpup_np;
++		amba_dai_link[0].init = amba_codec_init;
++		amba_dai_link[0].ops = &amba_dummy_board_ops;
++		card->dai_link = amba_dai_link;
++		card->num_links = 1;
++		card->dai_link[0].name = "AMB-DUMMY";
++		card->dai_link[0].stream_name = "AMB-DUMMY-STREAM";
++		card->dai_link[0].codec_dai_name = "AMBARELLA_DUMMY_CODEC";
++	}
++
++	of_node_put(codec_np);
++	of_node_put(cpup_np);
++	of_node_put(dummy_codec_np);
++
++	/*get dai_fmt and clk_fmt from device tree*/
++	of_property_read_u32(np, "amb,dai_fmt", &dai_fmt);
++	of_property_read_u32(np, "amb,dummy_dai_fmt", &dummy_dai_fmt);
++	of_property_read_u32(np, "amb,clk_fmt", &clk_fmt);
++
++	rval = snd_soc_register_card(card);
++	if (rval)
++		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", rval);
++
++	return rval;
++}
++
++static int amba_soc_snd_remove(struct platform_device *pdev)
++{
++	snd_soc_unregister_card(&snd_soc_card_amba);
++	if(snd_soc_card_amba.dapm_routes != NULL)
++		kfree(snd_soc_card_amba.dapm_routes);
++
++	return 0;
++}
++
++static const struct of_device_id amba_dt_ids[] = {
++	{ .compatible = "ambarella,audio-board", },
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, amba_dt_ids);
++
++static struct platform_driver amba_soc_snd_driver = {
++	.driver = {
++		.name = "snd_soc_card_amba",
++		.owner = THIS_MODULE,
++		.pm = &snd_soc_pm_ops,
++		.of_match_table = amba_dt_ids,
++	},
++	.probe = amba_soc_snd_probe,
++	.remove = amba_soc_snd_remove,
++};
++
++module_platform_driver(amba_soc_snd_driver);
++
++MODULE_AUTHOR("XianqingZheng<xqzheng@ambarella.com>");
++MODULE_DESCRIPTION("Amabrella Board for ALSA");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("snd-soc-amba");
++
+diff --git a/sound/soc/ambarella/ambarella_i2s.c b/sound/soc/ambarella/ambarella_i2s.c
+new file mode 100644
+index 00000000..8d28e81f
+--- /dev/null
++++ b/sound/soc/ambarella/ambarella_i2s.c
+@@ -0,0 +1,602 @@
++/*
++ * sound/soc/ambarella_i2s.c
++ *
++ * History:
++ *	2008/03/03 - [Eric Lee] created file
++ *	2008/04/16 - [Eric Lee] Removed the compiling warning
++ *	2009/01/22 - [Anthony Ginger] Port to 2.6.28
++ *	2009/03/05 - [Cao Rongrong] Update from 2.6.22.10
++ *	2009/06/10 - [Cao Rongrong] Port to 2.6.29
++ *	2009/06/29 - [Cao Rongrong] Support more mclk and fs
++ *	2010/10/25 - [Cao Rongrong] Port to 2.6.36+
++ *	2011/03/20 - [Cao Rongrong] Port to 2.6.38
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/clk.h>
++#include <linux/of.h>
++#include <linux/pinctrl/consumer.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/dmaengine_pcm.h>
++#include <plat/dma.h>
++#include <plat/audio.h>
++#include "ambarella_pcm.h"
++#include "ambarella_i2s.h"
++
++static unsigned int capture_enabled = 1;
++module_param(capture_enabled, uint, 0644);
++MODULE_PARM_DESC(capture_enabled, "capture_enabled.");
++
++static unsigned int bclk_reverse = 0;
++module_param(bclk_reverse, uint, 0644);
++MODULE_PARM_DESC(bclk_reverse, "bclk_reverse.");
++
++static DEFINE_MUTEX(clock_reg_mutex);
++
++static inline void dai_tx_enable(void)
++{
++	amba_setbitsl(I2S_INIT_REG, I2S_TX_ENABLE_BIT);
++}
++
++static inline void dai_rx_enable(void)
++{
++	amba_setbitsl(I2S_INIT_REG, I2S_RX_ENABLE_BIT);
++}
++
++static inline void dai_tx_disable(void)
++{
++	amba_clrbitsl(I2S_INIT_REG, I2S_TX_ENABLE_BIT);
++}
++
++static inline void dai_rx_disable(void)
++{
++	if(capture_enabled)
++		amba_clrbitsl(I2S_INIT_REG, I2S_RX_ENABLE_BIT);
++}
++
++static inline void dai_tx_fifo_rst(void)
++{
++	amba_setbitsl(I2S_INIT_REG, I2S_TX_FIFO_RESET_BIT);
++}
++
++static inline void dai_rx_fifo_rst(void)
++{
++	if(capture_enabled)
++		amba_setbitsl(I2S_INIT_REG, I2S_RX_FIFO_RESET_BIT);
++}
++
++static inline void dai_fifo_rst(void)
++{
++	if(capture_enabled)
++		amba_setbitsl(I2S_INIT_REG, I2S_FIFO_RESET_BIT);
++}
++
++static int ambarella_i2s_prepare(struct snd_pcm_substream *substream,
++			struct snd_soc_dai *dai)
++{
++	if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
++		dai_rx_disable();
++		dai_rx_fifo_rst();
++	} else {
++		dai_tx_disable();
++		dai_tx_fifo_rst();
++	}
++	return 0;
++}
++
++static int ambarella_i2s_startup(struct snd_pcm_substream *substream,
++			struct snd_soc_dai *dai)
++{
++	struct snd_pcm_runtime *runtime = substream->runtime;
++	int ret = 0;
++
++	/* Add a rule to enforce the DMA buffer align. */
++	ret = snd_pcm_hw_constraint_step(runtime, 0,
++		SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
++	if (ret)
++		goto ambarella_i2s_startup_exit;
++
++	ret = snd_pcm_hw_constraint_step(runtime, 0,
++		SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
++	if (ret)
++		goto ambarella_i2s_startup_exit;
++
++	ret = snd_pcm_hw_constraint_integer(runtime,
++		SNDRV_PCM_HW_PARAM_PERIODS);
++	if (ret < 0)
++		goto ambarella_i2s_startup_exit;
++
++	return 0;
++ambarella_i2s_startup_exit:
++	return ret;
++}
++
++static int ambarella_i2s_hw_params(struct snd_pcm_substream *substream,
++				struct snd_pcm_hw_params *params,
++				struct snd_soc_dai *cpu_dai)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
++	struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
++	u32 clock_reg;
++
++	if( capture_enabled == 0)
++		return 0;
++
++	/* Disable tx/rx before initializing */
++	dai_tx_disable();
++	dai_rx_disable();
++
++	i2s_intf->sfreq = params_rate(params);
++	i2s_intf->channels = params_channels(params);
++	amba_writel(I2S_REG(I2S_CHANNEL_SELECT_OFFSET), i2s_intf->channels / 2 - 1);
++
++	/* Set format */
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		i2s_intf->multi24 = 0;
++		i2s_intf->tx_ctrl = I2S_TX_UNISON_BIT;
++		i2s_intf->word_len = 15;
++		if (i2s_intf->mode == I2S_DSP_MODE) {
++			i2s_intf->slots = i2s_intf->channels - 1;
++			i2s_intf->word_pos = 15;
++		} else {
++			i2s_intf->slots = 0;
++			i2s_intf->word_pos = 0;
++		}
++		priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
++		break;
++
++	case SNDRV_PCM_FORMAT_S24_LE:		/* 32 bits, valie data in low 3 bytes. */
++		i2s_intf->multi24 = I2S_24BITMUX_MODE_ENABLE;
++		i2s_intf->tx_ctrl = 0;
++		i2s_intf->word_len = 23;
++		if (i2s_intf->mode == I2S_DSP_MODE) {
++			i2s_intf->slots = i2s_intf->channels - 1;
++			i2s_intf->word_pos = 0; /* ignored */
++		} else {
++			i2s_intf->slots = 0;
++			i2s_intf->word_pos = 0; /* ignored */
++		}
++		priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++		break;
++
++	case SNDRV_PCM_FORMAT_S32_LE:
++		i2s_intf->multi24 = I2S_24BITMUX_MODE_ENABLE;
++		i2s_intf->tx_ctrl = 0;
++		i2s_intf->word_len = 31;
++		if (i2s_intf->mode == I2S_DSP_MODE) {
++			i2s_intf->slots = i2s_intf->channels - 1;
++			i2s_intf->word_pos = 0; /* ignored */
++		} else {
++			i2s_intf->slots = 0;
++			i2s_intf->word_pos = 0; /* ignored */
++		}
++		priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++		break;
++
++	default:
++		goto hw_params_exit;
++	}
++
++	if (priv_data->dai_master == true) {
++		i2s_intf->tx_ctrl |= I2S_TX_WS_MST_BIT;
++		i2s_intf->rx_ctrl |= I2S_RX_WS_MST_BIT;
++	} else {
++		i2s_intf->tx_ctrl &= ~I2S_TX_WS_MST_BIT;
++		i2s_intf->rx_ctrl &= ~I2S_RX_WS_MST_BIT;
++	}
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		amba_writel(I2S_TX_CTRL_REG, i2s_intf->tx_ctrl);
++		amba_writel(I2S_TX_FIFO_LTH_REG, 0x10);
++	} else {
++		amba_writel(I2S_RX_CTRL_REG, i2s_intf->rx_ctrl);
++		amba_writel(I2S_RX_FIFO_GTH_REG, 0x20);
++	}
++
++	amba_writel(I2S_MODE_REG, i2s_intf->mode);
++	amba_writel(I2S_WLEN_REG, i2s_intf->word_len);
++	amba_writel(I2S_WPOS_REG, i2s_intf->word_pos);
++	amba_writel(I2S_SLOT_REG, i2s_intf->slots);
++	amba_writel(I2S_24BITMUX_MODE_REG, i2s_intf->multi24);
++
++	/* Set clock */
++	clk_set_rate(priv_data->mclk, i2s_intf->mclk);
++
++	mutex_lock(&clock_reg_mutex);
++
++	clock_reg = amba_readl(I2S_CLOCK_REG);
++	clock_reg &= ~DAI_CLOCK_MASK;
++	clock_reg |= i2s_intf->div;
++
++	if (priv_data->dai_master == true)
++		clock_reg |= I2S_CLK_MASTER_MODE;
++	else
++		clock_reg &= ~I2S_CLK_MASTER_MODE;
++
++	if (bclk_reverse)
++		clock_reg &= ~I2S_CLK_TX_PO_FALL;
++	else
++		clock_reg |= I2S_CLK_TX_PO_FALL;
++
++	amba_writel(I2S_CLOCK_REG, clock_reg);
++
++	mutex_unlock(&clock_reg_mutex);
++
++	dai_rx_enable();
++	dai_tx_enable();
++
++	msleep(1);
++
++	/* Notify HDMI that the audio interface is changed */
++	ambarella_audio_notify_transition(&priv_data->amb_i2s_intf,
++		AUDIO_NOTIFY_SETHWPARAMS);
++	return 0;
++
++hw_params_exit:
++	dai_rx_enable();
++	dai_tx_enable();
++	return -EINVAL;
++}
++
++static int ambarella_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
++		struct snd_soc_dai *cpu_dai)
++{
++	switch (cmd) {
++	case SNDRV_PCM_TRIGGER_START:
++	case SNDRV_PCM_TRIGGER_RESUME:
++	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++			dai_tx_enable();
++		else
++			dai_rx_enable();
++		break;
++	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
++			dai_tx_disable();
++			dai_tx_fifo_rst();
++		}else{
++			dai_rx_disable();
++			dai_rx_fifo_rst();
++		}
++		break;
++	default:
++		break;
++	}
++
++	return 0;
++}
++
++/*
++ * Set Ambarella I2S DAI format
++ */
++static int ambarella_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
++		unsigned int fmt)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
++
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_LEFT_J:
++		priv_data->amb_i2s_intf.mode = I2S_LEFT_JUSTIFIED_MODE;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		priv_data->amb_i2s_intf.mode = I2S_RIGHT_JUSTIFIED_MODE;
++		break;
++	case SND_SOC_DAIFMT_I2S:
++		priv_data->amb_i2s_intf.mode = I2S_I2S_MODE;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		priv_data->amb_i2s_intf.mode = I2S_DSP_MODE;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBS_CFS:
++		priv_data->dai_master = true;
++		break;
++	case SND_SOC_DAIFMT_CBM_CFM:
++		if (priv_data->amb_i2s_intf.mode != I2S_I2S_MODE) {
++			printk("DAI can't work in slave mode without standard I2S format!\n");
++			return -EINVAL;
++		}
++		priv_data->dai_master = false;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int ambarella_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
++
++	switch (clk_id) {
++	case AMBARELLA_CLKSRC_ONCHIP:
++		priv_data->amb_i2s_intf.clksrc = clk_id;
++		priv_data->amb_i2s_intf.mclk = freq;
++		break;
++
++	case AMBARELLA_CLKSRC_EXTERNAL:
++	default:
++		printk("CLK SOURCE (%d) is not supported yet\n", clk_id);
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int ambarella_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
++		int div_id, int div)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
++
++	switch (div_id) {
++	case AMBARELLA_CLKDIV_LRCLK:
++		priv_data->amb_i2s_intf.div = div;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int ambarella_i2s_dai_suspend(struct snd_soc_dai *dai)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
++	struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
++
++	priv_data->clock_reg = amba_readl(I2S_CLOCK_REG);
++	i2s_intf->mode = amba_readl(I2S_MODE_REG);
++	i2s_intf->word_len = amba_readl(I2S_WLEN_REG);
++	i2s_intf->word_pos = amba_readl(I2S_WPOS_REG);
++	i2s_intf->slots = amba_readl(I2S_SLOT_REG);
++	i2s_intf->channels = amba_readl(I2S_REG(I2S_CHANNEL_SELECT_OFFSET));
++	i2s_intf->rx_ctrl = amba_readl(I2S_RX_CTRL_REG);
++	i2s_intf->tx_ctrl = amba_readl(I2S_TX_CTRL_REG);
++	i2s_intf->rx_fifo_len = amba_readl(I2S_RX_FIFO_GTH_REG);
++	i2s_intf->tx_fifo_len = amba_readl(I2S_TX_FIFO_LTH_REG);
++	i2s_intf->multi24 = amba_readl(I2S_24BITMUX_MODE_REG);
++
++	return 0;
++}
++
++static int ambarella_i2s_dai_resume(struct snd_soc_dai *dai)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
++	struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
++
++	amba_writel(I2S_MODE_REG, i2s_intf->mode);
++	amba_writel(I2S_WLEN_REG, i2s_intf->word_len);
++	amba_writel(I2S_WPOS_REG, i2s_intf->word_pos);
++	amba_writel(I2S_SLOT_REG, i2s_intf->slots);
++	amba_writel(I2S_REG(I2S_CHANNEL_SELECT_OFFSET), i2s_intf->channels);
++	amba_writel(I2S_RX_CTRL_REG, i2s_intf->rx_ctrl);
++	amba_writel(I2S_TX_CTRL_REG, i2s_intf->tx_ctrl);
++	amba_writel(I2S_RX_FIFO_GTH_REG, i2s_intf->rx_fifo_len);
++	amba_writel(I2S_TX_FIFO_LTH_REG, i2s_intf->tx_fifo_len);
++	amba_writel(I2S_24BITMUX_MODE_REG,i2s_intf->multi24);
++	amba_writel(I2S_CLOCK_REG, priv_data->clock_reg);
++
++	return 0;
++}
++#else /* CONFIG_PM */
++#define ambarella_i2s_dai_suspend	NULL
++#define ambarella_i2s_dai_resume	NULL
++#endif /* CONFIG_PM */
++
++static int ambarella_i2s_dai_probe(struct snd_soc_dai *dai)
++{
++	u32 sfreq, clk_div = 3;
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
++	struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
++
++	dai->capture_dma_data = &priv_data->capture_dma_data;
++	dai->playback_dma_data = &priv_data->playback_dma_data;
++
++	if (priv_data->default_mclk == 12288000) {
++		sfreq = 48000;
++	} else if (priv_data->default_mclk == 11289600){
++		sfreq = 44100;
++	} else {
++		priv_data->default_mclk = 12288000;
++		sfreq = 48000;
++	}
++
++	clk_set_rate(priv_data->mclk, priv_data->default_mclk);
++
++	/*
++	 * Dai default smapling rate, polarity configuration.
++	 * Note: Just be configured, actually BCLK and LRCLK will not
++	 * output to outside at this time.
++	 */
++	if(capture_enabled)
++		amba_writel(I2S_CLOCK_REG, clk_div | I2S_CLK_TX_PO_FALL);
++
++	priv_data->dai_master = true;
++	i2s_intf->mode = I2S_I2S_MODE;
++	i2s_intf->clksrc = AMBARELLA_CLKSRC_ONCHIP;
++	i2s_intf->mclk = priv_data->default_mclk;
++	i2s_intf->div = clk_div;
++	i2s_intf->sfreq = sfreq;
++	i2s_intf->word_len = 15;
++	i2s_intf->word_pos = 0;
++	i2s_intf->slots = 0;
++	i2s_intf->channels = 2;
++
++	/* reset fifo */
++	dai_tx_enable();
++	dai_rx_enable();
++	dai_fifo_rst();
++
++	/* Notify HDMI that the audio interface is initialized */
++	ambarella_audio_notify_transition(&priv_data->amb_i2s_intf, AUDIO_NOTIFY_INIT);
++
++	return 0;
++}
++
++static int ambarella_i2s_dai_remove(struct snd_soc_dai *dai)
++{
++	struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
++
++	/* Disable I2S clock output */
++	amba_writel(I2S_CLOCK_REG, 0x0);
++
++	/* Notify that the audio interface is removed */
++	ambarella_audio_notify_transition(&priv_data->amb_i2s_intf,
++		AUDIO_NOTIFY_REMOVE);
++
++	return 0;
++}
++
++static const struct snd_soc_dai_ops ambarella_i2s_dai_ops = {
++	.prepare = ambarella_i2s_prepare,
++	.startup = ambarella_i2s_startup,
++	.hw_params = ambarella_i2s_hw_params,
++	.trigger = ambarella_i2s_trigger,
++	.set_fmt = ambarella_i2s_set_fmt,
++	.set_sysclk = ambarella_i2s_set_sysclk,
++	.set_clkdiv = ambarella_i2s_set_clkdiv,
++};
++
++static struct snd_soc_dai_driver ambarella_i2s_dai = {
++	.probe = ambarella_i2s_dai_probe,
++	.remove = ambarella_i2s_dai_remove,
++	.suspend = ambarella_i2s_dai_suspend,
++	.resume = ambarella_i2s_dai_resume,
++	.playback = {
++		.channels_min = 2,
++		.channels_max = 0, // initialized in ambarella_i2s_probe function
++		.rates = SNDRV_PCM_RATE_8000_48000,
++		.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE),
++	},
++	.capture = {
++		.channels_min = 2,
++		.channels_max = 0, // initialized in ambarella_i2s_probe function
++		.rates = SNDRV_PCM_RATE_8000_48000,
++		.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE),
++	},
++	.ops = &ambarella_i2s_dai_ops,
++	.symmetric_rates = 1,
++};
++
++static const struct snd_soc_component_driver ambarella_i2s_component = {
++	.name		= "ambarella-i2s",
++};
++
++static int ambarella_i2s_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct amb_i2s_priv *priv_data;
++	struct pinctrl *pinctrl;
++	int channels, rval;
++
++	priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv_data), GFP_KERNEL);
++	if (priv_data == NULL)
++		return -ENOMEM;
++
++	priv_data->playback_dma_data.addr = I2S_TX_LEFT_DATA_DMA_REG;
++	priv_data->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++	priv_data->playback_dma_data.maxburst = 32;
++
++	priv_data->capture_dma_data.addr = I2S_RX_DATA_DMA_REG;
++	priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
++	priv_data->capture_dma_data.maxburst = 32;
++	priv_data->mclk = clk_get(&pdev->dev, "gclk_audio");
++	if (IS_ERR(priv_data->mclk)) {
++		dev_err(&pdev->dev, "Get audio clk failed!\n");
++		return PTR_ERR(priv_data->mclk);
++	}
++
++	dev_set_drvdata(&pdev->dev, priv_data);
++
++	rval = of_property_read_u32(np, "amb,i2s-channels", &channels);
++	if (rval < 0) {
++		dev_err(&pdev->dev, "Get channels failed! %d\n", rval);
++		return -ENXIO;
++	}
++
++	of_property_read_u32(np, "amb,default-mclk", &priv_data->default_mclk);
++
++	ambarella_i2s_dai.playback.channels_max = channels;
++	ambarella_i2s_dai.capture.channels_max = channels;
++
++	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++	if (IS_ERR(pinctrl))
++		return PTR_ERR(pinctrl);
++
++	rval = snd_soc_register_component(&pdev->dev,
++			&ambarella_i2s_component,  &ambarella_i2s_dai, 1);
++	if (rval < 0){
++		dev_err(&pdev->dev, "register DAI failed\n");
++		return rval;
++	}
++
++	rval = ambarella_pcm_platform_register(&pdev->dev);
++	if (rval) {
++		dev_err(&pdev->dev, "register PCM failed: %d\n", rval);
++		snd_soc_unregister_component(&pdev->dev);
++		return rval;
++	}
++
++	return 0;
++}
++
++static int ambarella_i2s_remove(struct platform_device *pdev)
++{
++	ambarella_pcm_platform_unregister(&pdev->dev);
++	snd_soc_unregister_component(&pdev->dev);
++
++	return 0;
++}
++
++static const struct of_device_id ambarella_i2s_dt_ids[] = {
++	{ .compatible = "ambarella,i2s", },
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ambarella_i2s_dt_ids);
++
++static struct platform_driver ambarella_i2s_driver = {
++	.probe = ambarella_i2s_probe,
++	.remove = ambarella_i2s_remove,
++
++	.driver = {
++		.name = "ambarella-i2s",
++		.owner = THIS_MODULE,
++		.of_match_table = ambarella_i2s_dt_ids,
++	},
++};
++
++module_platform_driver(ambarella_i2s_driver);
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella Soc I2S Interface");
++
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/ambarella/ambarella_i2s.h b/sound/soc/ambarella/ambarella_i2s.h
+new file mode 100644
+index 00000000..9fa8e3b1
+--- /dev/null
++++ b/sound/soc/ambarella/ambarella_i2s.h
+@@ -0,0 +1,45 @@
++/*
++ * sound/soc/ambarella_i2s.h
++ *
++ * History:
++ *	2008/03/03 - [Eric Lee] created file
++ *	2008/04/16 - [Eric Lee] Removed the compiling warning
++ *	2009/01/22 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef AMBARELLA_I2S_H_
++#define AMBARELLA_I2S_H_
++
++struct amb_i2s_priv {
++	struct clk *mclk;
++	bool dai_master;
++	u32 default_mclk;
++	u32 clock_reg;
++	u32 bclk_reverse;
++	struct ambarella_i2s_interface amb_i2s_intf;
++
++	struct snd_dmaengine_dai_dma_data playback_dma_data;
++	struct snd_dmaengine_dai_dma_data capture_dma_data;
++};
++
++int ambarella_i2s_add_controls(struct snd_soc_codec *codec);
++
++#endif /*AMBARELLA_I2S_H_*/
++
+diff --git a/sound/soc/ambarella/ambarella_pcm.c b/sound/soc/ambarella/ambarella_pcm.c
+new file mode 100644
+index 00000000..8ffcd0ab
+--- /dev/null
++++ b/sound/soc/ambarella/ambarella_pcm.c
+@@ -0,0 +1,99 @@
++/*
++ * sound/soc/ambarella_pcm.c
++ *
++ * History:
++ *	2008/03/03 - [Eric Lee] created file
++ *	2008/04/16 - [Eric Lee] Removed the compiling warning
++ *	2008/08/07 - [Cao Rongrong] Fix the buffer bug,eg: size and allocation
++ *	2008/11/14 - [Cao Rongrong] Support pause and resume
++ *	2009/01/22 - [Anthony Ginger] Port to 2.6.28
++ *	2009/03/05 - [Cao Rongrong] Update from 2.6.22.10
++ *	2009/06/10 - [Cao Rongrong] Port to 2.6.29
++ *	2009/06/30 - [Cao Rongrong] Fix last_desc bug
++ *	2010/10/25 - [Cao Rongrong] Port to 2.6.36+
++ *	2011/03/20 - [Cao Rongrong] Port to 2.6.38
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/dmaengine_pcm.h>
++#include <plat/dma.h>
++
++
++#define AMBA_MAX_DESC_NUM		128
++#define AMBA_MIN_DESC_NUM		2
++#define AMBA_PERIOD_BYTES_MAX		(128 * 1024)
++#define AMBA_PERIOD_BYTES_MIN		32
++#define AMBA_BUFFER_BYTES_MAX		(256 * 1024)
++
++/*
++ * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a
++ * limitation in the I2S driver requires the sample rates for playback and
++ * capture to be the same.
++ */
++static const struct snd_pcm_hardware ambarella_pcm_hardware = {
++	.info			= SNDRV_PCM_INFO_INTERLEAVED |
++				  SNDRV_PCM_INFO_BLOCK_TRANSFER |
++				  SNDRV_PCM_INFO_MMAP |
++				  SNDRV_PCM_INFO_MMAP_VALID |
++				  SNDRV_PCM_INFO_PAUSE |
++				  SNDRV_PCM_INFO_RESUME |
++				  SNDRV_PCM_INFO_BATCH |
++				  SNDRV_PCM_INFO_JOINT_DUPLEX,
++	.formats		= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
++	.rates			= SNDRV_PCM_RATE_8000_48000,
++	.rate_min		= 8000,
++	.rate_max		= 48000,
++	.period_bytes_min	= AMBA_PERIOD_BYTES_MIN,
++	.period_bytes_max	= AMBA_PERIOD_BYTES_MAX,
++	.periods_min		= AMBA_MIN_DESC_NUM,
++	.periods_max		= AMBA_MAX_DESC_NUM,
++	.buffer_bytes_max	= AMBA_BUFFER_BYTES_MAX,
++};
++
++
++static const struct snd_dmaengine_pcm_config ambarella_dmaengine_pcm_config = {
++	.pcm_hardware = &ambarella_pcm_hardware,
++	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
++	.prealloc_buffer_size = AMBA_BUFFER_BYTES_MAX,
++};
++
++int ambarella_pcm_platform_register(struct device *dev)
++{
++	return snd_dmaengine_pcm_register(dev, &ambarella_dmaengine_pcm_config,
++			SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
++			SND_DMAENGINE_PCM_FLAG_COMPAT);
++}
++EXPORT_SYMBOL_GPL(ambarella_pcm_platform_register);
++
++void ambarella_pcm_platform_unregister(struct device *dev)
++{
++	snd_dmaengine_pcm_unregister(dev);
++}
++EXPORT_SYMBOL_GPL(ambarella_pcm_platform_unregister);
++
++
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_DESCRIPTION("Ambarella Soc PCM DMA module");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/ambarella/ambarella_pcm.h b/sound/soc/ambarella/ambarella_pcm.h
+new file mode 100644
+index 00000000..1a3d7de0
+--- /dev/null
++++ b/sound/soc/ambarella/ambarella_pcm.h
+@@ -0,0 +1,36 @@
++/*
++ * sound/soc/ambarella_pcm.h
++ *
++ * History:
++ *	2008/03/03 - [Eric Lee] created file
++ *	2008/04/16 - [Eric Lee] Removed the compiling warning
++ *	2008/08/07 - [Cao Rongrong] Fix the buffer bug,eg: size and allocation
++ *	2008/11/14 - [Cao Rongrong] Support pause and resume
++ *	2009/01/22 - [Anthony Ginger] Port to 2.6.28
++ *
++ * Copyright (C) 2004-2009, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef _AMBARELLA_PCM_H
++#define _AMBARELLA_PCM_H
++
++int ambarella_pcm_platform_register(struct device *dev);
++void ambarella_pcm_platform_unregister(struct device *dev);
++
++#endif /* _AMBARELLA_PCM_H */
++
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 2f45f00e..f318c6b0 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -21,12 +21,19 @@ config SND_SOC_ALL_CODECS
+ 	select SND_SOC_ADAU1373 if I2C
+ 	select SND_SOC_ADAV80X
+ 	select SND_SOC_ADS117X
++	select SND_SOC_AMBARELLA_DUMMY
+ 	select SND_SOC_AK4104 if SPI_MASTER
+ 	select SND_SOC_AK4535 if I2C
+ 	select SND_SOC_AK4641 if I2C
+ 	select SND_SOC_AK4642 if I2C
++	select SND_SOC_AK4642_AMB if I2C
+ 	select SND_SOC_AK4671 if I2C
+ 	select SND_SOC_AK5386
++	select SND_SOC_AK4951_AMB if I2C
++	select SND_SOC_AK4954_AMB if I2C
++	select SND_SOC_WM8940_AMB if I2C
++	select SND_SOC_WM8974_AMB if I2C
++	select SND_SOC_AK7755 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_ALC5623 if I2C
+ 	select SND_SOC_ALC5632 if I2C
+ 	select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
+@@ -41,6 +48,9 @@ config SND_SOC_ALL_CODECS
+ 	select SND_SOC_DA732X if I2C
+ 	select SND_SOC_DA9055 if I2C
+ 	select SND_SOC_DFBMCS320
++	select SND_SOC_ES8328 if I2C
++	select SND_SOC_ES8374 if I2C
++	select SND_SOC_ES8388 if I2C
+ 	select SND_SOC_ISABELLE if I2C
+ 	select SND_SOC_JZ4740_CODEC
+ 	select SND_SOC_LM4857 if I2C
+@@ -65,6 +75,7 @@ config SND_SOC_ALL_CODECS
+ 	select SND_SOC_STA529 if I2C
+ 	select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
+ 	select SND_SOC_TAS5086 if I2C
++	select SND_SOC_TLV320ADC3xxx if I2C
+ 	select SND_SOC_TLV320AIC23 if I2C
+ 	select SND_SOC_TLV320AIC26 if SPI_MASTER
+ 	select SND_SOC_TLV320AIC32X4 if I2C
+@@ -125,6 +136,7 @@ config SND_SOC_ALL_CODECS
+ 	select SND_SOC_WM9705 if SND_SOC_AC97_BUS
+ 	select SND_SOC_WM9712 if SND_SOC_AC97_BUS
+ 	select SND_SOC_WM9713 if SND_SOC_AC97_BUS
++	select SND_SOC_ZL380TW if SND_SOC_I2C_AND_SPI
+         help
+           Normally ASoC codec drivers are only built if a machine driver which
+           uses them is also built since they are only usable with a machine
+@@ -190,6 +202,9 @@ config SND_SOC_ADAV80X
+ config SND_SOC_ADS117X
+ 	tristate
+ 
++config SND_SOC_AMBARELLA_DUMMY
++	tristate
++
+ config SND_SOC_AK4104
+ 	tristate
+ 
+@@ -202,12 +217,30 @@ config SND_SOC_AK4641
+ config SND_SOC_AK4642
+ 	tristate
+ 
++config SND_SOC_AK4642_AMB
++	tristate
++
+ config SND_SOC_AK4671
+ 	tristate
+ 
+ config SND_SOC_AK5386
+ 	tristate
+ 
++config SND_SOC_AK4951_AMB
++	tristate
++
++config SND_SOC_AK4954_AMB
++	tristate
++
++config SND_SOC_WM8940_AMB
++	tristate
++
++config SND_SOC_WM8974_AMB
++	tristate
++
++config SND_SOC_AK7755
++	tristate
++
+ config SND_SOC_ALC5623
+        tristate
+ config SND_SOC_ALC5632
+@@ -269,6 +302,15 @@ config SND_SOC_DFBMCS320
+ config SND_SOC_DMIC
+ 	tristate
+ 
++config SND_SOC_ES8328
++	tristate
++
++config SND_SOC_ES8374
++	tristate
++
++config SND_SOC_ES8388
++	tristate
++
+ config SND_SOC_ISABELLE
+         tristate
+ 
+@@ -525,3 +567,12 @@ config SND_SOC_ML26124
+ 
+ config SND_SOC_TPA6130A2
+ 	tristate
++
++config SND_SOC_TLV320ADC3xxx
++	tristate
++
++config SND_SOC_ZL380TW
++	tristate
++
++config SND_SOC_RT5670
++	tristate
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index b9e41c9a..36c172e3 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -13,8 +13,17 @@ snd-soc-ak4104-objs := ak4104.o
+ snd-soc-ak4535-objs := ak4535.o
+ snd-soc-ak4641-objs := ak4641.o
+ snd-soc-ak4642-objs := ak4642.o
++snd-soc-ak4642-amb-objs := ak4642_amb.o
+ snd-soc-ak4671-objs := ak4671.o
+ snd-soc-ak5386-objs := ak5386.o
++snd-soc-ak4951-amb-objs := ak4951_amb.o
++snd-soc-ak4954-amb-objs := ak4954_amb.o
++snd-soc-ak7719-objs := ak7719_amb.o
++snd-soc-ak7755-objs := ak7755.o
++snd-soc-wm8940-amb-objs := wm8940_amb.o
++snd-soc-wm8974-amb-objs := wm8974_amb.o
++snd-soc-rt5670-objs := rt5670.o rt5670-dsp.o
++snd-soc-ambdummy-objs := ambarella_dummy.o
+ snd-soc-arizona-objs := arizona.o
+ snd-soc-cq93vc-objs := cq93vc.o
+ snd-soc-cs42l51-objs := cs42l51.o
+@@ -29,6 +38,9 @@ snd-soc-da732x-objs := da732x.o
+ snd-soc-da9055-objs := da9055.o
+ snd-soc-dfbmcs320-objs := dfbmcs320.o
+ snd-soc-dmic-objs := dmic.o
++snd-soc-es8328-objs := es8328.o
++snd-soc-es8374-objs := es8374.o
++snd-soc-es8388-objs := es8388.o
+ snd-soc-isabelle-objs := isabelle.o
+ snd-soc-jz4740-codec-objs := jz4740.o
+ snd-soc-l3-objs := l3.o
+@@ -57,6 +69,7 @@ snd-soc-sta32x-objs := sta32x.o
+ snd-soc-sta529-objs := sta529.o
+ snd-soc-stac9766-objs := stac9766.o
+ snd-soc-tas5086-objs := tas5086.o
++snd-soc-tlv320adc3xxx-amb-objs := tlv320adc3xxx_amb.o
+ snd-soc-tlv320aic23-objs := tlv320aic23.o
+ snd-soc-tlv320aic26-objs := tlv320aic26.o
+ snd-soc-tlv320aic3x-objs := tlv320aic3x.o
+@@ -122,6 +135,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
+ # Amp
+ snd-soc-max9877-objs := max9877.o
+ snd-soc-tpa6130a2-objs := tpa6130a2.o
++snd-soc-zl380tw-objs := zl380tw.o
+ 
+ obj-$(CONFIG_SND_SOC_88PM860X)	+= snd-soc-88pm860x.o
+ obj-$(CONFIG_SND_SOC_AB8500_CODEC)	+= snd-soc-ab8500-codec.o
+@@ -138,10 +152,19 @@ obj-$(CONFIG_SND_SOC_AK4104)	+= snd-soc-ak4104.o
+ obj-$(CONFIG_SND_SOC_AK4535)	+= snd-soc-ak4535.o
+ obj-$(CONFIG_SND_SOC_AK4641)	+= snd-soc-ak4641.o
+ obj-$(CONFIG_SND_SOC_AK4642)	+= snd-soc-ak4642.o
++obj-$(CONFIG_SND_SOC_AK4642_AMB)	+= snd-soc-ak4642-amb.o
+ obj-$(CONFIG_SND_SOC_AK4671)	+= snd-soc-ak4671.o
+ obj-$(CONFIG_SND_SOC_AK5386)	+= snd-soc-ak5386.o
++obj-$(CONFIG_SND_SOC_AK4951_AMB)    += snd-soc-ak4951-amb.o
++obj-$(CONFIG_SND_SOC_AK4954_AMB)    += snd-soc-ak4954-amb.o
++obj-$(CONFIG_SND_SOC_AK7719_DSP)    += snd-soc-ak7719.o
++obj-$(CONFIG_SND_SOC_AK7755)    += snd-soc-ak7755.o
++obj-$(CONFIG_SND_SOC_WM8940_AMB)    += snd-soc-wm8940-amb.o
++obj-$(CONFIG_SND_SOC_WM8974_AMB)    += snd-soc-wm8974-amb.o
++obj-$(CONFIG_SND_SOC_RT5670)    += snd-soc-rt5670.o
+ obj-$(CONFIG_SND_SOC_ALC5623)    += snd-soc-alc5623.o
+ obj-$(CONFIG_SND_SOC_ALC5632)	+= snd-soc-alc5632.o
++obj-$(CONFIG_SND_SOC_AMBARELLA_DUMMY)	+= snd-soc-ambdummy.o
+ obj-$(CONFIG_SND_SOC_ARIZONA)	+= snd-soc-arizona.o
+ obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
+ obj-$(CONFIG_SND_SOC_CS42L51)	+= snd-soc-cs42l51.o
+@@ -156,6 +179,9 @@ obj-$(CONFIG_SND_SOC_DA732X)	+= snd-soc-da732x.o
+ obj-$(CONFIG_SND_SOC_DA9055)	+= snd-soc-da9055.o
+ obj-$(CONFIG_SND_SOC_DFBMCS320)	+= snd-soc-dfbmcs320.o
+ obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o
++obj-$(CONFIG_SND_SOC_ES8328)	+= snd-soc-es8328.o
++obj-$(CONFIG_SND_SOC_ES8374)	+= snd-soc-es8374.o
++obj-$(CONFIG_SND_SOC_ES8388)	+= snd-soc-es8388.o
+ obj-$(CONFIG_SND_SOC_ISABELLE)	+= snd-soc-isabelle.o
+ obj-$(CONFIG_SND_SOC_JZ4740_CODEC)	+= snd-soc-jz4740-codec.o
+ obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o
+@@ -186,6 +212,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC26)	+= snd-soc-tlv320aic26.o
+ obj-$(CONFIG_SND_SOC_TLV320AIC3X)	+= snd-soc-tlv320aic3x.o
+ obj-$(CONFIG_SND_SOC_TLV320AIC32X4)     += snd-soc-tlv320aic32x4.o
+ obj-$(CONFIG_SND_SOC_TLV320DAC33)	+= snd-soc-tlv320dac33.o
++obj-$(CONFIG_SND_SOC_TLV320ADC3xxx)	+= snd-soc-tlv320adc3xxx-amb.o
+ obj-$(CONFIG_SND_SOC_TWL4030)	+= snd-soc-twl4030.o
+ obj-$(CONFIG_SND_SOC_TWL6040)	+= snd-soc-twl6040.o
+ obj-$(CONFIG_SND_SOC_UDA134X)	+= snd-soc-uda134x.o
+@@ -246,3 +273,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS)	+= snd-soc-wm-hubs.o
+ # Amp
+ obj-$(CONFIG_SND_SOC_MAX9877)	+= snd-soc-max9877.o
+ obj-$(CONFIG_SND_SOC_TPA6130A2)	+= snd-soc-tpa6130a2.o
++obj-$(CONFIG_SND_SOC_ZL380TW)	+= snd-soc-zl380tw.o
+diff --git a/sound/soc/codecs/ak4642_amb.c b/sound/soc/codecs/ak4642_amb.c
+new file mode 100644
+index 00000000..6df1c709
+--- /dev/null
++++ b/sound/soc/codecs/ak4642_amb.c
+@@ -0,0 +1,841 @@
++/*
++ * ak4642.c  --  AK4642 ALSA Soc Audio driver
++ *
++ * Copyright 2009 Ambarella Ltd.
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Based on ak4535.c by Richard Purdie
++ *
++ * History:
++ *	2009/05/29 - [Cao Rongrong] Created file
++ *	2010/10/25 - [Cao Rongrong] Port to 2.6.36+
++ *	2011/03/20 - [Cao Rongrong] Port to 2.6.38
++ *	2013/01/14 - [Ken He] Port to 3.8
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/of_gpio.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/initval.h>
++
++#include "ak4642_amb.h"
++
++#define AK4642_VERSION "0.3"
++
++
++/* codec private data */
++struct ak4642_priv {
++	unsigned int rst_pin;
++	unsigned int rst_active;
++	unsigned int sysclk;
++	unsigned int clk_id;
++};
++
++/*
++ * ak4642 register cache
++ */
++static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
++	0x00, 0x00, 0x01, 0x00,
++	0x02, 0x00, 0x00, 0x00,
++	0xe1, 0xe1, 0x18, 0x00,
++	0xe1, 0x18, 0x11, 0x08,
++	0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00,
++};
++
++/****************   ALSA Controls and widgets   **************/
++
++static int ak4642_get_mic_gain(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned short val, val1, val2;
++
++	val1 = snd_soc_read(codec, AK4642_SIG1);
++	val2 = snd_soc_read(codec, AK4642_SIG2);
++	val = (val2 & 0x20) >> 4 | (val1 & 0x01);
++
++	ucontrol->value.integer.value[0] = val;
++	return 0;
++}
++
++static int ak4642_set_mic_gain(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned short val, val1, val2;
++
++	val1 = snd_soc_read(codec, AK4642_SIG1);
++	val2 = snd_soc_read(codec, AK4642_SIG2);
++	val = (val2 & 0x20) >> 4 | (val1 & 0x01);
++
++	if (val == ucontrol->value.integer.value[0])
++		return 0;
++
++	val = ucontrol->value.integer.value[0];
++	val1 &= 0xfe;
++	val1 |= (val & 0x01);
++	snd_soc_write(codec, AK4642_SIG1, val1);
++	val2 &= 0xdf;
++	val2 |= ((val & 0x02) << 4);
++	snd_soc_write(codec, AK4642_SIG2, val2);
++
++	return 1;
++}
++
++static int ak4642_get_alc_gain(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned short val, val1, val2;
++
++	val1 = snd_soc_read(codec, AK4642_ALC1);
++	val2 = snd_soc_read(codec, AK4642_ALC3);
++	val = (val2 & 0x80) >> 6 | (val1 & 0x02) >> 1;
++
++	ucontrol->value.integer.value[0] = val;
++	return 0;
++}
++
++static int ak4642_set_alc_gain(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned short val, val1, val2;
++
++	val1 = snd_soc_read(codec, AK4642_ALC1);
++	val2 = snd_soc_read(codec, AK4642_ALC3);
++	val = (val2 & 0x80) >> 6 | (val1 & 0x02) >> 1;
++
++	if (val == ucontrol->value.integer.value[0])
++		return 0;
++
++	val = ucontrol->value.integer.value[0];
++	val1 &= 0xfd;
++	val1 |= ((val & 0x01) << 1);
++	snd_soc_write(codec, AK4642_ALC1, val1);
++	val2 &= 0x7f;
++	val2 |= ((val & 0x02) << 6);
++	snd_soc_write(codec, AK4642_ALC3, val2);
++
++	return 1;
++}
++
++static int ak4642_get_input_mux(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned short val, val1, val2;
++
++	val1 = snd_soc_read(codec, AK4642_PM3);
++	val2 = snd_soc_read(codec, AK4642_SIG1);
++
++	if(((val1 & 0x1e) == 0x06) && ((val2 & 0x04) == 0x00))
++		val = AK4642_LINE_IN_ON;
++	else if(((val1 & 0x18) == 0x18) && ((val2 & 0x04) == 0x04))
++		val = AK4642_BOTH_MIC_ON;
++	else
++		val = AK4642_INPUT_UNKNOWN;
++
++	ucontrol->value.integer.value[0] = val;
++	return 0;
++}
++
++static int ak4642_set_input_mux(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned short val, val1, val2;
++
++	val1 = snd_soc_read(codec, AK4642_PM3);
++	val2 = snd_soc_read(codec, AK4642_SIG1);
++
++	if(((val1 & 0x1e) == 0x06) && ((val2 & 0x04) == 0x00))
++		val = AK4642_LINE_IN_ON;
++	else if(((val1 & 0x18) == 0x18) && ((val2 & 0x04) == 0x04))
++		val = AK4642_BOTH_MIC_ON;
++	else
++		val = AK4642_INPUT_UNKNOWN;
++
++	if (val == ucontrol->value.integer.value[0])
++		return 0;
++
++	val = ucontrol->value.integer.value[0];
++
++	switch(val){
++	case AK4642_LINE_IN_ON:
++		snd_soc_update_bits(codec, AK4642_PM3, 0x18, 0x06);
++		snd_soc_update_bits(codec, AK4642_SIG1, 0x05, 0);
++		snd_soc_update_bits(codec, AK4642_SIG2, 0x20, 0);
++		break;
++	case AK4642_BOTH_MIC_ON:
++		snd_soc_update_bits(codec, AK4642_PM3, 0x18, 0x18);
++		snd_soc_update_bits(codec, AK4642_SIG1, 0x05, 0x05);
++		snd_soc_update_bits(codec, AK4642_SIG2, 0x20, 0x20);
++		break;
++	case AK4642_INPUT_UNKNOWN:
++		return 0;
++	}
++
++	return 1;
++}
++
++
++static const char *ak4642_lo_gain[] = {"+0db", "+2db"};
++static const char *ak4642_hp_gain[] = {"+0db", "+3.6db"};
++static const char *ak4642_sp_gain[] = {"+4.43db", "+6.43db", "+10.65db", "+12.65db"};
++static const char *ak4642_vol_ctrl[] = {"Independent", "Dependent"};
++static const char *ak4642_deemp[] = {"44.1kHz", "Off", "48kHz", "32kHz"};
++static const char *ak4642_hp_out[] = {"Stereo", "Mono"};
++static const char *ak4642_lsrc[] = {"LIN1", "LIN2"};
++static const char *ak4642_rsrc[] = {"RIN1", "RIN2"};
++static const char *ak4642_eq_gain[] = {"+0db", "+12db", "+24db"};
++static const char *ak4642_fil_sel[] = {"HPF", "LPF"};
++static const char *ak4642_mic_gain[] = {"0db", "+20db", "+26db", "+32db"};
++static const char *ak4642_alc_gain[] = {"0.375db", "0.750db", "1.125db", "1.500db"};
++static const char *ak4642_input_mux[] = {"Line-in", "Both Mic", "Unknown"};
++
++static const struct soc_enum ak4642_enum[] = {
++	SOC_ENUM_SINGLE(AK4642_SIG2, 7, 2, ak4642_lo_gain),
++	SOC_ENUM_SINGLE(AK4642_SIG2, 3, 4, ak4642_sp_gain),
++	SOC_ENUM_SINGLE(AK4642_MODE3, 4, 2, ak4642_vol_ctrl),
++	SOC_ENUM_SINGLE(AK4642_MODE3, 0, 4, ak4642_deemp),
++	SOC_ENUM_SINGLE(AK4642_MODE4, 3, 2, ak4642_vol_ctrl),
++	SOC_ENUM_SINGLE(AK4642_MODE4, 2, 2, ak4642_hp_out),
++	SOC_ENUM_SINGLE(AK4642_PM3, 5, 2, ak4642_hp_gain),
++	SOC_ENUM_SINGLE(AK4642_PM3, 1, 2, ak4642_lsrc),
++	SOC_ENUM_SINGLE(AK4642_PM3, 2, 2, ak4642_rsrc),
++	SOC_ENUM_SINGLE(AK4642_FSEL, 6, 3, ak4642_eq_gain),
++	SOC_ENUM_SINGLE(AK4642_F3EF1, 7, 2, ak4642_fil_sel),
++	SOC_ENUM_SINGLE(AK4642_E1EF1, 7, 2, ak4642_fil_sel),
++	SOC_ENUM_SINGLE_EXT(4, ak4642_mic_gain),
++	SOC_ENUM_SINGLE_EXT(4, ak4642_alc_gain),
++	SOC_ENUM_SINGLE_EXT(3, ak4642_input_mux),
++};
++
++static const struct snd_kcontrol_new ak4642_snd_controls[] = {
++	SOC_SINGLE("HP Mute Switch", AK4642_PM2, 6, 1, 0),
++	SOC_ENUM("Line Out Gain", ak4642_enum[0]),
++	SOC_ENUM("Speaker Gain", ak4642_enum[1]),
++	SOC_ENUM("Headphone Output Mode", ak4642_enum[5]),
++	SOC_ENUM("Headphone Gain", ak4642_enum[6]),
++	SOC_SINGLE("Mic Mute Switch", AK4642_SIG1, 2, 1, 1),
++
++	SOC_SINGLE("ALC Switch", AK4642_ALC1, 5, 1, 0),
++	SOC_SINGLE("ALC ZC Time", AK4642_TIMER, 4, 3, 0),
++	SOC_SINGLE("ALC Recovery Time", AK4642_TIMER, 2, 3, 0),
++	SOC_SINGLE("ALC ZC Detection Switch", AK4642_ALC1, 4, 1, 1),
++	SOC_SINGLE("ALC ATT Step", AK4642_TIMER, 2, 3, 0),
++	SOC_SINGLE("ALC Volume", AK4642_ALC2, 0, 255, 0),
++
++	SOC_SINGLE("Left Capture Volume", AK4642_LIVOL, 0, 255, 0),
++	SOC_SINGLE("Right Capture Volume", AK4642_RIVOL, 0, 255, 0),
++	SOC_SINGLE("Left Playback Volume", AK4642_LDVOL, 0, 255, 1),
++	SOC_SINGLE("Right Playback Volume", AK4642_RDVOL, 0, 255, 1),
++	SOC_ENUM("Playback Volume Control Mode", ak4642_enum[2]),
++	SOC_ENUM("Capture Volume Control Mode", ak4642_enum[4]),
++	SOC_SINGLE("Bass Boost Volume", AK4642_MODE3, 2, 3, 0),
++	SOC_ENUM("Playback Deemphasis", ak4642_enum[3]),
++
++	SOC_SINGLE("Left Differential Swtich", AK4642_PM3, 3, 1, 0),
++	SOC_SINGLE("Right Differential Swtich", AK4642_PM3, 4, 1, 0),
++	/* ADC Source Selector is only available when differential switch is off */
++	SOC_ENUM("Left ADC Source", ak4642_enum[7]),
++	SOC_ENUM("Right ADC Source", ak4642_enum[8]),
++	SOC_ENUM_EXT("Input Mux", ak4642_enum[14],
++		ak4642_get_input_mux, ak4642_set_input_mux),
++
++	SOC_ENUM("EQ Gain Select", ak4642_enum[9]),
++	SOC_SINGLE("Emphasis Filter Switch", AK4642_FSEL, 2, 1, 0),
++	SOC_ENUM("Emphasis Filter Select", ak4642_enum[10]),
++	SOC_SINGLE("Gain Compensation Filter Switch", AK4642_FSEL, 3, 1, 0),
++	SOC_SINGLE("Wind-noise Filter Switch", AK4642_FSEL, 4, 1, 0),
++	SOC_ENUM("Wind-noise Filter Select", ak4642_enum[11]),
++	SOC_SINGLE("Emphasis Filter 1 low Coeff", AK4642_F3EF0, 0, 255, 0),
++	SOC_SINGLE("Emphasis Filter 1 high Coeff", AK4642_F3EF1, 0, 63, 0),
++	SOC_SINGLE("Emphasis Filter 2 low Coeff", AK4642_F3EF2, 0, 255, 0),
++	SOC_SINGLE("Emphasis Filter 2 high Coeff", AK4642_F3EF3, 0, 63, 0),
++	SOC_SINGLE("Gain Compensation Filter 1 low Coeff", AK4642_EQEF0, 0, 255, 0),
++	SOC_SINGLE("Gain Compensation Filter 1 high Coeff", AK4642_EQEF1, 0, 255, 0),
++	SOC_SINGLE("Gain Compensation Filter 2 low Coeff", AK4642_EQEF2, 0, 255, 0),
++	SOC_SINGLE("Gain Compensation Filter 2 high Coeff", AK4642_EQEF3, 0, 63, 0),
++	SOC_SINGLE("Gain Compensation Filter 3 low Coeff", AK4642_EQEF4, 0, 255, 0),
++	SOC_SINGLE("Gain Compensation Filter 3 high Coeff", AK4642_EQEF5, 0, 255, 0),
++	SOC_SINGLE("Wind-noise Filter 1 low Coeff", AK4642_F3EF0, 0, 255, 0),
++	SOC_SINGLE("Wind-noise Filter 1 high Coeff", AK4642_F3EF1, 0, 63, 0),
++	SOC_SINGLE("Wind-noise Filter 2 low Coeff", AK4642_F3EF2, 0, 255, 0),
++	SOC_SINGLE("Wind-noise Filter 2 high Coeff", AK4642_F3EF3, 0, 63, 0),
++	SOC_ENUM_EXT("Mic Gain", ak4642_enum[12],
++		ak4642_get_mic_gain, ak4642_set_mic_gain),
++	SOC_ENUM_EXT("ALC Recovery Gain", ak4642_enum[13],
++		ak4642_get_alc_gain, ak4642_set_alc_gain),
++};
++
++/* Mono 1 Mixer */
++static const struct snd_kcontrol_new ak4642_hp_mixer_controls[] = {
++	SOC_DAPM_SINGLE("HP Playback Switch", AK4642_MODE4, 0, 1, 0),
++	SOC_DAPM_SINGLE("MIN HP Switch", AK4642_MODE4, 1, 1, 0),
++};
++
++/* Stereo Line Out Mixer */
++static const struct snd_kcontrol_new ak4642_lo_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Line Playback Switch", AK4642_SIG1, 4, 1, 0),
++	SOC_DAPM_SINGLE("MIN LO Switch", AK4642_SIG2, 2, 1, 0),
++};
++
++/* Input Mixer */
++static const struct snd_kcontrol_new ak4642_sp_mixer_controls[] = {
++	SOC_DAPM_SINGLE("SP Playback Switch", AK4642_SIG1, 5, 1, 0),
++	SOC_DAPM_SINGLE("MIN SP Switch", AK4642_SIG1, 6, 1, 0),
++};
++
++/* line out switch */
++static const struct snd_kcontrol_new ak4642_lo_control =
++	SOC_DAPM_SINGLE("Switch", AK4642_PM1, 3, 1, 0);
++/* speaker switch */
++static const struct snd_kcontrol_new ak4642_sp_control =
++	SOC_DAPM_SINGLE("Switch", AK4642_SIG1, 7, 1, 0);
++
++/* ak4642 dapm widgets */
++static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
++	/* OUTPUT */
++	SND_SOC_DAPM_MIXER("Line Out Mixer", SND_SOC_NOPM, 0, 0,
++			&ak4642_lo_mixer_controls[0],
++			ARRAY_SIZE(ak4642_lo_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Headphone Mixer", SND_SOC_NOPM, 0, 0,
++			&ak4642_hp_mixer_controls[0],
++			ARRAY_SIZE(ak4642_hp_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Speaker Mixer", SND_SOC_NOPM, 0, 0,
++			&ak4642_sp_mixer_controls[0],
++			ARRAY_SIZE(ak4642_sp_mixer_controls)),
++
++	SND_SOC_DAPM_DAC("DAC", "Playback", AK4642_PM1, 2, 0),
++	SND_SOC_DAPM_PGA("Spk Amp", AK4642_PM1, 4, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HP L Amp", AK4642_PM2, 5, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HP R Amp", AK4642_PM2, 4, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Line Out Pga", AK4642_SIG2, 6, 1, NULL, 0),
++	SND_SOC_DAPM_SWITCH("Speaker Enable", SND_SOC_NOPM, 0, 0,
++			&ak4642_sp_control),
++	SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
++			&ak4642_lo_control),
++	SND_SOC_DAPM_OUTPUT("LOUT"),
++	SND_SOC_DAPM_OUTPUT("ROUT"),
++	SND_SOC_DAPM_OUTPUT("HPL"),
++	SND_SOC_DAPM_OUTPUT("HPR"),
++	SND_SOC_DAPM_OUTPUT("SPP"),
++	SND_SOC_DAPM_OUTPUT("SPN"),
++
++	/* INPUT */
++	SND_SOC_DAPM_ADC("Left ADC", "Capture", AK4642_PM1, 0, 0),
++	SND_SOC_DAPM_ADC("Right ADC", "Capture", AK4642_PM3, 0, 0),
++	SND_SOC_DAPM_PGA("MIN Input", AK4642_PM1, 5, 0, NULL, 0),
++	SND_SOC_DAPM_MICBIAS("Mic Bias", AK4642_SIG1, 2, 0),
++
++	SND_SOC_DAPM_INPUT("LIN1"),
++	SND_SOC_DAPM_INPUT("RIN1"),
++	SND_SOC_DAPM_INPUT("LIN2"),
++	SND_SOC_DAPM_INPUT("RIN2"),
++	SND_SOC_DAPM_INPUT("MIN"),
++};
++
++static const struct snd_soc_dapm_route ak4642_dapm_routes[] = {
++	/*line out mixer */
++	{"Line Out Mixer", "Line Playback Switch", "DAC"},
++	{"Line Out Mixer", "MIN LO Switch", "MIN Input"},
++
++	/* headphone mixer */
++	{"Headphone Mixer", "HP Playback Switch", "DAC"},
++	{"Headphone Mixer", "MIN HP Switch", "MIN Input"},
++
++	/*speaker mixer */
++	{"Speaker Mixer", "SP Playback Switch", "DAC"},
++	{"Speaker Mixer", "MIN SP Switch", "MIN Input"},
++
++	/* line out */
++	{"Line Out Pga", NULL, "Line Out Mixer"},
++	{"Line Out Enable", "Switch", "Line Out Pga"},
++	{"LOUT", NULL, "Line Out Enable"},
++	{"ROUT", NULL, "Line Out Enable"},
++
++	/* left headphone */
++	{"HP L Amp", NULL, "Headphone Mixer"},
++	{"HPL", NULL, "HP L Amp"},
++
++	/* right headphone */
++	{"HP R Amp", NULL, "Headphone Mixer"},
++	{"HPR", NULL, "HP R Amp"},
++
++	/* speaker */
++	{"Spk Amp", NULL, "Speaker Mixer"},
++	{"Speaker Enable", "Switch", "Spk Amp"},
++	{"SPP", NULL, "Speaker Enable"},
++	{"SPN", NULL, "Speaker Enable"},
++
++	/* INPUT */
++	{"MIN Input", NULL, "MIN"},
++	{"Left ADC", NULL, "LIN1"},
++	{"Left ADC", NULL, "LIN2"},
++	{"Right ADC", NULL, "RIN1"},
++	{"Right ADC", NULL, "RIN2"},
++};
++
++static int ak4642_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++	int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
++
++	ak4642->sysclk = freq;
++	ak4642->clk_id = clk_id;
++	return 0;
++}
++
++static int ak4642_hw_params(struct snd_pcm_substream *substream,
++			    struct snd_pcm_hw_params *params,
++			    struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++	struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
++	int rate = params_rate(params);
++	u8 mode0, mode1;
++
++	mode0 = snd_soc_read(codec, AK4642_MODE1) & 0x0F;
++	mode1 = snd_soc_read(codec, AK4642_MODE2) & 0xD8;
++
++	if(ak4642->clk_id == AK4642_MCLK_IN) {
++		switch(ak4642->sysclk) {
++		case 11289600:
++			mode0 |= (4 << 4);
++			break;
++		case 12288000:
++			mode0 |= (5 << 4);
++			break;
++		case 12000000:
++			mode0 |= (6 << 4);
++			break;
++		case 24000000:
++			mode0 |= (7 << 4);
++			break;
++		case 13500000:
++			mode0 |= (0xC << 4);
++			break;
++		case 27000000:
++			mode0 |= (0xD << 4);
++			break;
++		default:
++			mode0 |= (5 << 4);
++			break;
++		}
++
++		snd_soc_write(codec, AK4642_MODE1, mode0);
++		snd_soc_update_bits(codec,AK4642_PM2,0x09,0x01);
++	} else if(ak4642->clk_id == AK4642_BCLK_IN) {
++		u32 oversampe = ak4642->sysclk / rate;
++
++		switch(oversampe) {
++		case 32:
++			mode0 |= (2 << 4);
++			break;
++		case 64:
++			mode0 |= (3 << 4);
++			break;
++		default:
++			mode0 |= (2 << 4);
++			break;
++		}
++
++		snd_soc_write(codec, AK4642_MODE1, mode0);
++		snd_soc_update_bits(codec,AK4642_PM2,0x09,0x01);
++
++	} else if(ak4642->clk_id == AK4642_MCLK_IN_BCLK_OUT) {
++		switch(ak4642->sysclk) {
++		case 11289600:
++			mode0 |= (4 << 4);
++			break;
++		case 12288000:
++			mode0 |= (5 << 4);
++			break;
++		case 12000000:
++			mode0 |= (6 << 4);
++			break;
++		case 24000000:
++			mode0 |= (7 << 4);
++			break;
++		case 13500000:
++			mode0 |= (0xC << 4);
++			break;
++		case 27000000:
++			mode0 |= (0xD << 4);
++			break;
++		default:
++			mode0 |= (5 << 4);
++			break;
++		}
++
++		snd_soc_write(codec, AK4642_MODE1, mode0);
++		snd_soc_update_bits(codec,AK4642_PM2,0x09,0x09);
++	}
++
++	if(ak4642->clk_id == AK4642_BCLK_IN) {
++		if(rate >= 7350 && rate <= 8000)
++			mode1 |= 0;
++		else if(rate > 8000 && rate <= 12000)
++			mode1 |= 1;
++		else if(rate > 12000 && rate <= 16000)
++			mode1 |= 2;
++		else if(rate > 16000 && rate <= 24000)
++			mode1 |= 3;
++		else if(rate > 24000 && rate <= 32000)
++			mode1 |= 0x22;
++		else if(rate > 32 && rate <= 48000)
++			mode1 |= 0x23;
++
++		snd_soc_write(codec, AK4642_MODE2, mode1);
++	} else {
++		switch(rate) {
++		case 7350:
++			mode1 |= 4;
++			break;
++		case 8000:
++			mode1 |= 0;
++			break;
++		case 11025:
++			mode1 |= 5;
++			break;
++		case 12000:
++			mode1 |= 1;
++			break;
++		case 14700:
++			mode1 |= 6;
++			break;
++		case 16000:
++			mode1 |= 2;
++			break;
++		case 22050:
++			mode1 |= 7;
++			break;
++		case 24000:
++			mode1 |= 3;
++			break;
++		case 29400:
++			mode1 |= 0x26;
++			break;
++		case 32000:
++			mode1 |= 0x22;
++			break;
++		case 44100:
++			mode1 |= 0x27;
++			break;
++		case 48000:
++			mode1 |= 0x23;
++			break;
++		default:
++			mode1 |= 0x23;
++			break;
++		}
++
++		snd_soc_write(codec, AK4642_MODE2, mode1);
++	}
++
++	return 0;
++}
++
++static int ak4642_set_dai_fmt(struct snd_soc_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 mode1 = 0, mode2 = 0;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBS_CFS:
++		snd_soc_update_bits(codec, AK4642_PM2, 0x08, 0);
++		break;
++	case SND_SOC_DAIFMT_CBM_CFM:
++		snd_soc_update_bits(codec, AK4642_PM2, 0x08, 0x08);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	mode1 = snd_soc_read(codec, AK4642_MODE1);
++	mode2 = snd_soc_read(codec, AK4642_MODE2);
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		mode1 |= 0x3;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		mode1 &= ~0x3;
++		mode2 &= ~0x18;
++		mode2 |= 0x10;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		mode1 &= ~0x3;
++		mode2 &= ~0x18;
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++	case SND_SOC_DAIFMT_RIGHT_J:
++		pr_info("We don't implement this format (%d) yet.\n", fmt);
++	default:
++		return -EINVAL;
++	}
++
++	snd_soc_write(codec, AK4642_MODE1, mode1);
++	snd_soc_write(codec, AK4642_MODE2, mode2);
++	return 0;
++}
++
++static int ak4642_mute(struct snd_soc_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++
++	if (mute){
++		snd_soc_update_bits(codec, AK4642_MODE3, 0x20, 0x20);
++		snd_soc_update_bits(codec, AK4642_PM2, 0x40, 0);
++	}
++	else{
++		snd_soc_update_bits(codec, AK4642_MODE3, 0x20, 0);
++		snd_soc_update_bits(codec, AK4642_PM2, 0x40, 0x40);
++	}
++
++	return 0;
++}
++
++static int ak4642_set_bias_level(struct snd_soc_codec *codec,
++	enum snd_soc_bias_level level)
++{
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++		/* Everything is ON */
++		break;
++	case SND_SOC_BIAS_PREPARE:
++		break;
++	case SND_SOC_BIAS_STANDBY:
++		snd_soc_update_bits(codec, AK4642_PM1, 0x40, 0x40);
++		break;
++	case SND_SOC_BIAS_OFF:
++		/* Everything is OFF */
++		snd_soc_update_bits(codec, AK4642_PM1, 0x40, 0);
++		break;
++	}
++	codec->dapm.bias_level = level;
++	return 0;
++}
++
++
++#define AK4642_RATES		SNDRV_PCM_RATE_8000_48000
++#define AK4642_FORMATS		SNDRV_PCM_FMTBIT_S16_LE
++
++static const struct snd_soc_dai_ops ak4642_dai_ops = {
++	.hw_params =	ak4642_hw_params,
++	.set_fmt =	ak4642_set_dai_fmt,
++	.digital_mute =	ak4642_mute,
++	.set_sysclk =	ak4642_set_dai_sysclk,
++};
++
++static struct snd_soc_dai_driver ak4642_dai = {
++	.name = "ak4642-hifi",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = AK4642_RATES,
++		.formats = AK4642_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = AK4642_RATES,
++		.formats = AK4642_FORMATS,},
++	.ops = &ak4642_dai_ops,
++};
++
++static int ak4642_suspend(struct snd_soc_codec *codec)
++{
++	ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static int ak4642_resume(struct snd_soc_codec *codec)
++{
++	snd_soc_cache_sync(codec);
++	ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return 0;
++}
++
++static int ak4642_probe(struct snd_soc_codec *codec)
++{
++	struct ak4642_priv *ak4642;
++	int ret;
++
++	dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
++
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++	ak4642 = snd_soc_codec_get_drvdata(codec);
++
++	ret = devm_gpio_request(codec->dev, ak4642->rst_pin, "ak4642 reset");
++	if (ret < 0){
++		dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
++		return ret;
++	}
++
++	/* Reset AK4642 codec */
++	gpio_direction_output(ak4642->rst_pin, ak4642->rst_active);
++	msleep(1);
++	gpio_direction_output(ak4642->rst_pin, !ak4642->rst_active);
++
++	/* power on device */
++	ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	/* Initial some register */
++	/* Select Input to ADC */
++	snd_soc_update_bits(codec, AK4642_PM3, 0x06, 0x06);
++	/* Open DAC to Line-Out */
++	snd_soc_update_bits(codec, AK4642_SIG1, 0x10, 0x10);
++	/* Open DAC to Headphone */
++	snd_soc_update_bits(codec, AK4642_MODE4, 0x01, 0x01);
++	/* Open Line-Out Switch */
++	snd_soc_update_bits(codec, AK4642_PM1, 0x08, 0x08);
++	snd_soc_write(codec, AK4642_LIVOL, 0x91);	/* Input 0db */
++	snd_soc_write(codec, AK4642_RIVOL, 0x91);	/* Input 0db */
++	/* Mic-Amp 0db */
++	snd_soc_update_bits(codec, AK4642_SIG1, 0x01, 0x01);
++	/* Mic-Amp 0db */
++	snd_soc_update_bits(codec, AK4642_SIG2, 0x20, 0x20);
++
++	snd_soc_add_codec_controls(codec, ak4642_snd_controls,
++				ARRAY_SIZE(ak4642_snd_controls));
++
++	return 0;
++}
++
++static int ak4642_remove(struct snd_soc_codec *codec)
++{
++	ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
++	.probe			= ak4642_probe,
++	.remove			= ak4642_remove,
++	.suspend		= ak4642_suspend,
++	.resume			= ak4642_resume,
++	.set_bias_level		= ak4642_set_bias_level,
++	.reg_cache_default	= ak4642_reg,
++	.reg_cache_size		= ARRAY_SIZE(ak4642_reg),
++	.reg_word_size		= sizeof(u8),
++	.reg_cache_step		= 1,
++	.dapm_widgets		= ak4642_dapm_widgets,
++	.num_dapm_widgets	= ARRAY_SIZE(ak4642_dapm_widgets),
++	.dapm_routes		= ak4642_dapm_routes,
++	.num_dapm_routes	= ARRAY_SIZE(ak4642_dapm_routes),
++};
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static int ak4642_i2c_probe(struct i2c_client *i2c,
++			    const struct i2c_device_id *id)
++{
++	struct device_node *np = i2c->dev.of_node;
++	struct ak4642_priv *ak4642;
++	enum of_gpio_flags flags;
++	int rst_pin;
++
++	ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv), GFP_KERNEL);
++	if (ak4642 == NULL)
++		return -ENOMEM;
++
++
++	rst_pin = of_get_gpio_flags(np, 0, &flags);
++	if (rst_pin < 0 || !gpio_is_valid(rst_pin))
++		return -ENXIO;
++
++	ak4642->rst_pin = rst_pin;
++	ak4642->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	i2c_set_clientdata(i2c, ak4642);
++	return snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_ak4642, &ak4642_dai, 1);
++}
++
++static int ak4642_i2c_remove(struct i2c_client *i2c)
++{
++	snd_soc_unregister_codec(&i2c->dev);
++	return 0;
++}
++
++static struct of_device_id ak4642_of_match[] = {
++	{ .compatible = "ambarella,ak4642",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, ak4642_of_match);
++
++static const struct i2c_device_id ak4642_i2c_id[] = {
++	{ "ak4642", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
++
++static struct i2c_driver ak4642_i2c_driver = {
++	.driver = {
++		.name = "ak4642-codec",
++		.owner = THIS_MODULE,
++		.of_match_table = ak4642_of_match,
++	},
++	.probe		=	ak4642_i2c_probe,
++	.remove		=	ak4642_i2c_remove,
++	.id_table	=	ak4642_i2c_id,
++};
++
++#endif
++
++static int __init ak4642_modinit(void)
++{
++	int ret;
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&ak4642_i2c_driver);
++	if (ret != 0)
++		pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
++#endif
++	return ret;
++}
++module_init(ak4642_modinit);
++
++static void __exit ak4642_exit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	i2c_del_driver(&ak4642_i2c_driver);
++#endif
++}
++module_exit(ak4642_exit);
++
++MODULE_DESCRIPTION("Soc AK4642 driver");
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/ak4642_amb.h b/sound/soc/codecs/ak4642_amb.h
+new file mode 100644
+index 00000000..75377e3e
+--- /dev/null
++++ b/sound/soc/codecs/ak4642_amb.h
+@@ -0,0 +1,65 @@
++/*
++ * ak4642.h  --  AK4642 Soc Audio driver
++ *
++ * Copyright 2009 Ambarella Ltd.
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++#ifndef _AK4642_H
++#define _AK4642_H
++
++/* AK4642 register space */
++
++#define AK4642_PM1		0x00
++#define AK4642_PM2		0x01
++#define AK4642_SIG1		0x02
++#define AK4642_SIG2		0x03
++#define AK4642_MODE1		0x04
++#define AK4642_MODE2		0x05
++#define AK4642_TIMER		0x06
++#define AK4642_ALC1		0x07
++#define AK4642_ALC2		0x08
++#define AK4642_LIVOL		0x09
++#define AK4642_LDVOL		0x0a
++#define AK4642_ALC3		0x0b
++#define AK4642_RIVOL		0x0c
++#define AK4642_RDVOL		0x0d
++#define AK4642_MODE3		0x0e
++#define AK4642_MODE4		0x0f
++#define AK4642_PM3		0x10
++#define AK4642_FSEL		0x11
++#define AK4642_F3EF0		0x12
++#define AK4642_F3EF1		0x13
++#define AK4642_F3EF2		0x14
++#define AK4642_F3EF3		0x15
++#define AK4642_EQEF0		0x16
++#define AK4642_EQEF1		0x17
++#define AK4642_EQEF2		0x18
++#define AK4642_EQEF3		0x19
++#define AK4642_EQEF4		0x1a
++#define AK4642_EQEF5		0x1b
++#define AK4642_F1EF0		0x1c
++#define AK4642_E1EF1		0x1d
++#define AK4642_E1EF2		0x1e
++#define AK4642_E1EF3		0x1f
++
++#define AK4642_CACHEREGNUM 	0x20
++
++#define AK4642_SYSCLK	0
++
++#define AK4642_LINE_IN_ON	0
++#define AK4642_BOTH_MIC_ON	1
++#define AK4642_INPUT_UNKNOWN	2
++
++#define AK4642_MCLK_IN	0
++#define AK4642_BCLK_IN	1
++#define AK4642_MCLK_IN_BCLK_OUT	2
++
++
++
++#endif
+diff --git a/sound/soc/codecs/ak4951_amb.c b/sound/soc/codecs/ak4951_amb.c
+new file mode 100644
+index 00000000..873b9c42
+--- /dev/null
++++ b/sound/soc/codecs/ak4951_amb.c
+@@ -0,0 +1,1317 @@
++/*
++ * ak4951_amb.c  --  audio driver for AK4951
++ *
++ * Copyright 2014 Ambarella Ltd.
++ *
++ * Author: Diao Chengdong <cddiao@ambarella.com>
++ *
++ * History:
++ *	2014/03/27 - created
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/of_gpio.h>
++#include <linux/regmap.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++
++#include "ak4951_amb.h"
++
++//#define PLL_32BICK_MODE
++//#define PLL_64BICK_MODE
++
++//#define AK4951_DEBUG			//used at debug mode
++//#define AK4951_CONTIF_DEBUG		//used at debug mode
++
++#ifdef AK4951_DEBUG
++#define akdbgprt printk
++#else
++#define akdbgprt(format, arg...) do {} while (0)
++#endif
++
++#define LINEIN1_MIC_BIAS_CONNECT
++#define LINEIN2_MIC_BIAS_CONNECT
++
++/* AK4951 Codec Private Data */
++struct ak4951_priv {
++	unsigned int rst_pin;
++	unsigned int rst_active;
++	unsigned int sysclk;
++	unsigned int clkid;
++	struct regmap *regmap;
++	struct i2c_client* i2c_clt;
++	u8 reg_cache[AK4951_MAX_REGISTERS];
++	int onStereo;
++	int mic;
++	u8 fmt;
++};
++
++struct ak4951_priv *ak4951_data;
++
++/*
++ * ak4951 register
++ */
++static struct reg_default  ak4951_reg_defaults[] = {
++	{ 0,  0x00 },
++	{ 1,  0x00 },
++	{ 2,  0x06 },
++	{ 3,  0x00 },
++	{ 4,  0x44 },
++	{ 5,  0x52 },
++	{ 6,  0x09 },
++	{ 7,  0x14 },
++	{ 8,  0x00 },
++	{ 9,  0x00 },
++	{ 10, 0x60 },
++	{ 11, 0x00 },
++	{ 12, 0xE1 },
++	{ 13, 0xE1 },
++	{ 14, 0xE1 },
++	{ 15, 0x00 },
++	{ 16, 0x80 },
++	{ 17, 0x80 },
++	{ 18, 0x00 },
++	{ 19, 0x18 },
++	{ 20, 0x18 },
++	{ 21, 0x00 },
++	{ 22, 0x00 },
++	{ 23, 0x00 },
++	{ 24, 0x00 },
++	{ 25, 0x00 },
++	{ 26, 0x0C },
++	{ 27, 0x01 },
++	{ 28, 0x00 },
++	{ 29, 0x03 },
++	{ 30, 0xA9 },
++	{ 31, 0x1F },
++	{ 32, 0xAD },
++	{ 33, 0x20 },
++	{ 34, 0x7F },
++	{ 35, 0x0C },
++	{ 36, 0xFF },
++	{ 37, 0x38 },
++	{ 38, 0xA2 },
++	{ 39, 0x83 },
++	{ 40, 0x80 },
++	{ 41, 0x2E },
++	{ 42, 0x5B },
++	{ 43, 0x23 },
++	{ 44, 0x07 },
++	{ 45, 0x28 },
++	{ 46, 0xAA },
++	{ 47, 0xEC },
++	{ 48, 0x00 },
++	{ 49, 0x00 },
++	{ 50, 0x9F },
++	{ 51, 0x00 },
++	{ 52, 0x2B },
++	{ 53, 0x3F },
++	{ 54, 0xD4 },
++	{ 55, 0xE0 },
++	{ 56, 0x6A },
++	{ 57, 0x00 },
++	{ 58, 0x1B },
++	{ 59, 0x3F },
++	{ 60, 0xD4 },
++	{ 61, 0xE0 },
++	{ 62, 0x6A },
++	{ 63, 0x00 },
++	{ 64, 0xA2 },
++	{ 65, 0x3E },
++	{ 66, 0xD4 },
++	{ 67, 0xE0 },
++	{ 68, 0x6A },
++	{ 69, 0x00 },
++	{ 70, 0xA8 },
++	{ 71, 0x38 },
++	{ 72, 0xD4 },
++	{ 73, 0xE0 },
++	{ 74, 0x6A },
++	{ 75, 0x00 },
++	{ 76, 0x96 },
++	{ 77, 0x1F },
++	{ 78, 0xD4 },
++	{ 79, 0xE0 },
++};
++
++static bool ak4951_volatile_register(struct device *dev,
++							unsigned int reg)
++{
++	switch (reg) {
++		case AK4951_00_POWER_MANAGEMENT1:
++		case AK4951_01_POWER_MANAGEMENT2:
++		case AK4951_02_SIGNAL_SELECT1:
++		case AK4951_03_SIGNAL_SELECT2:
++		case AK4951_04_SIGNAL_SELECT3:
++		case AK4951_05_MODE_CONTROL1:
++		case AK4951_06_MODE_CONTROL2:
++		case AK4951_07_MODE_CONTROL3:
++		case AK4951_08_DIGITL_MIC:
++		case AK4951_09_TIMER_SELECT:
++		case AK4951_0A_ALC_TIMER_SELECT:
++		case AK4951_0B_ALC_MODE_CONTROL1:
++		case AK4951_0C_ALC_MODE_CONTROL2:
++		case AK4951_0D_LCH_INPUT_VOLUME_CONTROL:
++		case AK4951_0E_RCH_INPUT_VOLUME_CONTROL:
++		case AK4951_0F_ALC_VOLUME:
++		case AK4951_10_LCH_MIC_GAIN_SETTING:
++		case AK4951_11_RCH_MIC_GAIN_SETTING:
++		case AK4951_12_BEEP_CONTROL:
++		case AK4951_13_LCH_DIGITAL_VOLUME_CONTROL:
++		case AK4951_14_RCH_DIGITAL_VOLUME_CONTROL:
++		case AK4951_15_EQ_COMMON_GAIN_SELECT:
++		case AK4951_16_EQ2_COMMON_GAIN_SELECT:
++		case AK4951_17_EQ3_COMMON_GAIN_SELECT:
++		case AK4951_18_EQ4_COMMON_GAIN_SELECT:
++		case AK4951_19_EQ5_COMMON_GAIN_SELECT:
++		case AK4951_1A_AUTO_HPF_CONTROL:
++		case AK4951_1B_DIGITAL_FILTER_SELECT1:
++		case AK4951_1C_DIGITAL_FILTER_SELECT2:
++		case AK4951_1D_DIGITAL_FILTER_MODE:
++		case AK4951_1E_HPF2_COEFFICIENT0:
++		case AK4951_1F_HPF2_COEFFICIENT1:
++		case AK4951_20_HPF2_COEFFICIENT2:
++		case AK4951_21_HPF2_COEFFICIENT3:
++		case AK4951_22_LPF_COEFFICIENT0:
++		case AK4951_23_LPF_COEFFICIENT1:
++		case AK4951_24_LPF_COEFFICIENT2:
++		case AK4951_25_LPF_COEFFICIENT3:
++		case AK4951_26_FIL3_COEFFICIENT0:
++		case AK4951_27_FIL3_COEFFICIENT1:
++		case AK4951_28_FIL3_COEFFICIENT2:
++		case AK4951_29_FIL3_COEFFICIENT3:
++		case AK4951_2A_EQ_COEFFICIENT0:
++		case AK4951_2B_EQ_COEFFICIENT1:
++		case AK4951_2C_EQ_COEFFICIENT2:
++		case AK4951_2D_EQ_COEFFICIENT3:
++		case AK4951_2E_EQ_COEFFICIENT4:
++		case AK4951_2F_EQ_COEFFICIENT5:
++		case AK4951_30_DIGITAL_FILTER_SELECT3:
++		case AK4951_31_DEVICE_INFO:
++		case AK4951_32_E1_COEFFICIENT0:
++		case AK4951_33_E1_COEFFICIENT1:
++		case AK4951_34_E1_COEFFICIENT2:
++		case AK4951_35_E1_COEFFICIENT3:
++		case AK4951_36_E1_COEFFICIENT4:
++		case AK4951_37_E1_COEFFICIENT5:
++		case AK4951_38_E2_COEFFICIENT0:
++		case AK4951_39_E2_COEFFICIENT1:
++		case AK4951_3A_E2_COEFFICIENT2:
++		case AK4951_3B_E2_COEFFICIENT3:
++		case AK4951_3C_E2_COEFFICIENT4:
++		case AK4951_3D_E2_COEFFICIENT5:
++		case AK4951_3E_E3_COEFFICIENT0:
++		case AK4951_3F_E3_COEFFICIENT1:
++		case AK4951_40_E3_COEFFICIENT2:
++		case AK4951_41_E3_COEFFICIENT3:
++		case AK4951_42_E3_COEFFICIENT4:
++		case AK4951_43_E3_COEFFICIENT5:
++		case AK4951_44_E4_COEFFICIENT0:
++		case AK4951_45_E4_COEFFICIENT1:
++		case AK4951_46_E4_COEFFICIENT2:
++		case AK4951_47_E4_COEFFICIENT3:
++		case AK4951_48_E4_COEFFICIENT4:
++		case AK4951_49_E4_COEFFICIENT5:
++		case AK4951_4A_E5_COEFFICIENT0:
++		case AK4951_4B_E5_COEFFICIENT1:
++		case AK4951_4C_E5_COEFFICIENT2:
++		case AK4951_4D_E5_COEFFICIENT3:
++		case AK4951_4E_E5_COEFFICIENT4:
++		case AK4951_4F_E5_COEFFICIENT5:
++		return true;
++
++	default:
++		return false;
++	}
++}
++
++static inline int aK4951_reset(struct regmap *map)
++{
++	return regmap_write(map, AK4951_00_POWER_MANAGEMENT1, 0x00);
++}
++
++/*
++ *  MIC Gain control:
++ * from 6 to 26 dB in 6.5 dB steps
++ *
++ * MIC Gain control: (table 39)
++ *
++ * max : 0x00 : +12.0 dB
++ *       ( 0.5 dB step )
++ * min : 0xFE : -115.0 dB
++ * mute: 0xFF
++ */
++static DECLARE_TLV_DB_SCALE(mgain_tlv, 600, 650, 0);
++
++/*
++ * Input Digital volume control: (Table 44)
++ *
++ * max : 0xF1 : +36.0 dB
++ *       ( 0.375 dB step )
++ * min : 0x00 : -54.375 dB
++ * mute: 0x00 - 0x04
++ * from -54.375 to 36 dB in 0.375 dB steps mute instead of -54.375 dB)
++ */
++static DECLARE_TLV_DB_SCALE(ivol_tlv, -5437, 37, 1);
++
++/*
++ * Speaker output volume control: (Table 55)
++ *
++ * max : 0x11: +14.9dB
++ *       0x10: +11.1dB
++ *		 0x01: +8.4 dB
++ * min : 0x00: +6.4 dB
++ * from 6.4 to 14.9 dB in 2.8 dB steps
++ */
++static DECLARE_TLV_DB_SCALE(spkout_tlv, 640, 280, 0);
++
++/*
++ * Output Digital volume control: (Table 49)
++ * (This can be used as Bluetooth I/F output volume)
++ *
++ * max : 0x00: +12.0 dB
++ *       ( 0.5 dB step )
++ * min : 0x90: -66.0 dB
++ * from -90.0 to 12 dB in 0.5 dB steps (mute instead of -90.0 dB)
++ */
++static DECLARE_TLV_DB_SCALE(dvol_tlv, -9000, 50, 1);
++
++/*
++ * Programmable Filter Output volume control: (Table 46)
++  *
++ * max : 0x00: 0.0 dB
++ *       ( 6 dB step )
++ * min : 0x11: -18.0 dB
++ * from -18 to 0 dB in 6 dB steps
++ */
++//static DECLARE_TLV_DB_SCALE(pfvol_tlv, -1800, 600, 0);
++
++/*For our Board -- cddiao*/
++static const char *mic_and_lin_select[]  =
++{
++	"LIN",
++	"MIC",
++};
++
++
++static const struct soc_enum ak4951_micswitch_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mic_and_lin_select), mic_and_lin_select),
++};
++
++
++static int get_micstatus(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak4951->mic;
++
++    return 0;
++
++}
++
++static int set_micstatus(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++
++	ak4951->mic = ucontrol->value.enumerated.item[0];
++
++	if ( ak4951->mic ) {
++		snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
++	}else {
++		snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
++	}
++    return 0;
++}
++
++
++
++static const char *stereo_on_select[]  =
++{
++	"Stereo Emphasis Filter OFF",
++	"Stereo Emphasis Filter ON",
++};
++
++static const struct soc_enum ak4951_stereo_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(stereo_on_select), stereo_on_select),
++};
++
++static int ak4951_writeMask(struct snd_soc_codec *, u16, u16, u16);
++
++static int get_onstereo(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak4951->onStereo;
++
++    return 0;
++
++}
++
++static int set_onstereo(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++
++	ak4951->onStereo = ucontrol->value.enumerated.item[0];
++
++	if ( ak4951->onStereo ) {
++		ak4951_writeMask(codec, AK4951_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x30);
++	}
++	else {
++		ak4951_writeMask(codec, AK4951_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x00);
++	}
++
++    return 0;
++}
++
++#ifdef AK4951_DEBUG
++static const char *test_reg_select[]   =
++{
++    "read AK4951 Reg 00:2F",
++    "read AK4951 Reg 30:4F",
++};
++
++static const struct soc_enum ak4951_enum[] =
++{
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
++};
++
++static int nTestRegNo = 0;
++
++static int get_test_reg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = nTestRegNo;
++
++    return 0;
++
++}
++
++static int set_test_reg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    i, value;
++	int	   regs, rege;
++
++	nTestRegNo = currMode;
++
++	switch(nTestRegNo) {
++		case 1:
++			regs = 0x30;
++			rege = 0x4F;
++			break;
++		default:
++			regs = 0x00;
++			rege = 0x2F;
++			break;
++	}
++
++	for ( i = regs ; i <= rege ; i++ ){
++		value = snd_soc_read(codec, i);
++		printk("***AK4951 Addr,Reg=(%x, %x)\n", i, value);
++	}
++
++	return(0);
++
++}
++#endif
++
++static const struct snd_kcontrol_new ak4951_snd_controls[] = {
++	SOC_SINGLE_TLV("Mic Gain Control",
++			AK4951_02_SIGNAL_SELECT1, 0, 0x07, 0, mgain_tlv),
++	SOC_SINGLE_TLV("Input Digital Volume",
++			AK4951_0D_LCH_INPUT_VOLUME_CONTROL, 0, 0xF1, 0, ivol_tlv),
++	SOC_SINGLE_TLV("Speaker Output Volume",
++			AK4951_03_SIGNAL_SELECT2, 6, 0x03, 0, spkout_tlv),
++	SOC_SINGLE_TLV("Digital Output Volume",
++			AK4951_13_LCH_DIGITAL_VOLUME_CONTROL, 0, 0xFF, 1, dvol_tlv),
++
++    SOC_SINGLE("High Path Filter 1", AK4951_1B_DIGITAL_FILTER_SELECT1, 1, 3, 0),
++    SOC_SINGLE("High Path Filter 2", AK4951_1C_DIGITAL_FILTER_SELECT2, 0, 1, 0),
++    SOC_SINGLE("Low Path Filter", 	 AK4951_1C_DIGITAL_FILTER_SELECT2, 1, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 1", AK4951_30_DIGITAL_FILTER_SELECT3, 0, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 2", AK4951_30_DIGITAL_FILTER_SELECT3, 1, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 3", AK4951_30_DIGITAL_FILTER_SELECT3, 2, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 4", AK4951_30_DIGITAL_FILTER_SELECT3, 3, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 5", AK4951_30_DIGITAL_FILTER_SELECT3, 4, 1, 0),
++	SOC_SINGLE("Auto Level Control 1", AK4951_0B_ALC_MODE_CONTROL1, 5, 1, 0),
++	SOC_SINGLE("Soft Mute Control", AK4951_07_MODE_CONTROL3, 5, 1, 0),
++	SOC_ENUM_EXT("Stereo Emphasis Filter Control", ak4951_stereo_enum[0], get_onstereo, set_onstereo),
++	SOC_ENUM_EXT("Mic and Lin Switch",ak4951_micswitch_enum[0],get_micstatus,set_micstatus),
++#ifdef AK4951_DEBUG
++	SOC_ENUM_EXT("Reg Read", ak4951_enum[0], get_test_reg, set_test_reg),
++#endif
++
++
++};
++
++static const char *ak4951_lin_select_texts[] =
++		{"LIN1", "LIN2", "LIN3"};
++
++static const struct soc_enum ak4951_lin_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_03_SIGNAL_SELECT2, 2,
++			ARRAY_SIZE(ak4951_lin_select_texts), ak4951_lin_select_texts);
++
++static const struct snd_kcontrol_new ak4951_lin_mux_control =
++	SOC_DAPM_ENUM("LIN Select", ak4951_lin_mux_enum);
++
++static const char *ak4951_rin_select_texts[] =
++		{"RIN1", "RIN2", "RIN3"};
++
++static const struct soc_enum ak4951_rin_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_03_SIGNAL_SELECT2, 0,
++			ARRAY_SIZE(ak4951_rin_select_texts), ak4951_rin_select_texts);
++
++static const struct snd_kcontrol_new ak4951_rin_mux_control =
++	SOC_DAPM_ENUM("RIN Select", ak4951_rin_mux_enum);
++//////////////////////////////////////////
++static const char *ak4951_lin1_select_texts[] =
++		{"LIN1", "Mic Bias"};
++
++static const struct soc_enum ak4951_lin1_mux_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak4951_lin1_select_texts), ak4951_lin1_select_texts);
++
++static const struct snd_kcontrol_new ak4951_lin1_mux_control =
++	SOC_DAPM_ENUM_VIRT("LIN1 Switch", ak4951_lin1_mux_enum);
++////////////////////////////////////////////
++
++static const char *ak4951_micbias_select_texts[] =
++		{"LIN1", "LIN2"};
++
++static const struct soc_enum ak4951_micbias_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_02_SIGNAL_SELECT1, 4,
++			ARRAY_SIZE(ak4951_micbias_select_texts), ak4951_micbias_select_texts);
++
++static const struct snd_kcontrol_new ak4951_micbias_mux_control =
++	SOC_DAPM_ENUM("MIC bias Select", ak4951_micbias_mux_enum);
++
++static const char *ak4951_spklo_select_texts[] =
++		{"Speaker", "Line"};
++
++static const struct soc_enum ak4951_spklo_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_01_POWER_MANAGEMENT2, 0,
++			ARRAY_SIZE(ak4951_spklo_select_texts), ak4951_spklo_select_texts);
++
++static const struct snd_kcontrol_new ak4951_spklo_mux_control =
++	SOC_DAPM_ENUM("SPKLO Select", ak4951_spklo_mux_enum);
++
++static const char *ak4951_adcpf_select_texts[] =
++		{"SDTI", "ADC"};
++
++static const struct soc_enum ak4951_adcpf_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_1D_DIGITAL_FILTER_MODE, 1,
++			ARRAY_SIZE(ak4951_adcpf_select_texts), ak4951_adcpf_select_texts);
++
++static const struct snd_kcontrol_new ak4951_adcpf_mux_control =
++	SOC_DAPM_ENUM("ADCPF Select", ak4951_adcpf_mux_enum);
++
++
++static const char *ak4951_pfsdo_select_texts[] =
++		{"ADC", "PFIL"};
++
++static const struct soc_enum ak4951_pfsdo_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_1D_DIGITAL_FILTER_MODE, 0,
++			ARRAY_SIZE(ak4951_pfsdo_select_texts), ak4951_pfsdo_select_texts);
++
++static const struct snd_kcontrol_new ak4951_pfsdo_mux_control =
++	SOC_DAPM_ENUM("PFSDO Select", ak4951_pfsdo_mux_enum);
++
++static const char *ak4951_pfdac_select_texts[] =
++		{"SDTI", "PFIL", "SPMIX"};
++
++static const struct soc_enum ak4951_pfdac_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_1D_DIGITAL_FILTER_MODE, 2,
++			ARRAY_SIZE(ak4951_pfdac_select_texts), ak4951_pfdac_select_texts);
++
++static const struct snd_kcontrol_new ak4951_pfdac_mux_control =
++	SOC_DAPM_ENUM("PFDAC Select", ak4951_pfdac_mux_enum);
++
++
++static const char *ak4951_mic_select_texts[] =
++		{"AMIC", "DMIC"};
++
++static const struct soc_enum ak4951_mic_mux_enum =
++	SOC_ENUM_SINGLE(AK4951_08_DIGITL_MIC, 0,
++			ARRAY_SIZE(ak4951_mic_select_texts), ak4951_mic_select_texts);
++
++static const struct snd_kcontrol_new ak4951_mic_mux_control =
++	SOC_DAPM_ENUM("MIC Select", ak4951_mic_mux_enum);
++
++
++static const struct snd_kcontrol_new ak4951_dacsl_mixer_controls[] = {
++	SOC_DAPM_SINGLE("DACSL", AK4951_02_SIGNAL_SELECT1, 5, 1, 0),
++};
++
++static int ak4951_spklo_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event) //CONFIG_LINF
++{
++	struct snd_soc_codec *codec = w->codec;
++	u32 reg, nLOSEL;
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	reg = snd_soc_read(codec, AK4951_01_POWER_MANAGEMENT2);
++	nLOSEL = (0x1 & reg);
++
++	switch (event) {
++		case SND_SOC_DAPM_PRE_PMU:	/* before widget power up */
++			break;
++		case SND_SOC_DAPM_POST_PMU:	/* after widget power up */
++			if ( nLOSEL ) {
++				akdbgprt("\t[AK4951] %s wait=300msec\n",__FUNCTION__);
++				mdelay(300);
++			}
++			else {
++				akdbgprt("\t[AK4951] %s wait=1msec\n",__FUNCTION__);
++				mdelay(1);
++			}
++			snd_soc_update_bits(codec, AK4951_02_SIGNAL_SELECT1, 0x80,0x80);
++			break;
++		case SND_SOC_DAPM_PRE_PMD:	/* before widget power down */
++			snd_soc_update_bits(codec, AK4951_02_SIGNAL_SELECT1, 0x80,0x00);
++			mdelay(1);
++			break;
++		case SND_SOC_DAPM_POST_PMD:	/* after widget power down */
++			if ( nLOSEL ) {
++				akdbgprt("\t[AK4951] %s wait=300msec\n",__FUNCTION__);
++				mdelay(300);
++			}
++			break;
++	}
++
++	return 0;
++}
++
++static const struct snd_soc_dapm_widget ak4951_dapm_widgets[] = {
++
++// ADC, DAC
++	SND_SOC_DAPM_ADC("ADC Left", "NULL", AK4951_00_POWER_MANAGEMENT1, 0, 0),
++	SND_SOC_DAPM_ADC("ADC Right", "NULL", AK4951_00_POWER_MANAGEMENT1, 1, 0),
++	SND_SOC_DAPM_DAC("DAC", "NULL", AK4951_00_POWER_MANAGEMENT1, 2, 0),
++
++#ifdef PLL_32BICK_MODE
++	SND_SOC_DAPM_SUPPLY("PMPLL", AK4951_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
++#else
++#ifdef PLL_64BICK_MODE
++	SND_SOC_DAPM_SUPPLY("PMPLL", AK4951_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
++#endif
++#endif
++
++	SND_SOC_DAPM_ADC("PFIL", "NULL", AK4951_00_POWER_MANAGEMENT1, 7, 0),
++
++	SND_SOC_DAPM_ADC("DMICL", "NULL", AK4951_08_DIGITL_MIC, 4, 0),
++	SND_SOC_DAPM_ADC("DMICR", "NULL", AK4951_08_DIGITL_MIC, 5, 0),
++
++	SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_IN("SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
++
++// Analog Output
++	SND_SOC_DAPM_OUTPUT("HPL"),
++	SND_SOC_DAPM_OUTPUT("HPR"),
++	SND_SOC_DAPM_OUTPUT("SPKLO"),
++
++	SND_SOC_DAPM_PGA("HPL Amp", AK4951_01_POWER_MANAGEMENT2, 4, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HPR Amp", AK4951_01_POWER_MANAGEMENT2, 5, 0, NULL, 0),
++
++	SND_SOC_DAPM_PGA("SPK Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Line Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	SND_SOC_DAPM_MIXER_E("SPKLO Mixer", AK4951_01_POWER_MANAGEMENT2, 1, 0,
++			&ak4951_dacsl_mixer_controls[0], ARRAY_SIZE(ak4951_dacsl_mixer_controls),
++			ak4951_spklo_event, (SND_SOC_DAPM_POST_PMU |SND_SOC_DAPM_PRE_PMD
++                            |SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMD)),
++
++// Analog Input
++	SND_SOC_DAPM_INPUT("LIN1"),
++	SND_SOC_DAPM_INPUT("RIN1"),
++	SND_SOC_DAPM_INPUT("LIN2"),
++	SND_SOC_DAPM_INPUT("RIN2"),
++	SND_SOC_DAPM_INPUT("LIN3"),
++	SND_SOC_DAPM_INPUT("RIN3"),
++
++	SND_SOC_DAPM_MUX("LIN MUX", SND_SOC_NOPM, 0, 0,	&ak4951_lin_mux_control),
++	SND_SOC_DAPM_MUX("RIN MUX", SND_SOC_NOPM, 0, 0,	&ak4951_rin_mux_control),
++
++// MIC Bias
++	SND_SOC_DAPM_MICBIAS("Mic Bias", AK4951_02_SIGNAL_SELECT1, 3, 0),
++	SND_SOC_DAPM_VIRT_MUX("LIN1 MUX", SND_SOC_NOPM, 0, 0, &ak4951_lin1_mux_control),
++	SND_SOC_DAPM_MUX("Mic Bias MUX", SND_SOC_NOPM, 0, 0, &ak4951_micbias_mux_control),
++	SND_SOC_DAPM_MUX("SPKLO MUX", SND_SOC_NOPM, 0, 0, &ak4951_spklo_mux_control),
++
++
++// PFIL
++	SND_SOC_DAPM_MUX("PFIL MUX", SND_SOC_NOPM, 0, 0, &ak4951_adcpf_mux_control),
++	SND_SOC_DAPM_MUX("PFSDO MUX", SND_SOC_NOPM, 0, 0, &ak4951_pfsdo_mux_control),
++	SND_SOC_DAPM_MUX("PFDAC MUX", SND_SOC_NOPM, 0, 0, &ak4951_pfdac_mux_control),
++
++// Digital Mic
++	SND_SOC_DAPM_INPUT("DMICLIN"),
++	SND_SOC_DAPM_INPUT("DMICRIN"),
++
++	SND_SOC_DAPM_VIRT_MUX("MIC MUX", SND_SOC_NOPM, 0, 0, &ak4951_mic_mux_control),
++
++};
++
++
++static const struct snd_soc_dapm_route ak4951_intercon[] = {
++
++#ifdef PLL_32BICK_MODE
++	{"ADC Left", "NULL", "PMPLL"},
++	{"ADC Right", "NULL", "PMPLL"},
++	{"DAC", "NULL", "PMPLL"},
++#else
++#ifdef PLL_64BICK_MODE
++	{"ADC Left", "NULL", "PMPLL"},
++	{"ADC Right", "NULL", "PMPLL"},
++	{"DAC", "NULL", "PMPLL"},
++#endif
++#endif
++
++	{"Mic Bias MUX", "LIN1", "LIN1"},
++	{"Mic Bias MUX", "LIN2", "LIN2"},
++
++	{"Mic Bias", "NULL", "Mic Bias MUX"},
++
++	{"LIN1 MUX", "LIN1", "LIN1"},
++	{"LIN1 MUX", "Mic Bias", "Mic Bias"},
++
++	{"LIN MUX", "LIN1", "LIN1 MUX"},
++	{"LIN MUX", "LIN2", "Mic Bias"},
++	{"LIN MUX", "LIN3", "LIN3"},
++	{"RIN MUX", "RIN1", "RIN1"},
++	{"RIN MUX", "RIN2", "RIN2"},
++	{"RIN MUX", "RIN3", "RIN3"},
++	{"ADC Left", "NULL", "LIN MUX"},
++	{"ADC Right", "NULL", "RIN MUX"},
++
++	{"DMICL", "NULL", "DMICLIN"},
++	{"DMICR", "NULL", "DMICRIN"},
++
++	{"MIC MUX", "AMIC", "ADC Left"},
++	{"MIC MUX", "AMIC", "ADC Right"},
++	{"MIC MUX", "DMIC", "DMICL"},
++	{"MIC MUX", "DMIC", "DMICR"},
++
++	{"PFIL MUX", "SDTI", "SDTI"},
++	{"PFIL MUX", "ADC", "MIC MUX"},
++	{"PFIL", "NULL", "PFIL MUX"},
++
++	{"PFSDO MUX", "ADC", "MIC MUX"},
++	{"PFSDO MUX", "PFIL", "PFIL"},
++
++	{"SDTO", "NULL", "PFSDO MUX"},
++
++	{"PFDAC MUX", "SDTI", "SDTI"},
++	{"PFDAC MUX", "PFIL", "PFIL"},
++
++//	{"DAC MUX", "PFDAC", "PFDAC MUX"},
++	{"DAC", "NULL", "PFDAC MUX"},
++
++//	{"DAC", "NULL", "DAC MUX"},
++
++	{"HPL Amp", "NULL", "DAC"},
++	{"HPR Amp", "NULL", "DAC"},
++	{"HPL", "NULL", "HPL Amp"},
++	{"HPR", "NULL", "HPR Amp"},
++
++	{"SPKLO Mixer", "DACSL", "DAC"},
++	{"SPK Amp", "NULL", "SPKLO Mixer"},
++	{"Line Amp", "NULL", "SPKLO Mixer"},
++	{"SPKLO MUX", "Speaker", "SPK Amp"},
++	{"SPKLO MUX", "Line", "Line Amp"},
++	{"SPKLO", "NULL", "SPKLO MUX"},
++
++};
++
++static int ak4951_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	int rate = params_rate(params);
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++	int oversample = 0;
++	u8 	fs = 0;
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++	oversample = ak4951->sysclk / rate;
++	switch (oversample) {
++	case 256:
++		fs &= (~AK4951_FS_CM1);
++		fs &= (~AK4951_FS_CM0);
++		break;
++	case 384:
++		fs &= (~AK4951_FS_CM1);
++		fs |= AK4951_FS_CM0;
++		break;
++	case 512:
++		fs |= AK4951_FS_CM1;
++		fs &= (~AK4951_FS_CM0);
++		break;
++	case 1024:
++		fs |= AK4951_FS_CM1;
++		fs |= AK4951_FS_CM0;
++		break;
++	default:
++		break;
++	}
++
++	if(ak4951->clkid == AK4951_BCLK_IN) {
++		switch (rate) {
++			case 8000:
++				fs |= AK4951_BICK_FS_8KHZ;
++				break;
++			case 11025:
++				fs |= AK4951_BICK_FS_11_025KHZ;
++				break;
++			case 12000:
++				fs |= AK4951_BICK_FS_12KHZ;
++				break;
++			case 16000:
++				fs |= AK4951_BICK_FS_16KHZ;
++				break;
++			case 22050:
++				fs |= AK4951_BICK_FS_22_05KHZ;
++				break;
++			case 24000:
++				fs |= AK4951_BICK_FS_24KHZ;
++				break;
++			case 32000:
++				fs |= AK4951_BICK_FS_32KHZ;
++				break;
++			case 44100:
++				fs |= AK4951_BICK_FS_44_1KHZ;
++				break;
++			case 48000:
++				fs |= AK4951_BICK_FS_48KHZ;
++				break;
++
++			default:
++				return -EINVAL;
++		}
++
++	} else {
++		switch (rate) {
++			case 8000:
++				fs |= AK4951_MCKI_FS_8KHZ;
++				break;
++			case 11025:
++				fs |= AK4951_MCKI_FS_11_025KHZ;
++				break;
++			case 12000:
++				fs |= AK4951_MCKI_FS_12KHZ;
++				break;
++			case 16000:
++				fs |= AK4951_MCKI_FS_16KHZ;
++				break;
++			case 22050:
++				fs |= AK4951_MCKI_FS_22_05KHZ;
++				break;
++			case 24000:
++				fs |= AK4951_MCKI_FS_24KHZ;
++				break;
++			case 32000:
++				fs |= AK4951_MCKI_FS_32KHZ;
++				break;
++			case 44100:
++				fs |= AK4951_MCKI_FS_44_1KHZ;
++				break;
++			case 48000:
++				fs |= AK4951_MCKI_FS_48KHZ;
++				break;
++
++			default:
++				return -EINVAL;
++		}
++	}
++
++	switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			ak4951->fmt = 2 << 4;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			ak4951->fmt = 3 << 4;
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			ak4951->fmt = 3 << 4;
++			break;
++		default:
++			dev_err(codec->dev, "Can not support the format");
++			return -EINVAL;
++	}
++	snd_soc_write(codec, AK4951_06_MODE_CONTROL2, fs);
++
++	return 0;
++}
++
++static int ak4951_set_pll(u8 *pll, int clk_id,int freq)
++{
++	if (clk_id == AK4951_MCLK_IN_BCLK_OUT){
++		switch (freq) {
++		case 11289600:
++			*pll |= (4 << 4);
++			break;
++		case 12288000:
++			*pll |= (5 << 4);
++			break;
++		case 12000000:
++			*pll |= (6 << 4);
++			break;
++		case 24000000:
++			*pll |= (7 << 4);
++			break;
++		case 13500000:
++			*pll |= (0xC << 4);
++			break;
++		case 27000000:
++			*pll |= (0xD << 4);
++			break;
++		default:
++			break;
++		}
++	}
++
++	return 0;
++}
++
++static int ak4951_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
++		unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++	u8 pllpwr = 0, pll = 0;
++
++	akdbgprt("\t[AK4951] %s(%d),CLK id is %d\n",__FUNCTION__,__LINE__, clk_id);
++
++	pll= snd_soc_read(codec, AK4951_05_MODE_CONTROL1);
++	akdbgprt("\t[AK4951] pll valuse is 0x%x\n",pll);
++	pll &=(~0xF0);
++	pllpwr = snd_soc_read(codec,AK4951_01_POWER_MANAGEMENT2);
++	akdbgprt("\t[AK4951] pllpwr valuse is 0x%x\n",pllpwr);
++	pllpwr &=(~0x0c);
++
++	if (clk_id == AK4951_MCLK_IN) {
++		pll |= AK4951_PLL_12_288MHZ;
++		pllpwr &= (~AK4951_PMPLL);
++		pllpwr &= (~AK4951_M_S);
++	}else if (clk_id == AK4951_BCLK_IN) {
++		pllpwr |= AK4951_PMPLL;
++		pllpwr &= (~AK4951_M_S);
++		pll |= ak4951->fmt;
++	}else if (clk_id == AK4951_MCLK_IN_BCLK_OUT) {
++		pllpwr |= AK4951_PMPLL;
++		pllpwr |= AK4951_M_S;
++		ak4951_set_pll(&pll, clk_id, freq);
++	}
++	snd_soc_write(codec, AK4951_05_MODE_CONTROL1, pll);
++	snd_soc_write(codec, AK4951_01_POWER_MANAGEMENT2, pllpwr);
++	msleep(5); //AKM suggested
++
++	ak4951->sysclk = freq;
++	ak4951->clkid = clk_id;
++	return 0;
++}
++
++static int ak4951_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++
++	struct snd_soc_codec *codec = dai->codec;
++	u8 mode;
++	u8 format;
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	/* set master/slave audio interface */
++	mode = snd_soc_read(codec, AK4951_01_POWER_MANAGEMENT2);
++	format = snd_soc_read(codec, AK4951_05_MODE_CONTROL1);
++	format &= ~AK4951_DIF;
++
++    switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++        case SND_SOC_DAIFMT_CBS_CFS:
++			akdbgprt("\t[AK4951] %s(Slave)\n",__FUNCTION__);
++            mode &= ~(AK4951_M_S);
++            //format &= ~(AK4951_BCKO);
++            break;
++        case SND_SOC_DAIFMT_CBM_CFM:
++			akdbgprt("\t[AK4951] %s(Master)\n",__FUNCTION__);
++            mode |= AK4951_M_S;
++            //format |= (AK4951_BCKO);
++            break;
++        case SND_SOC_DAIFMT_CBS_CFM:
++        case SND_SOC_DAIFMT_CBM_CFS:
++        default:
++            dev_err(codec->dev, "Clock mode unsupported");
++           return -EINVAL;
++	}
++
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++		case SND_SOC_DAIFMT_I2S:
++			format |= AK4951_DIF_I2S_MODE;
++			break;
++		case SND_SOC_DAIFMT_LEFT_J:
++			format |= AK4951_DIF_24MSB_MODE;
++			break;
++		default:
++			return -EINVAL;
++	}
++
++	/* set mode and format */
++
++	snd_soc_write(codec, AK4951_01_POWER_MANAGEMENT2, mode);
++	snd_soc_write(codec, AK4951_05_MODE_CONTROL1, format);
++
++	return 0;
++}
++
++/*
++ * Write with Mask to  AK4951 register space
++ */
++static int ak4951_writeMask(
++struct snd_soc_codec *codec,
++u16 reg,
++u16 mask,
++u16 value)
++{
++    u16 olddata;
++    u16 newdata;
++
++	if ( (mask == 0) || (mask == 0xFF) ) {
++		newdata = value;
++	}
++	else {
++		olddata = snd_soc_read(codec, reg);
++	    newdata = (olddata & ~(mask)) | value;
++	}
++
++	snd_soc_write(codec, (unsigned int)reg, (unsigned int)newdata);
++
++	akdbgprt("\t[ak4951_writeMask] %s(%d): (addr,data)=(%x, %x)\n",__FUNCTION__,__LINE__, reg, newdata);
++
++    return(0);
++}
++
++// * for AK4951
++static int ak4951_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *codec_dai)
++{
++	int 	ret = 0;
++ //   struct snd_soc_codec *codec = codec_dai->codec;
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	return ret;
++}
++
++
++static int ak4951_set_bias_level(struct snd_soc_codec *codec,
++		enum snd_soc_bias_level level)
++{
++	u8 reg;
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++	case SND_SOC_BIAS_PREPARE:
++	case SND_SOC_BIAS_STANDBY:
++		reg = snd_soc_read(codec, AK4951_00_POWER_MANAGEMENT1);	// * for AK4951
++		snd_soc_write(codec, AK4951_00_POWER_MANAGEMENT1,			// * for AK4951
++				reg | AK4951_PMVCM | AK4951_PMPFIL);
++		msleep(250);	//AKM suggested
++		break;
++	case SND_SOC_BIAS_OFF:
++		snd_soc_write(codec, AK4951_00_POWER_MANAGEMENT1, 0x00);	// * for AK4951
++		break;
++	}
++	codec->dapm.bias_level = level;
++	return 0;
++}
++
++#define AK4951_RATES		(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++				SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
++				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
++				SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
++				SNDRV_PCM_RATE_96000)
++
++#define AK4951_FORMATS		(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_ops ak4951_dai_ops = {
++	.hw_params	= ak4951_hw_params,
++	.set_sysclk	= ak4951_set_dai_sysclk,
++	.set_fmt	= ak4951_set_dai_fmt,
++	.trigger = ak4951_trigger,
++};
++
++struct snd_soc_dai_driver ak4951_dai[] = {
++	{
++		.name = "ak4951-hifi",
++		.playback = {
++		       .stream_name = "Playback",
++		       .channels_min = 1,
++		       .channels_max = 2,
++		       .rates = AK4951_RATES,
++		       .formats = AK4951_FORMATS,
++		},
++		.capture = {
++		       .stream_name = "Capture",
++		       .channels_min = 1,
++		       .channels_max = 2,
++		       .rates = AK4951_RATES,
++		       .formats = AK4951_FORMATS,
++		},
++		.ops = &ak4951_dai_ops,
++	},
++};
++
++static int ak4951_probe(struct snd_soc_codec *codec)
++{
++	struct ak4951_priv *ak4951 = ak4951_data;
++	int ret = 0;
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++	codec->control_data = ak4951->regmap;
++	snd_soc_codec_set_drvdata(codec, ak4951);
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++	akdbgprt("\t[AK4951] %s(%d) ak4951=%x\n",__FUNCTION__,__LINE__, (int)ak4951);
++
++	ret = devm_gpio_request(codec->dev, ak4951->rst_pin, "ak4951 reset");
++	if (ret < 0){
++		dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
++		return ret;
++	}
++
++	/* Reset AK4951 codec */
++	gpio_direction_output(ak4951->rst_pin, ak4951->rst_active);
++	msleep(1);
++	gpio_direction_output(ak4951->rst_pin, !ak4951->rst_active);
++
++	/*The 0x00 register no Ack for the dummy command:write 0x00 to 0x00*/
++	ak4951->i2c_clt->flags |= I2C_M_IGNORE_NAK;
++	i2c_smbus_write_byte_data(ak4951->i2c_clt, (u8)(AK4951_00_POWER_MANAGEMENT1 & 0xFF), 0x00);
++	ak4951->i2c_clt->flags &= ~I2C_M_IGNORE_NAK;
++
++	ak4951_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	akdbgprt("\t[AK4951 bias] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak4951->onStereo = 0;
++	ak4951->mic = 1;
++	/*Enable Line out */
++	snd_soc_update_bits(codec,AK4951_01_POWER_MANAGEMENT2,0x02,0x02);
++	snd_soc_update_bits(codec,AK4951_02_SIGNAL_SELECT1, 0xa0,0xa0);//0x10100110
++
++	/*Enable LIN2*/
++	snd_soc_update_bits(codec,AK4951_02_SIGNAL_SELECT1,0x18,0x08);//MPWR1
++	snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
++	snd_soc_update_bits(codec,AK4951_08_DIGITL_MIC,0x01,0x00);//AMIC
++	snd_soc_update_bits(codec,AK4951_1D_DIGITAL_FILTER_MODE,0x02,0x02);//ADC output
++	snd_soc_update_bits(codec,AK4951_1D_DIGITAL_FILTER_MODE,0x01,0x01);//ALC output
++	snd_soc_update_bits(codec,AK4951_02_SIGNAL_SELECT1,0x47,0x00);//Mic Gain 0x10100110
++	snd_soc_update_bits(codec,AK4951_0D_LCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
++	snd_soc_update_bits(codec,AK4951_0E_RCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
++	snd_soc_write(codec, AK4951_0B_ALC_MODE_CONTROL1, 0x20);	//enable ALC
++	snd_soc_write(codec, AK4951_1B_DIGITAL_FILTER_SELECT1, 0x07); //enable HPF1
++	snd_soc_write(codec, AK4951_0C_ALC_MODE_CONTROL2, 0xF1);
++	/*Enable LIN3*/
++	//snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
++    return ret;
++
++}
++
++static int ak4951_remove(struct snd_soc_codec *codec)
++{
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak4951_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++
++	return 0;
++}
++
++static int ak4951_suspend(struct snd_soc_codec *codec)
++{
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++	int i;
++
++	for(i = 0; i < 7; i++) {
++		ak4951->reg_cache[i] = snd_soc_read(codec, i);
++	}
++
++	ak4951_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	return 0;
++}
++
++static int ak4951_resume(struct snd_soc_codec *codec)
++{
++	struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
++	int i;
++
++	for(i = 0; i < 7; i++) {
++		snd_soc_write(codec, i, ak4951->reg_cache[i]);
++	}
++
++	ak4951_set_bias_level(codec, codec->dapm.bias_level);
++
++	return 0;
++}
++
++
++struct snd_soc_codec_driver soc_codec_dev_ak4951 = {
++	.probe = ak4951_probe,
++	.remove = ak4951_remove,
++	.suspend =	ak4951_suspend,
++	.resume =	ak4951_resume,
++
++	.set_bias_level = ak4951_set_bias_level,
++
++	.controls = ak4951_snd_controls,
++	.num_controls = ARRAY_SIZE(ak4951_snd_controls),
++	.dapm_widgets = ak4951_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(ak4951_dapm_widgets),
++	.dapm_routes = ak4951_intercon,
++	.num_dapm_routes = ARRAY_SIZE(ak4951_intercon),
++};
++EXPORT_SYMBOL_GPL(soc_codec_dev_ak4951);
++
++static struct regmap_config ak4951_regmap = {
++	.reg_bits = 8,
++	.val_bits = 8,
++
++	.max_register = AK4951_MAX_REGISTERS,
++	.reg_defaults = ak4951_reg_defaults,
++	.num_reg_defaults = ARRAY_SIZE(ak4951_reg_defaults),
++	.volatile_reg = ak4951_volatile_register,
++	.cache_type = REGCACHE_RBTREE,
++};
++
++static int ak4951_i2c_probe(struct i2c_client *i2c,
++                            const struct i2c_device_id *id)
++{
++	struct device_node *np = i2c->dev.of_node;
++	struct ak4951_priv *ak4951;
++	enum of_gpio_flags flags;
++	int rst_pin;
++	int ret = 0;
++
++	akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak4951 = devm_kzalloc(&i2c->dev, sizeof(struct ak4951_priv), GFP_KERNEL);
++	if (ak4951 == NULL)
++		return -ENOMEM;
++
++	rst_pin = of_get_gpio_flags(np, 0, &flags);
++	if (rst_pin < 0 || !gpio_is_valid(rst_pin))
++		return -ENXIO;
++
++	ak4951->i2c_clt = i2c;
++	ak4951->rst_pin = rst_pin;
++	ak4951->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	i2c_set_clientdata(i2c, ak4951);
++	ak4951->regmap = devm_regmap_init_i2c(i2c, &ak4951_regmap);
++	if (IS_ERR(ak4951->regmap)) {
++		ret = PTR_ERR(ak4951->regmap);
++		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
++		return ret;
++	}
++
++	ak4951_data = ak4951;
++
++	ret = snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_ak4951, &ak4951_dai[0], ARRAY_SIZE(ak4951_dai));
++	if (ret < 0){
++		kfree(ak4951);
++		akdbgprt("\t[AK4951 Error!] %s(%d)\n",__FUNCTION__,__LINE__);
++	}
++	return ret;
++}
++
++static int ak4951_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	kfree(i2c_get_clientdata(client));
++	return 0;
++}
++
++static struct of_device_id ak4951_of_match[] = {
++	{ .compatible = "ambarella,ak4951",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, ak4951_of_match);
++
++static const struct i2c_device_id ak4951_i2c_id[] = {
++	{ "ak4951", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, ak4951_i2c_id);
++
++static struct i2c_driver ak4951_i2c_driver = {
++	.driver = {
++		.name = "ak4951-codec",
++		.owner = THIS_MODULE,
++		.of_match_table = ak4951_of_match,
++	},
++	.probe		=	ak4951_i2c_probe,
++	.remove		=	ak4951_i2c_remove,
++	.id_table	=	ak4951_i2c_id,
++};
++
++static int __init ak4951_modinit(void)
++{
++	int ret;
++	akdbgprt("\t[AK4951] %s(%d)\n", __FUNCTION__,__LINE__);
++
++	ret = i2c_add_driver(&ak4951_i2c_driver);
++	if (ret != 0)
++		pr_err("Failed to register ak4951 I2C driver: %d\n",ret);
++	return ret;
++}
++
++module_init(ak4951_modinit);
++
++static void __exit ak4951_exit(void)
++{
++	i2c_del_driver(&ak4951_i2c_driver);
++}
++module_exit(ak4951_exit);
++
++MODULE_DESCRIPTION("Soc AK4951 driver");
++MODULE_AUTHOR("Diao Chengdong<cddiao@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/ak4951_amb.h b/sound/soc/codecs/ak4951_amb.h
+new file mode 100644
+index 00000000..919ce5ed
+--- /dev/null
++++ b/sound/soc/codecs/ak4951_amb.h
+@@ -0,0 +1,167 @@
++/*
++ * ak4954_amb.h  --  audio driver for AK4951
++ *
++ * Copyright 2014 Ambarella Ltd.
++ *
++ * Author: Diao Chengdong <cddiao@ambarella.com>
++ *
++ * History:
++ *	2014/03/27 - created
++ *
++ * 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.
++ */
++
++
++#ifndef _AK4951_AMB_H
++#define _AK4951_AMB_H
++
++#define AK4954_CLOCK_PLAYBACK	1
++#define AK4954_CLOCK_CAPTURE	2
++#define AK4954_CLOCK_OTHER		4
++
++#define AK4951_00_POWER_MANAGEMENT1		0x00
++#define AK4951_01_POWER_MANAGEMENT2		0x01
++#define AK4951_02_SIGNAL_SELECT1		0x02
++#define AK4951_03_SIGNAL_SELECT2		0x03
++#define AK4951_04_SIGNAL_SELECT3		0x04
++#define AK4951_05_MODE_CONTROL1			0x05
++#define AK4951_06_MODE_CONTROL2			0x06
++#define AK4951_07_MODE_CONTROL3			0x07
++#define AK4951_08_DIGITL_MIC			0x08
++#define AK4951_09_TIMER_SELECT			0x09
++#define AK4951_0A_ALC_TIMER_SELECT		0x0A
++#define AK4951_0B_ALC_MODE_CONTROL1		0x0B
++#define AK4951_0C_ALC_MODE_CONTROL2		0x0C
++#define AK4951_0D_LCH_INPUT_VOLUME_CONTROL		0x0D
++#define AK4951_0E_RCH_INPUT_VOLUME_CONTROL		0x0E
++#define AK4951_0F_ALC_VOLUME			0x0F
++#define AK4951_10_LCH_MIC_GAIN_SETTING				0x10
++#define AK4951_11_RCH_MIC_GAIN_SETTING				0x11
++#define AK4951_12_BEEP_CONTROL		0x12
++#define AK4951_13_LCH_DIGITAL_VOLUME_CONTROL	0x13
++#define AK4951_14_RCH_DIGITAL_VOLUME_CONTROL	0x14
++#define AK4951_15_EQ_COMMON_GAIN_SELECT		0x15
++#define AK4951_16_EQ2_COMMON_GAIN_SELECT			0x16
++#define AK4951_17_EQ3_COMMON_GAIN_SELECT			0x17
++#define AK4951_18_EQ4_COMMON_GAIN_SELECT		0x18
++#define AK4951_19_EQ5_COMMON_GAIN_SELECT	0x19
++#define AK4951_1A_AUTO_HPF_CONTROL				0x1A
++#define AK4951_1B_DIGITAL_FILTER_SELECT1		0x1B
++#define AK4951_1C_DIGITAL_FILTER_SELECT2		0x1C
++#define AK4951_1D_DIGITAL_FILTER_MODE			0x1D
++#define AK4951_1E_HPF2_COEFFICIENT0		0x1E
++#define AK4951_1F_HPF2_COEFFICIENT1		0x1F
++#define AK4951_20_HPF2_COEFFICIENT2		0x20
++#define AK4951_21_HPF2_COEFFICIENT3		0x21
++#define AK4951_22_LPF_COEFFICIENT0		0x22
++#define AK4951_23_LPF_COEFFICIENT1		0x23
++#define AK4951_24_LPF_COEFFICIENT2		0x24
++#define AK4951_25_LPF_COEFFICIENT3		0x25
++#define AK4951_26_FIL3_COEFFICIENT0		0x26
++#define AK4951_27_FIL3_COEFFICIENT1		0x27
++#define AK4951_28_FIL3_COEFFICIENT2		0x28
++#define AK4951_29_FIL3_COEFFICIENT3		0x29
++#define AK4951_2A_EQ_COEFFICIENT0		0x2A
++#define AK4951_2B_EQ_COEFFICIENT1		0x2B
++#define AK4951_2C_EQ_COEFFICIENT2		0x2C
++#define AK4951_2D_EQ_COEFFICIENT3		0x2D
++#define AK4951_2E_EQ_COEFFICIENT4		0x2E
++#define AK4951_2F_EQ_COEFFICIENT5		0x2F
++
++#define AK4951_30_DIGITAL_FILTER_SELECT3		0x30
++#define AK4951_31_DEVICE_INFO			0x31
++#define AK4951_32_E1_COEFFICIENT0		0x32
++#define AK4951_33_E1_COEFFICIENT1		0x33
++#define AK4951_34_E1_COEFFICIENT2		0x34
++#define AK4951_35_E1_COEFFICIENT3		0x35
++#define AK4951_36_E1_COEFFICIENT4		0x36
++#define AK4951_37_E1_COEFFICIENT5		0x37
++#define AK4951_38_E2_COEFFICIENT0		0x38
++#define AK4951_39_E2_COEFFICIENT1		0x39
++#define AK4951_3A_E2_COEFFICIENT2		0x3A
++#define AK4951_3B_E2_COEFFICIENT3		0x3B
++#define AK4951_3C_E2_COEFFICIENT4		0x3C
++#define AK4951_3D_E2_COEFFICIENT5		0x3D
++#define AK4951_3E_E3_COEFFICIENT0		0x3E
++#define AK4951_3F_E3_COEFFICIENT1		0x3F
++#define AK4951_40_E3_COEFFICIENT2		0x40
++#define AK4951_41_E3_COEFFICIENT3		0x41
++#define AK4951_42_E3_COEFFICIENT4		0x42
++#define AK4951_43_E3_COEFFICIENT5		0x43
++#define AK4951_44_E4_COEFFICIENT0		0x44
++#define AK4951_45_E4_COEFFICIENT1		0x45
++#define AK4951_46_E4_COEFFICIENT2		0x46
++#define AK4951_47_E4_COEFFICIENT3		0x47
++#define AK4951_48_E4_COEFFICIENT4		0x48
++#define AK4951_49_E4_COEFFICIENT5		0x49
++#define AK4951_4A_E5_COEFFICIENT0		0x4A
++#define AK4951_4B_E5_COEFFICIENT1		0x4B
++#define AK4951_4C_E5_COEFFICIENT2		0x4C
++#define AK4951_4D_E5_COEFFICIENT3		0x4D
++#define AK4951_4E_E5_COEFFICIENT4		0x4E
++#define AK4951_4F_E5_COEFFICIENT5		0x4F
++
++#define AK4951_MAX_REGISTERS	(AK4951_4F_E5_COEFFICIENT5 + 1)
++
++/* Bitfield Definitions */
++
++/* AK4954_00_POWER_MANAGEMENT1 (0x00) Fields */
++#define AK4951_PMVCM				0x40
++#define AK4951_PMPFIL				0x80
++
++/* AK4954_01_POWER_MANAGEMENT2 (0x01) Fields */
++#define AK4951_PMPLL				0x04
++#define AK4951_M_S					0x08
++
++/* AK4951_05_MODE_CONTROL1 (0x05) Fields */
++#define AK4951_DIF					0x03
++#define AK4951_DIF_24MSB_24LSB_MODE	(0 << 0)
++#define AK4951_DIF_24MSB_16LSB_MODE	(1 << 0)
++#define AK4951_DIF_24MSB_MODE		(2 << 0)
++#define AK4951_DIF_I2S_MODE			(3 << 0)
++#define AK4951_CKOFF				0x04
++#define AK4951_BCKO					0x08
++
++#define AK4951_PLL					0xF0
++#define AK4951_EXT_SLAVE			0
++#define AK4951_PLL_BICK32			(2 << 4)
++#define AK4951_PLL_BICK64			(3 << 4)
++#define AK4951_PLL_11_2896MHZ		(4 << 4)
++#define AK4951_PLL_12_288MHZ		(5 << 4)
++#define AK4951_PLL_12MHZ			(6 << 4)
++#define AK4951_PLL_24MHZ			(7 << 4)
++#define AK4951_PLL_13_5MHZ			(12 << 4)
++#define AK4951_PLL_27MHZ			(13 << 4)
++
++#define AK4951_MCLK_IN	0
++#define AK4951_BCLK_IN		1
++#define AK4951_MCLK_IN_BCLK_OUT 2
++
++/* AK4954_06_MODE_CONTROL2 (0x06) Fields */
++#define AK4951_FS				0x0F
++#define AK4951_MCKI_FS_8KHZ			(0 << 0)
++#define AK4951_MCKI_FS_12KHZ			(1 << 0)
++#define AK4951_MCKI_FS_16KHZ			(2 << 0)
++#define AK4951_MCKI_FS_11_025KHZ		(5 << 0)
++#define AK4951_MCKI_FS_22_05KHZ			(7 << 0)
++#define AK4951_MCKI_FS_24KHZ			(9 << 0)
++#define AK4951_MCKI_FS_32KHZ			(10 << 0)
++#define AK4951_MCKI_FS_44_1KHZ			(15 << 0)
++#define AK4951_MCKI_FS_48KHZ			(11 << 0)
++
++#define AK4951_BICK_FS_8KHZ			(0 << 0)
++#define AK4951_BICK_FS_12KHZ			(1 << 0)
++#define AK4951_BICK_FS_16KHZ			(5 << 0)
++#define AK4951_BICK_FS_11_025KHZ		(2 << 0)
++#define AK4951_BICK_FS_22_05KHZ			(7 << 0)
++#define AK4951_BICK_FS_24KHZ			(6 << 0)
++#define AK4951_BICK_FS_32KHZ			(10 << 0)
++#define AK4951_BICK_FS_44_1KHZ			(8 << 0)
++#define AK4951_BICK_FS_48KHZ			(11 << 0)
++
++#define AK4951_FS_CM0			(1 << 6)
++#define AK4951_FS_CM1			(1 << 7)
++
++#endif
+diff --git a/sound/soc/codecs/ak4954_amb.c b/sound/soc/codecs/ak4954_amb.c
+new file mode 100644
+index 00000000..02ae6e7f
+--- /dev/null
++++ b/sound/soc/codecs/ak4954_amb.c
+@@ -0,0 +1,1513 @@
++/*
++ * ak4954_amb.c  --  audio driver for AK4954
++ *
++ * Copyright 2014 Ambarella Ltd.
++ *
++ * Author: Diao Chengdong <cddiao@ambarella.com>
++ *
++ * History:
++ *	2014/03/27 - created
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/of_gpio.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++
++#include "ak4954_amb.h"
++
++//#define PLL_32BICK_MODE
++//#define PLL_64BICK_MODE
++
++//#define AK4954_DEBUG			//used at debug mode
++//#define AK4954_CONTIF_DEBUG		//used at debug mode
++
++#ifdef AK4954_DEBUG
++#define akdbgprt printk
++#else
++#define akdbgprt(format, arg...) do {} while (0)
++#endif
++
++#define LINEIN1_MIC_BIAS_CONNECT
++#define LINEIN2_MIC_BIAS_CONNECT
++
++/* AK4954 Codec Private Data */
++struct ak4954_priv {
++	unsigned int rst_pin;
++	unsigned int rst_active;
++	unsigned int sysclk;
++	unsigned int clkid;
++	struct snd_soc_codec codec;
++	u8 reg_cache[AK4954_MAX_REGISTERS];
++	int onDrc;
++	int onStereo;
++	int mic;
++};
++
++static struct snd_soc_codec *ak4954_codec;
++static struct ak4954_priv *ak4954_data;
++
++
++/* ak4954 register cache & default register settings */
++static const u8 ak4954_reg[AK4954_MAX_REGISTERS] = {
++	0x00,	/*	0x00	AK4954_00_POWER_MANAGEMENT1	*/
++	0x30,	/*	0x01	AK4954_01_POWER_MANAGEMENT2	*/
++	0x0a,	/*	0x02	AK4954_02_SIGNAL_SELECT1	*/
++	0x00,	/*	0x03	AK4954_03_SIGNAL_SELECT2	*/
++	0x34,	/*	0x04	AK4954_04_SIGNAL_SELECT3	*/
++	0x02,	/*	0x05	AK4954_05_MODE_CONTROL1	*/
++	0x09,	/*	0x06	AK4954_06_MODE_CONTROL2	*/
++	0x14,	/*	0x07	AK4954_07_MODE_CONTROL3		*/
++	0x00,	/*	0x08	AK4954_08_DIGITL_MIC	*/
++	0x3A,	/*	0x09	AK4954_09_TIMER_SELECT	*/
++	0x48,	/*	0x0A	AK4954_0A_ALC_TIMER_SELECT	*/
++	0x01,	/*	0x0B	AK4954_0B_ALC_MODE_CONTROL1	*/
++	0xE1,	/*	0x0C	AK4954_0C_ALC_MODE_CONTROL2	*/
++	0x91,	/*	0x0D	AK4954_0D_LCH_INPUT_VOLUME_CONTROL	*/
++	0x91,	/*	0x0E	AK4954_0E_RCH_INPUT_VOLUME_CONTROL	*/
++	0x00,	/*	0x0F	AK4954_0F_RESERVEDL	*/
++	0x00,	/*	0x10	AK4954_10_RESERVED	*/
++	0x00,	/*	0x11	AK4954_11_RESERVED	*/
++	0x00,	/*	0x12	AK4954_12_HP_OUTPUT_CONTROL	*/
++	0x0C,	/*	0x13	AK4954_13_LCH_DIGITAL_VOLUME_CONTROL	*/
++	0x0C,	/*	0x14	AK4954_14_RCH_DIGITAL_VOLUME_CONTROL	*/
++	0x00,	/*	0x15	AK4954_15_BEEP_FREQUENCY	*/
++	0x00,	/*	0x16	AK4954_16_BEEP_ON_TIME	*/
++	0x00,	/*	0x17	AK4954_17_BEEP_OFF_TIME	*/
++	0x00,	/*	0x18	AK4954_18_BEEP_REPEAT_COUNT	*/
++	0x00,	/*	0x19	AK4954_19_BEEP_VOLUME_CONTROL	*/
++	0x00,	/*	0x1A	AK4954_1A_RESERVED	*/
++	0x01,	/*	0x1B	AK4954_1B_DIGITAL_FILTER_SELECT1	*/
++	0x00,	/*	0x1C	AK4954_1C_DIGITAL_FILTER_SELECT2	*/
++	0x03,	/*	0x1D	AK4954_1D_DIGITAL_FILTER_MODE	*/
++	0xA9,	/*	0x1E	AK4954_1E_HPF2_COEFFICIENT0	*/
++	0x1F,	/*	0x1F	AK4954_1F_HPF2_COEFFICIENT1	*/
++	0xAD,	/*	0x20	AK4954_20_HPF2_COEFFICIENT2	*/
++	0x20,	/*	0x21	AK4954_21_HPF2_COEFFICIENT3	*/
++	0x7F,	/*	0x22	AK4954_22_LPF_COEFFICIENT0	*/
++	0x0C,	/*	0x23	AK4954_23_LPF_COEFFICIENT1	*/
++	0xFF,	/*	0x24	AK4954_24_LPF_COEFFICIENT2	*/
++	0x38,	/*	0x25	AK4954_25_LPF_COEFFICIENT3	*/
++	0xA2,	/*	0x26	AK4954_26_FIL3_COEFFICIENT0	*/
++	0x83,	/*	0x27	AK4954_27_FIL3_COEFFICIENT1	*/
++	0x80,	/*	0x28	AK4954_28_FIL3_COEFFICIENT2	*/
++	0x2E,	/*	0x29	AK4954_29_FIL3_COEFFICIENT3	*/
++	0x5B,	/*	0x2A	AK4954_2A_EQ_COEFFICIENT0	*/
++	0x23,	/*	0x2B	AK4954_2B_EQ_COEFFICIENT1	*/
++	0x07,	/*	0x2C	AK4954_2C_EQ_COEFFICIENT2	*/
++	0x28,	/*	0x2D	AK4954_2D_EQ_COEFFICIENT3	*/
++	0xAA,	/*	0x2E	AK4954_2E_EQ_COEFFICIENT4	*/
++	0xEC,	/*	0x2F	AK4954_2F_EQ_COEFFICIENT5	*/
++	0x00,	/*	0x30	AK4954_30_DIGITAL_FILTER_SELECT3	*/
++	0x00,	/*	0x31	AK4954_31_RESERVED	*/
++	0x9F,	/*	0x32	AK4954_32_E1_COEFFICIENT0	*/
++	0x00,	/*	0x33	AK4954_33_E1_COEFFICIENT1	*/
++	0x2B,	/*	0x34	AK4954_34_E1_COEFFICIENT2	*/
++	0x3F,	/*	0x35	AK4954_35_E1_COEFFICIENT3	*/
++	0xD4,	/*	0x36	AK4954_36_E1_COEFFICIENT4	*/
++	0xE0,	/*	0x37	AK4954_37_E1_COEFFICIENT5	*/
++	0x6A,	/*	0x38	AK4954_38_E2_COEFFICIENT0	*/
++	0x00,	/*	0x39	AK4954_39_E2_COEFFICIENT1	*/
++	0x1B,	/*	0x3A	AK4954_3A_E2_COEFFICIENT2	*/
++	0x3F,	/*	0x3B	AK4954_3B_E2_COEFFICIENT3	*/
++	0xD4,	/*	0x3C	AK4954_3C_E2_COEFFICIENT4	*/
++	0xE0,	/*	0x3D	AK4954_3D_E2_COEFFICIENT5	*/
++	0x6A,	/*	0x3E	AK4954_3E_E3_COEFFICIENT0	*/
++	0x00,	/*	0x3F	AK4954_3F_E3_COEFFICIENT1	*/
++	0xA2,	/*	0x40	AK4954_40_E3_COEFFICIENT2	*/
++	0x3E,	/*	0x41	AK4954_41_E3_COEFFICIENT3	*/
++	0xD4,	/*	0x42	AK4954_42_E3_COEFFICIENT4	*/
++	0xE0,	/*	0x43	AK4954_43_E3_COEFFICIENT5	*/
++	0x6A,	/*	0x44	AK4954_44_E4_COEFFICIENT0	*/
++	0x00,	/*	0x45	AK4954_45_E4_COEFFICIENT1	*/
++	0xA8,	/*	0x46	AK4954_46_E4_COEFFICIENT2	*/
++	0x38,	/*	0x47	AK4954_47_E4_COEFFICIENT3	*/
++	0xD4,	/*	0x48	AK4954_48_E4_COEFFICIENT4	*/
++	0xE0,	/*	0x49	AK4954_49_E4_COEFFICIENT5	*/
++	0x6A,	/*	0x4A	AK4954_4A_E5_COEFFICIENT0	*/
++	0x00,	/*	0x4B	AK4954_4B_E5_COEFFICIENT1	*/
++	0x96,	/*	0x4C	AK4954_4C_E5_COEFFICIENT2	*/
++	0x1F,	/*	0x4D	AK4954_4D_E5_COEFFICIENT3	*/
++	0xD4,	/*	0x4E	AK4954_4E_E5_COEFFICIENT4	*/
++	0xE0,	/*	0x4F	AK4954_4F_E5_COEFFICIENT5	*/
++	0x00,	/*	0x50	AK4954_50_DRC_MODE_CONTROL	*/
++	0x00,	/*	0x51	AK4954_51_NS_CONTROL		*/
++	0x11,	/*	0x52	AK4954_52_NS_GAIN_ATT_CONTROL	*/
++	0x90,	/*	0x53	AK4954_53_NS_ON_LEVEL		*/
++	0x8A,	/*	0x54	AK4954_54_NS_OFF_LEVEL		*/
++	0x07,	/*	0x55	AK4954_55_NS_REFERENCE_SELECT	*/
++	0x40,	/*	0x56	AK4954_56_NS_LPF_COEFFICIENT0	*/
++	0x07,	/*	0x57	AK4954_57_NS_LPF_COEFFICIENT1	*/
++	0x80,	/*	0x58	AK4954_58_NS_LPF_COEFFICIENT2	*/
++	0x2E,	/*	0x59	AK4954_59_NS_LPF_COEFFICIENT3	*/
++	0xA9,	/*	0x5A	AK4954_5A_NS_HPF_COEFFICIENT0	*/
++	0x1F,	/*	0x5B	AK4954_5B_NS_HPF_COEFFICIENT1	*/
++	0xAD,	/*	0x5C	AK4954_5C_NS_HPF_COEFFICIENT2	*/
++	0x20,	/*	0x5D	AK4954_5D_NS_HPF_COEFFICIENT3	*/
++	0x00,	/*	0x5E	AK4954_5E_RESERVED				*/
++	0x00,	/*	0x5F	AK4954_5F_RESERVED				*/
++	0x00,	/*	0x60	AK4954_60_DVLC_FILTER_SELECT	*/
++	0x6F,	/*	0x61	AK4954_61_DVLC_MODE_CONTROL		*/
++	0x18,	/*	0x62	AK4954_62_DVLCL_CURVE_X1		*/
++	0x0C,	/*	0x63	AK4954_63_DVLCL_CURVE_Y1		*/
++	0x10,	/*	0x64	AK4954_64_DVLCL_CURVE_X2		*/
++	0x09,	/*	0x65	AK4954_65_DVLCL_CURVE_Y2		*/
++	0x08,	/*	0x66	AK4954_66_DVLCL_CURVE_X3		*/
++	0x08,	/*	0x67	AK4954_67_DVLCL_CURVE_Y3		*/
++	0x7F,	/*	0x68	AK4954_68_DVLCL_SLOPE1			*/
++	0x1D,	/*	0x69	AK4954_69_DVLCL_SLOPE2			*/
++	0x03,	/*	0x6A	AK4954_6A_DVLCL_SLOPE3			*/
++	0x00,	/*	0x6B	AK4954_6B_DVLCL_SLOPE4			*/
++	0x18,	/*	0x6C	AK4954_6C_DVLCM_CURVE_X1		*/
++	0x0C,	/*	0x6D	AK4954_6D_DVLCM_CURVE_Y1		*/
++	0x10,	/*	0x6E	AK4954_6E_DVLCM_CURVE_X2		*/
++	0x06,	/*	0x6F	AK4954_6F_DVLCM_CURVE_Y2		*/
++	0x08,	/*	0x70	AK4954_70_DVLCM_CURVE_X3		*/
++	0x04,	/*	0x71	AK4954_71_DVLCM_CURVE_Y3		*/
++	0x7F,	/*	ox72	AK4954_72_DVLCM_SLOPE1			*/
++	0x4E,	/*	0x73	AK4954_73_DVLCM_SLOPE2			*/
++	0x0C,	/*	0x74	AK4954_74_DVLCM_SLOPE3			*/
++	0x00,	/*	0x75	AK4954_75_DVLCM_SLOPE4			*/
++	0x1C,	/*	0x76	AK4954_76_DVLCH_CURVE_X1		*/
++	0x10,	/*	0x77	AK4954_77_DVLCH_CURVE_Y1		*/
++	0x10,	/*	0x78	AK4954_78_DVLCH_CURVE_X2		*/
++	0x0C,	/*	0x79	AK4954_79_DVLCH_CURVE_Y2		*/
++	0x08,	/*	0x7A	AK4954_7A_DVLCH_CURVE_X3		*/
++	0x09,	/*	0x7B	AK4954_7B_DVLCH_CURVE_Y3		*/
++	0x7F,	/*	0x7C	AK4954_7C_DVLCH_SLOPE1			*/
++	0x12,	/*	0x7D	AK4954_7D_DVLCH_SLOPE2			*/
++	0x07,	/*	0x7E	AK4954_7E_DVLCH_SLOPE3			*/
++	0x01,	/*	0x7F	AK4954_7F_DVLCH_SLOPE4			*/
++	0x50,	/*	0x80	AK4954_80_DVLCL_LPF_COEFFICIENT0	*/
++	0x01,	/*	0x81	AK4954_81_DVLCL_LPF_COEFFICIENT1	*/
++	0xA0,	/*	0x82	AK4954_82_DVLCL_LPF_COEFFICIENT2	*/
++	0x22,	/*	0x83	AK4954_83_DVLCL_LPF_COEFFICIENT3	*/
++	0xA9,	/*	0x84	AK4954_84_DVLCM_HPF_COEFFICIENT0	*/
++	0x1F,	/*	0x85	AK4954_85_DVLCM_HPF_COEFFICIENT1	*/
++	0xAD,	/*	0x86	AK4954_86_DVLCM_HPF_COEFFICIENT2	*/
++	0x20,	/*	0x87	AK4954_87_DVLCM_HPF_COEFFICIENT3	*/
++	0x04,	/*	0x88	AK4954_88_DVLCM_LPF_COEFFICIENT0	*/
++	0x0A,	/*	0x89	AK4954_89_DVLCM_LPF_COEFFICIENT1	*/
++	0x07,	/*	0x8A	AK4954_8A_DVLCM_LPF_COEFFICIENT2	*/
++	0x34,	/*	0x8B	AK4954_8B_DVLCM_LPF_COEFFICIENT3	*/
++	0xE6,	/*	0x8C	AK4954_8C_DVLCH_HPF_COEFFICIENT0	*/
++	0x1C,	/*	0x8D	AK4954_8D_DVLCH_HPF_COEFFICIENT1	*/
++	0x33,	/*	0x8E	AK4954_8E_DVLCH_HPF_COEFFICIENT2	*/
++	0x26,	/*	0x8F	AK4954_8F_DVLCH_HPF_COEFFICIENT3	*/
++};
++
++
++static const struct {
++	int readable;   /* Mask of readable bits */
++	int writable;   /* Mask of writable bits */
++} ak4954_access_masks[] = {
++    { 0xEF, 0xEF },	//0x00
++    { 0x3F, 0x3F },	//0x01
++    { 0xBF, 0xBF },	//0x02
++    { 0xCF, 0xCF },	//0x03
++    { 0x3F, 0x3F },	//0x04
++    { 0x7F, 0x7F },	//0x05
++    { 0xCF, 0xCF },	//0x06
++    { 0xF7, 0xB7 },	//0x07
++    { 0x7B, 0x7B },	//0x08
++    { 0xFF, 0xFF },	//0x09
++    { 0xCF, 0xCF },	//0x0A
++    { 0xBF, 0xBF },	//0x0B
++    { 0xFF, 0xFF },	//0x0C
++    { 0xFF, 0xFF },	//0x0D
++    { 0xFF, 0xFF },	//0x0E
++    { 0x00, 0x00 },	//0x0F
++    { 0x00, 0x00 },	//0x10
++    { 0x00, 0x00 },	//0x11
++    { 0x80, 0x80 },	//0x12
++    { 0xFF, 0xFF },	//0x13
++    { 0xFF, 0xFF },	//0x14
++    { 0x83, 0x83 },	//0x15
++    { 0xFF, 0xFF },	//0x16
++    { 0xFF, 0xFF },	//0x17
++    { 0x7F, 0x7F },	//0x18
++    { 0x9F, 0x9F },	//0x19
++    { 0x00, 0x00 },	//0x1A
++    { 0x0F, 0x0F },	//0x1B
++    { 0xF3, 0xF3 },	//0x1C
++    { 0x87, 0x87 },	//0x1D
++    { 0xFF, 0xFF },	//0x1E
++    { 0xFF, 0xFF },	//0x1F
++    { 0xFF, 0xFF },	//0x20
++    { 0xFF, 0xFF },	//0x21
++    { 0xFF, 0xFF },	//0x22
++    { 0xFF, 0xFF },	//0x23
++    { 0xFF, 0xFF },	//0x24
++    { 0xFF, 0xFF },	//0x25
++    { 0xFF, 0xFF },	//0x26
++    { 0xFF, 0xFF },	//0x27
++    { 0xFF, 0xFF },	//0x28
++    { 0xFF, 0xFF },	//0x29
++    { 0xFF, 0xFF },	//0x2A
++    { 0xFF, 0xFF },	//0x2B
++    { 0xFF, 0xFF },	//0x2C
++    { 0xFF, 0xFF },	//0x2D
++    { 0xFF, 0xFF },	//0x2E
++    { 0xFF, 0xFF },	//0x2F
++    { 0x1F, 0x1F },	//0x30
++    { 0x00, 0x00 },	//0x31
++    { 0xFF, 0xFF },	//0x32
++    { 0xFF, 0xFF },	//0x33
++    { 0xFF, 0xFF },	//0x34
++    { 0xFF, 0xFF },	//0x35
++    { 0xFF, 0xFF },	//0x36
++    { 0xFF, 0xFF },	//0x37
++    { 0xFF, 0xFF },	//0x38
++    { 0xFF, 0xFF },	//0x39
++    { 0xFF, 0xFF },	//0x3A
++    { 0xFF, 0xFF },	//0x3B
++    { 0xFF, 0xFF },	//0x3C
++    { 0xFF, 0xFF },	//0x3D
++    { 0xFF, 0xFF },	//0x3E
++    { 0xFF, 0xFF },	//0x3F
++    { 0xFF, 0xFF },	//0x40
++    { 0xFF, 0xFF },	//0x41
++    { 0xFF, 0xFF },	//0x42
++    { 0xFF, 0xFF },	//0x43
++    { 0xFF, 0xFF },	//0x44
++    { 0xFF, 0xFF },	//0x45
++    { 0xFF, 0xFF },	//0x46
++    { 0xFF, 0xFF },	//0x47
++    { 0xFF, 0xFF },	//0x48
++    { 0xFF, 0xFF },	//0x49
++    { 0xFF, 0xFF },	//0x4A
++    { 0xFF, 0xFF },	//0x4B
++    { 0xFF, 0xFF },	//0x4C
++    { 0xFF, 0xFF },	//0x4D
++    { 0xFF, 0xFF },	//0x4E
++    { 0xFF, 0xFF },	//0x4F
++    { 0x7F, 0x7F },	//0x50
++    { 0x37, 0x37 },	//0x51
++    { 0x77, 0x77 },	//0x52
++    { 0xDF, 0xDF },	//0x53
++    { 0xDF, 0xDF },	//0x54
++    { 0x0F, 0x0F },	//0x55
++    { 0xFF, 0xFF },	//0x56
++    { 0xFF, 0xFF },	//0x57
++    { 0xFF, 0xFF },	//0x58
++    { 0xFF, 0xFF },	//0x59
++    { 0xFF, 0xFF },	//0x5A
++    { 0xFF, 0xFF },	//0x5B
++    { 0xFF, 0xFF },	//0x5C
++    { 0xFF, 0xFF },	//0x5D
++    { 0x00, 0x00 },	//0x5E
++    { 0x00, 0x00 },	//0x5F
++    { 0xFF, 0xFF },	//0x60
++    { 0xFF, 0xFF },	//0x61
++    { 0x7F, 0x7F },	//0x62
++    { 0x7F, 0x7F },	//0x63
++    { 0x7F, 0x7F },	//0x64
++    { 0x7F, 0x7F },	//0x65
++    { 0x7F, 0x7F },	//0x66
++    { 0x7F, 0x7F },	//0x67
++    { 0x7F, 0x7F },	//0x68
++    { 0x7F, 0x7F },	//0x69
++    { 0x7F, 0x7F },	//0x6A
++    { 0x7F, 0x7F },	//0x6B
++    { 0x7F, 0x7F },	//0x6C
++    { 0x7F, 0x7F },	//0x6D
++    { 0x7F, 0x7F },	//0x6E
++    { 0x7F, 0x7F },	//0x6F
++    { 0x7F, 0x7F },	//0x70
++    { 0x7F, 0x7F },	//0x71
++    { 0x7F, 0x7F },	//0x72
++    { 0x7F, 0x7F },	//0x73
++    { 0x7F, 0x7F },	//0x74
++    { 0x7F, 0x7F },	//0x75
++    { 0x7F, 0x7F },	//0x76
++    { 0x7F, 0x7F },	//0x77
++    { 0x7F, 0x7F },	//0x78
++    { 0x7F, 0x7F },	//0x79
++    { 0x7F, 0x7F },	//0x7A
++    { 0x7F, 0x7F },	//0x7B
++    { 0x7F, 0x7F },	//0x7C
++    { 0x7F, 0x7F },	//0x7D
++    { 0x7F, 0x7F },	//0x7E
++    { 0x7F, 0x7F },	//0x7F
++    { 0xFF, 0xFF },	//0x80
++    { 0xFF, 0xFF },	//0x81
++    { 0xFF, 0xFF },	//0x82
++    { 0xFF, 0xFF },	//0x83
++    { 0xFF, 0xFF },	//0x84
++    { 0xFF, 0xFF },	//0x85
++    { 0xFF, 0xFF },	//0x86
++    { 0xFF, 0xFF },	//0x87
++    { 0xFF, 0xFF },	//0x88
++    { 0xFF, 0xFF },	//0x89
++    { 0xFF, 0xFF },	//0x8A
++    { 0xFF, 0xFF },	//0x8B
++    { 0xFF, 0xFF },	//0x8C
++    { 0xFF, 0xFF },	//0x8D
++    { 0xFF, 0xFF },	//0x8E
++    { 0xFF, 0xFF }	//0x8F
++
++};
++/*
++ *  MIC Gain control:
++ * from 6 to 26 dB in 6.5 dB steps
++ */
++static DECLARE_TLV_DB_SCALE(mgain_tlv, 600, 650, 0);
++
++/*
++ * Input Digital volume control:
++ * from -54.375 to 36 dB in 0.375 dB steps mute instead of -54.375 dB)
++ */
++static DECLARE_TLV_DB_SCALE(ivol_tlv, -5437, 37, 1);
++
++/*
++ * Speaker output volume control:
++ * from -33 to 12 dB in 3 dB steps (mute instead of -33 dB)
++ */
++static DECLARE_TLV_DB_SCALE(spkout_tlv, 426, 200, 0);
++
++/*
++ * Output Digital volume control: (DATT-A)
++ * (This can be used as Bluetooth I/F output volume)
++ * from -57.5 to 6 dB in 0.5 dB steps (mute instead of -57.5 dB)
++ */
++static DECLARE_TLV_DB_SCALE(dvol_tlv, -6600, 50, 1);
++
++
++static const char *drc_on_select[]  =
++{
++	"DRC OFF",
++	"DRC ON",
++};
++
++static const struct soc_enum ak4954_drc_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(drc_on_select), drc_on_select),
++};
++/*For our Board -- cddiao*/
++static const char *mic_and_lin_select[]  =
++{
++	"LIN",
++	"MIC",
++};
++
++
++static const struct soc_enum ak4954_micswitch_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mic_and_lin_select), mic_and_lin_select),
++};
++
++
++static int get_micstatus(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak4954->mic;
++
++    return 0;
++
++}
++
++static int set_micstatus(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++
++	ak4954->mic = ucontrol->value.enumerated.item[0];
++
++	if ( ak4954->mic ) {
++		snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
++	}else {
++		snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
++	}
++    return 0;
++}
++
++
++
++static const char *stereo_on_select[]  =
++{
++	"Stereo Enphasis Filter OFF",
++	"Stereo Enphasis Filter ON",
++};
++
++static const struct soc_enum ak4954_stereo_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(stereo_on_select), stereo_on_select),
++};
++
++static int ak4954_writeMask(struct snd_soc_codec *, u16, u16, u16);
++static inline u32 ak4954_read_reg_cache(struct snd_soc_codec *, u16);
++
++static int get_ondrc(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak4954->onDrc;
++
++    return 0;
++
++}
++
++static int set_ondrc(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++
++	ak4954->onDrc = ucontrol->value.enumerated.item[0];
++
++	if ( ak4954->onDrc ) {
++		ak4954_writeMask(codec, AK4954_50_DRC_MODE_CONTROL, 0x3, 0x3);
++		ak4954_writeMask(codec, AK4954_60_DVLC_FILTER_SELECT, 0, 0x55);
++	}
++	else {
++		ak4954_writeMask(codec, AK4954_50_DRC_MODE_CONTROL, 0x3, 0x0);
++		ak4954_writeMask(codec, AK4954_60_DVLC_FILTER_SELECT, 0, 0x0);
++	}
++
++    return 0;
++}
++
++static int get_onstereo(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak4954->onStereo;
++
++    return 0;
++
++}
++
++static int set_onstereo(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++
++	ak4954->onStereo = ucontrol->value.enumerated.item[0];
++
++	if ( ak4954->onStereo ) {
++		ak4954_writeMask(codec, AK4954_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x30);
++	}
++	else {
++		ak4954_writeMask(codec, AK4954_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x00);
++	}
++
++    return 0;
++}
++
++#ifdef AK4954_DEBUG
++
++static const char *test_reg_select[]   =
++{
++    "read AK4954 Reg 00:2F",
++    "read AK4954 Reg 30:5F",
++    "read AK4954 Reg 60:8F",
++};
++
++static const struct soc_enum ak4954_enum[] =
++{
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
++};
++
++static int nTestRegNo = 0;
++
++static int get_test_reg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = nTestRegNo;
++
++    return 0;
++
++}
++
++static int set_test_reg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    i, value;
++	int	   regs, rege;
++
++	nTestRegNo = currMode;
++
++	switch(nTestRegNo) {
++		case 1:
++			regs = 0x30;
++			rege = 0x5F;
++			break;
++		case 2:
++			regs = 0x60;
++			rege = 0x8F;
++			break;
++		default:
++			regs = 0x00;
++			rege = 0x2F;
++			break;
++	}
++
++	for ( i = regs ; i <= rege ; i++ ){
++		value = snd_soc_read(codec, i);
++		printk("***AK4954 Addr,Reg=(%x, %x)\n", i, value);
++	}
++
++	return(0);
++
++}
++
++#endif
++
++static const struct snd_kcontrol_new ak4954_snd_controls[] = {
++	SOC_SINGLE_TLV("Mic Gain Control",
++			AK4954_02_SIGNAL_SELECT1, 0, 0x07, 0, mgain_tlv),
++	SOC_SINGLE_TLV("Input Digital Volume",
++			AK4954_0D_LCH_INPUT_VOLUME_CONTROL, 0, 0xF1, 0, ivol_tlv),
++	SOC_SINGLE_TLV("Speaker Output Volume",
++			AK4954_03_SIGNAL_SELECT2, 6, 0x03, 0, spkout_tlv),
++	SOC_SINGLE_TLV("Digital Output Volume",
++			AK4954_13_LCH_DIGITAL_VOLUME_CONTROL, 0, 0x90, 1, dvol_tlv),
++
++    SOC_SINGLE("High Path Filter 1", AK4954_1B_DIGITAL_FILTER_SELECT1, 1, 3, 0),
++    SOC_SINGLE("High Path Filter 2", AK4954_1C_DIGITAL_FILTER_SELECT2, 0, 1, 0),
++    SOC_SINGLE("Low Path Filter", 	 AK4954_1C_DIGITAL_FILTER_SELECT2, 1, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 1", AK4954_30_DIGITAL_FILTER_SELECT3, 0, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 2", AK4954_30_DIGITAL_FILTER_SELECT3, 1, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 3", AK4954_30_DIGITAL_FILTER_SELECT3, 2, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 4", AK4954_30_DIGITAL_FILTER_SELECT3, 3, 1, 0),
++	SOC_SINGLE("5 Band Equalizer 5", AK4954_30_DIGITAL_FILTER_SELECT3, 4, 1, 0),
++	SOC_SINGLE("Auto Level Control 1", AK4954_0B_ALC_MODE_CONTROL1, 5, 1, 0),
++	SOC_SINGLE("Soft Mute Control", AK4954_07_MODE_CONTROL3, 5, 1, 0),
++	SOC_ENUM_EXT("DRC Control", ak4954_drc_enum[0], get_ondrc, set_ondrc),
++	SOC_ENUM_EXT("Stereo Enphasis Filter Control", ak4954_stereo_enum[0], get_onstereo, set_onstereo),
++	SOC_ENUM_EXT("Mic and Lin Switch",ak4954_micswitch_enum[0],get_micstatus,set_micstatus),
++#ifdef AK4954_DEBUG
++	SOC_ENUM_EXT("Reg Read", ak4954_enum[0], get_test_reg, set_test_reg),
++#endif
++
++
++};
++
++static const char *ak4954_lin_select_texts[] =
++		{"LIN1", "LIN2", "LIN3"};
++
++static const struct soc_enum ak4954_lin_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_03_SIGNAL_SELECT2, 2,
++			ARRAY_SIZE(ak4954_lin_select_texts), ak4954_lin_select_texts);
++
++static const struct snd_kcontrol_new ak4954_lin_mux_control =
++	SOC_DAPM_ENUM("LIN Select", ak4954_lin_mux_enum);
++
++static const char *ak4954_rin_select_texts[] =
++		{"RIN1", "RIN2", "RIN3"};
++
++static const struct soc_enum ak4954_rin_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_03_SIGNAL_SELECT2, 0,
++			ARRAY_SIZE(ak4954_rin_select_texts), ak4954_rin_select_texts);
++
++static const struct snd_kcontrol_new ak4954_rin_mux_control =
++	SOC_DAPM_ENUM("RIN Select", ak4954_rin_mux_enum);
++
++static const char *ak4954_lin1_select_texts[] =
++		{"LIN1", "Mic Bias"};
++
++static const struct soc_enum ak4954_lin1_mux_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak4954_lin1_select_texts), ak4954_lin1_select_texts);
++
++static const struct snd_kcontrol_new ak4954_lin1_mux_control =
++	SOC_DAPM_ENUM_VIRT("LIN1 Switch", ak4954_lin1_mux_enum);
++
++
++static const char *ak4954_micbias_select_texts[] =
++		{"LIN1", "LIN2"};
++
++static const struct soc_enum ak4954_micbias_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_02_SIGNAL_SELECT1, 4,
++			ARRAY_SIZE(ak4954_micbias_select_texts), ak4954_micbias_select_texts);
++
++static const struct snd_kcontrol_new ak4954_micbias_mux_control =
++	SOC_DAPM_ENUM("MIC bias Select", ak4954_micbias_mux_enum);
++
++static const char *ak4954_spklo_select_texts[] =
++		{"Speaker", "Line"};
++
++static const struct soc_enum ak4954_spklo_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_01_POWER_MANAGEMENT2, 0,
++			ARRAY_SIZE(ak4954_spklo_select_texts), ak4954_spklo_select_texts);
++
++static const struct snd_kcontrol_new ak4954_spklo_mux_control =
++	SOC_DAPM_ENUM("SPKLO Select", ak4954_spklo_mux_enum);
++
++static const char *ak4954_adcpf_select_texts[] =
++		{"SDTI", "ADC"};
++
++static const struct soc_enum ak4954_adcpf_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 1,
++			ARRAY_SIZE(ak4954_adcpf_select_texts), ak4954_adcpf_select_texts);
++
++static const struct snd_kcontrol_new ak4954_adcpf_mux_control =
++	SOC_DAPM_ENUM("ADCPF Select", ak4954_adcpf_mux_enum);
++
++
++static const char *ak4954_pfsdo_select_texts[] =
++		{"ADC", "PFIL"};
++
++static const struct soc_enum ak4954_pfsdo_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 0,
++			ARRAY_SIZE(ak4954_pfsdo_select_texts), ak4954_pfsdo_select_texts);
++
++static const struct snd_kcontrol_new ak4954_pfsdo_mux_control =
++	SOC_DAPM_ENUM("PFSDO Select", ak4954_pfsdo_mux_enum);
++
++static const char *ak4954_pfdac_select_texts[] =
++		{"SDTI", "PFIL"};
++
++static const struct soc_enum ak4954_pfdac_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 2,
++			ARRAY_SIZE(ak4954_pfdac_select_texts), ak4954_pfdac_select_texts);
++
++static const struct snd_kcontrol_new ak4954_pfdac_mux_control =
++	SOC_DAPM_ENUM("PFDAC Select", ak4954_pfdac_mux_enum);
++
++static const char *ak4954_dac_select_texts[] =
++		{"PFDAC", "DRC"};
++
++static const struct soc_enum ak4954_dac_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 7,
++			ARRAY_SIZE(ak4954_dac_select_texts), ak4954_dac_select_texts);
++
++static const struct snd_kcontrol_new ak4954_dac_mux_control =
++	SOC_DAPM_ENUM("DAC Select", ak4954_dac_mux_enum);
++
++static const char *ak4954_mic_select_texts[] =
++		{"AMIC", "DMIC"};
++
++static const struct soc_enum ak4954_mic_mux_enum =
++	SOC_ENUM_SINGLE(AK4954_08_DIGITL_MIC, 0,
++			ARRAY_SIZE(ak4954_mic_select_texts), ak4954_mic_select_texts);
++
++static const struct snd_kcontrol_new ak4954_mic_mux_control =
++	SOC_DAPM_ENUM("MIC Select", ak4954_mic_mux_enum);
++
++
++static const struct snd_kcontrol_new ak4954_dacsl_mixer_controls[] = {
++	SOC_DAPM_SINGLE("DACSL", AK4954_02_SIGNAL_SELECT1, 5, 1, 0),
++};
++
++static int ak4954_spklo_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event) //CONFIG_LINF
++{
++	struct snd_soc_codec *codec = w->codec;
++	u32 reg, nLOSEL;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	reg = ak4954_read_reg_cache(codec, AK4954_01_POWER_MANAGEMENT2);
++	nLOSEL = (0x1 & reg);
++
++	switch (event) {
++		case SND_SOC_DAPM_PRE_PMU:	/* before widget power up */
++			break;
++		case SND_SOC_DAPM_POST_PMU:	/* after widget power up */
++			if ( nLOSEL ) {
++				akdbgprt("\t[AK4954] %s wait=300msec\n",__FUNCTION__);
++				mdelay(300);
++			}
++			else {
++				akdbgprt("\t[AK4954] %s wait=1msec\n",__FUNCTION__);
++				mdelay(1);
++			}
++			snd_soc_update_bits(codec, AK4954_02_SIGNAL_SELECT1, 0x80,0x80);
++			break;
++		case SND_SOC_DAPM_PRE_PMD:	/* before widget power down */
++			snd_soc_update_bits(codec, AK4954_02_SIGNAL_SELECT1, 0x80,0x00);
++			mdelay(1);
++			break;
++		case SND_SOC_DAPM_POST_PMD:	/* after widget power down */
++			if ( nLOSEL ) {
++				akdbgprt("\t[AK4954] %s wait=300msec\n",__FUNCTION__);
++				mdelay(300);
++			}
++			break;
++	}
++
++	return 0;
++}
++
++static const struct snd_soc_dapm_widget ak4954_dapm_widgets[] = {
++
++// ADC, DAC
++	SND_SOC_DAPM_ADC("ADC Left", "NULL", AK4954_00_POWER_MANAGEMENT1, 0, 0),
++	SND_SOC_DAPM_ADC("ADC Right", "NULL", AK4954_00_POWER_MANAGEMENT1, 1, 0),
++	SND_SOC_DAPM_DAC("DAC", "NULL", AK4954_00_POWER_MANAGEMENT1, 2, 0),
++
++#ifdef PLL_32BICK_MODE
++	SND_SOC_DAPM_SUPPLY("PMPLL", AK4954_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
++#else
++#ifdef PLL_64BICK_MODE
++	SND_SOC_DAPM_SUPPLY("PMPLL", AK4954_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
++#endif
++#endif
++
++	SND_SOC_DAPM_ADC("PFIL", "NULL", AK4954_00_POWER_MANAGEMENT1, 7, 0),
++	SND_SOC_DAPM_DAC("DRC", "NULL", AK4954_1D_DIGITAL_FILTER_MODE, 7, 0),
++
++	SND_SOC_DAPM_ADC("DMICL", "NULL", AK4954_08_DIGITL_MIC, 4, 0),
++	SND_SOC_DAPM_ADC("DMICR", "NULL", AK4954_08_DIGITL_MIC, 5, 0),
++
++	SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_IN("SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
++
++// Analog Output
++	SND_SOC_DAPM_OUTPUT("HPL"),
++	SND_SOC_DAPM_OUTPUT("HPR"),
++	SND_SOC_DAPM_OUTPUT("SPKLO"),
++
++	SND_SOC_DAPM_PGA("HPL Amp", AK4954_01_POWER_MANAGEMENT2, 4, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HPR Amp", AK4954_01_POWER_MANAGEMENT2, 5, 0, NULL, 0),
++
++	SND_SOC_DAPM_PGA("SPK Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Line Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	SND_SOC_DAPM_MIXER_E("SPKLO Mixer", AK4954_01_POWER_MANAGEMENT2, 1, 0,
++			&ak4954_dacsl_mixer_controls[0], ARRAY_SIZE(ak4954_dacsl_mixer_controls),
++			ak4954_spklo_event, (SND_SOC_DAPM_POST_PMU |SND_SOC_DAPM_PRE_PMD
++                            |SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMD)),
++
++// Analog Input
++	SND_SOC_DAPM_INPUT("LIN1"),
++	SND_SOC_DAPM_INPUT("RIN1"),
++	SND_SOC_DAPM_INPUT("LIN2"),
++	SND_SOC_DAPM_INPUT("RIN2"),
++	SND_SOC_DAPM_INPUT("LIN3"),
++	SND_SOC_DAPM_INPUT("RIN3"),
++
++	SND_SOC_DAPM_MUX("LIN MUX", SND_SOC_NOPM, 0, 0,	&ak4954_lin_mux_control),
++	SND_SOC_DAPM_MUX("RIN MUX", SND_SOC_NOPM, 0, 0,	&ak4954_rin_mux_control),
++
++// MIC Bias
++	SND_SOC_DAPM_MICBIAS("Mic Bias", AK4954_02_SIGNAL_SELECT1, 3, 0),
++	SND_SOC_DAPM_VIRT_MUX("LIN1 MUX", SND_SOC_NOPM, 0, 0, &ak4954_lin1_mux_control),
++	SND_SOC_DAPM_MUX("Mic Bias MUX", SND_SOC_NOPM, 0, 0, &ak4954_micbias_mux_control),
++	SND_SOC_DAPM_MUX("SPKLO MUX", SND_SOC_NOPM, 0, 0, &ak4954_spklo_mux_control),
++
++
++// PFIL
++	SND_SOC_DAPM_MUX("PFIL MUX", SND_SOC_NOPM, 0, 0, &ak4954_adcpf_mux_control),
++	SND_SOC_DAPM_MUX("PFSDO MUX", SND_SOC_NOPM, 0, 0, &ak4954_pfsdo_mux_control),
++	SND_SOC_DAPM_MUX("PFDAC MUX", SND_SOC_NOPM, 0, 0, &ak4954_pfdac_mux_control),
++	SND_SOC_DAPM_MUX("DAC MUX", SND_SOC_NOPM, 0, 0, &ak4954_dac_mux_control),
++
++// Digital Mic
++	SND_SOC_DAPM_INPUT("DMICLIN"),
++	SND_SOC_DAPM_INPUT("DMICRIN"),
++
++	SND_SOC_DAPM_VIRT_MUX("MIC MUX", SND_SOC_NOPM, 0, 0, &ak4954_mic_mux_control),
++
++};
++
++
++static const struct snd_soc_dapm_route ak4954_intercon[] = {
++
++#ifdef PLL_32BICK_MODE
++	{"ADC Left", "NULL", "PMPLL"},
++	{"ADC Right", "NULL", "PMPLL"},
++	{"DAC", "NULL", "PMPLL"},
++#else
++#ifdef PLL_64BICK_MODE
++	{"ADC Left", "NULL", "PMPLL"},
++	{"ADC Right", "NULL", "PMPLL"},
++	{"DAC", "NULL", "PMPLL"},
++#endif
++#endif
++
++	{"Mic Bias MUX", "LIN1", "LIN1"},
++	{"Mic Bias MUX", "LIN2", "LIN2"},
++
++	{"Mic Bias", "NULL", "Mic Bias MUX"},
++
++	{"LIN1 MUX", "LIN1", "LIN1"},
++	{"LIN1 MUX", "Mic Bias", "Mic Bias"},
++
++	{"LIN MUX", "LIN1", "LIN1 MUX"},
++	{"LIN MUX", "LIN2", "Mic Bias"},
++	{"LIN MUX", "LIN3", "LIN3"},
++	{"RIN MUX", "RIN1", "RIN1"},
++	{"RIN MUX", "RIN2", "RIN2"},
++	{"RIN MUX", "RIN3", "RIN3"},
++	{"ADC Left", "NULL", "LIN MUX"},
++	{"ADC Right", "NULL", "RIN MUX"},
++
++	{"DMICL", "NULL", "DMICLIN"},
++	{"DMICR", "NULL", "DMICRIN"},
++
++	{"MIC MUX", "AMIC", "ADC Left"},
++	{"MIC MUX", "AMIC", "ADC Right"},
++	{"MIC MUX", "DMIC", "DMICL"},
++	{"MIC MUX", "DMIC", "DMICR"},
++
++	{"PFIL MUX", "SDTI", "SDTI"},
++	{"PFIL MUX", "ADC", "MIC MUX"},
++	{"PFIL", "NULL", "PFIL MUX"},
++
++	{"PFSDO MUX", "ADC", "MIC MUX"},
++	{"PFSDO MUX", "PFIL", "PFIL"},
++
++	{"SDTO", "NULL", "PFSDO MUX"},
++
++	{"PFDAC MUX", "SDTI", "SDTI"},
++	{"PFDAC MUX", "PFIL", "PFIL"},
++
++	{"DAC MUX", "PFDAC", "PFDAC MUX"},
++	{"DRC", "NULL", "PFDAC MUX"},
++	{"DAC MUX", "DRC", "DRC"},
++
++	{"DAC", "NULL", "DAC MUX"},
++
++	{"HPL Amp", "NULL", "DAC"},
++	{"HPR Amp", "NULL", "DAC"},
++	{"HPL", "NULL", "HPL Amp"},
++	{"HPR", "NULL", "HPR Amp"},
++
++	{"SPKLO Mixer", "DACSL", "DAC"},
++	{"SPK Amp", "NULL", "SPKLO Mixer"},
++	{"Line Amp", "NULL", "SPKLO Mixer"},
++	{"SPKLO MUX", "Speaker", "SPK Amp"},
++	{"SPKLO MUX", "Line", "Line Amp"},
++	{"SPKLO", "NULL", "SPKLO MUX"},
++
++};
++
++static int ak4954_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	int rate = params_rate(params);
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++	int oversample = 0;
++	u8 	fs = 0;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	oversample = ak4954->sysclk / rate;
++	switch (oversample) {
++	case 256:
++		fs &= (~AK4954_FS_CM1);
++		fs &= (~AK4954_FS_CM0);
++		break;
++	case 384:
++		fs &= (~AK4954_FS_CM1);
++		fs |= AK4954_FS_CM0;
++		break;
++	case 512:
++		fs |= AK4954_FS_CM1;
++		fs &= (~AK4954_FS_CM0);
++		break;
++	case 1024:
++		fs |= AK4954_FS_CM1;
++		fs |= AK4954_FS_CM0;
++		break;
++	default:
++		break;
++	}
++	switch (rate) {
++	case 8000:
++		fs |= AK4954_FS_8KHZ;
++		break;
++	case 11025:
++		fs |= AK4954_FS_11_025KHZ;
++		break;
++	case 12000:
++		fs |= AK4954_FS_12KHZ;
++		break;
++	case 16000:
++		fs |= AK4954_FS_16KHZ;
++		break;
++	case 22050:
++		fs |= AK4954_FS_22_05KHZ;
++		break;
++	case 24000:
++		fs |= AK4954_FS_24KHZ;
++		break;
++	case 32000:
++		fs |= AK4954_FS_32KHZ;
++		break;
++	case 44100:
++		fs |= AK4954_FS_44_1KHZ;
++		break;
++	case 48000:
++		fs |= AK4954_FS_48KHZ;
++		break;
++	case 64000:
++		fs |= AK4954_FS_64KHZ;
++		break;
++	case 88000:
++		fs |= AK4954_FS_88_2KHZ;
++		break;
++	case 96000:
++		fs |= AK4954_FS_96KHZ;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	snd_soc_write(codec, AK4954_06_MODE_CONTROL2, fs);
++
++	return 0;
++}
++
++static int ak4954_set_pll(u8 *pll, int clk_id,int freq)
++{
++	if (clk_id == AK4954_MCLK_IN_BCLK_OUT){
++		switch (freq) {
++		case 11289600:
++			*pll |= (2 << 4);
++			break;
++		case 12288000:
++			*pll |= (3 << 4);
++			break;
++		case 12000000:
++			*pll |= (4 << 4);
++			break;
++		case 24000000:
++			*pll |= (5 << 4);
++			break;
++		case 13500000:
++			*pll |= (6 << 4);
++			break;
++		case 27000000:
++			*pll |= (7 << 4);
++			break;
++		default:
++			break;
++		}
++	}else if  (clk_id == AK4954_BCLK_IN) {
++		*pll |= (0 << 4);
++	}
++	return 0;
++}
++
++static int ak4954_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
++		unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++	u8 pllpwr = 0, pll = 0;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	pll= snd_soc_read(codec, AK4954_05_MODE_CONTROL1);
++	pll &=(~0x70);
++	pllpwr = snd_soc_read(codec,AK4954_01_POWER_MANAGEMENT2);
++	pllpwr &=(~0x0c);
++
++	if (clk_id == AK4954_MCLK_IN) {
++		pllpwr &= (~AK4954_PMPLL);
++		pllpwr &= (~AK4954_M_S);
++	}else if (clk_id == AK4954_BCLK_IN) {
++		pllpwr |= AK4954_PMPLL;
++		pllpwr &= (~AK4954_M_S);
++		ak4954_set_pll(&pll, clk_id, freq);
++	}else if (clk_id == AK4954_MCLK_IN_BCLK_OUT) {
++		pllpwr |= AK4954_PMPLL;
++		pllpwr |= AK4954_M_S;
++		ak4954_set_pll(&pll, clk_id, freq);
++	}
++	snd_soc_write(codec, AK4954_05_MODE_CONTROL1, pll);
++	snd_soc_write(codec, AK4954_01_POWER_MANAGEMENT2, pllpwr);
++
++	ak4954->sysclk = freq;
++	ak4954->clkid = clk_id;
++	return 0;
++}
++
++static int ak4954_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++
++	struct snd_soc_codec *codec = dai->codec;
++	u8 mode;
++	u8 format;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	/* set master/slave audio interface */
++	mode = snd_soc_read(codec, AK4954_01_POWER_MANAGEMENT2);
++	format = snd_soc_read(codec, AK4954_05_MODE_CONTROL1);
++	format &= ~AK4954_DIF;
++
++    switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++        case SND_SOC_DAIFMT_CBS_CFS:
++			akdbgprt("\t[AK4954] %s(Slave)\n",__FUNCTION__);
++            mode &= ~(AK4954_M_S);
++            //format &= ~(AK4954_BCKO);
++            break;
++        case SND_SOC_DAIFMT_CBM_CFM:
++			akdbgprt("\t[AK4954] %s(Master)\n",__FUNCTION__);
++            mode |= (AK4954_M_S);
++            //format |= (AK4954_BCKO);
++            break;
++        case SND_SOC_DAIFMT_CBS_CFM:
++        case SND_SOC_DAIFMT_CBM_CFS:
++        default:
++            dev_err(codec->dev, "Clock mode unsupported");
++           return -EINVAL;
++	}
++
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++		case SND_SOC_DAIFMT_I2S:
++			format |= AK4954_DIF_24_16_I2S_MODE;
++			break;
++		case SND_SOC_DAIFMT_LEFT_J:
++			format |= AK4954_DIF_24MSB_MODE;
++			break;
++		default:
++			return -EINVAL;
++	}
++
++	/* set mode and format */
++
++	snd_soc_write(codec, AK4954_01_POWER_MANAGEMENT2, mode);
++	snd_soc_write(codec, AK4954_05_MODE_CONTROL1, format);
++
++	return 0;
++}
++
++static int ak4954_volatile(struct snd_soc_codec *codec, unsigned int reg)
++{
++	int	ret;
++
++	switch (reg) {
++//		case :
++//			ret = 1;
++		default:
++			ret = 0;
++			break;
++	}
++	return(ret);
++}
++
++static int ak4954_readable(struct snd_soc_codec *codec, unsigned int reg)
++{
++
++	if (reg >= ARRAY_SIZE(ak4954_access_masks))
++		return 0;
++	return ak4954_access_masks[reg].readable != 0;
++}
++
++/*
++ * Read ak4954 register cache
++ */
++static inline u32 ak4954_read_reg_cache(struct snd_soc_codec *codec, u16 reg)
++{
++    u8 *cache = codec->reg_cache;
++    BUG_ON(reg > ARRAY_SIZE(ak4954_reg));
++    return (u32)cache[reg];
++}
++
++#ifdef AK4954_CONTIF_DEBUG
++/*
++ * Write ak4954 register cache
++ */
++static inline void ak4954_write_reg_cache(
++struct snd_soc_codec *codec,
++u16 reg,
++u16 value)
++{
++    u8 *cache = codec->reg_cache;
++    BUG_ON(reg > ARRAY_SIZE(ak4954_reg));
++    cache[reg] = (u8)value;
++}
++
++unsigned int ak4954_i2c_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++
++	int ret;
++
++	if ( reg == AK4954_10_RESERVED ) { // Dummy Register
++		ret = ak4954_read_reg_cache(codec, reg);
++		return ret;
++	}
++
++	ret = i2c_smbus_read_byte_data(codec->control_data, (u8)(reg & 0xFF));
++//	ret = ak4954_read_reg_cache(codec, reg);
++
++//	if ( reg < 3 )
++//		akdbgprt("\t[ak4954] %s: (addr,data)=(%x, %x)\n",__FUNCTION__, reg, ret);
++
++	if (ret < 0)
++		akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	return ret;
++
++}
++
++static int ak4954_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int value)
++{
++	ak4954_write_reg_cache(codec, reg, value);
++
++	akdbgprt("\t[ak4954] %s: (addr,data)=(%x, %x)\n",__FUNCTION__, reg, value);
++
++	if ( reg == AK4954_10_RESERVED ) return 0;  // Dummy Register
++	if(i2c_smbus_write_byte_data(codec->control_data, (u8)(reg & 0xFF), (u8)(value & 0xFF))<0) {
++		akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++		return EIO;
++	}
++
++	return 0;
++}
++#endif
++
++/*
++ * Write with Mask to  AK4954 register space
++ */
++static int ak4954_writeMask(
++struct snd_soc_codec *codec,
++u16 reg,
++u16 mask,
++u16 value)
++{
++    u16 olddata;
++    u16 newdata;
++
++	if ( (mask == 0) || (mask == 0xFF) ) {
++		newdata = value;
++	}
++	else {
++		olddata = ak4954_read_reg_cache(codec, reg);
++	    newdata = (olddata & ~(mask)) | value;
++	}
++
++	snd_soc_write(codec, (unsigned int)reg, (unsigned int)newdata);
++
++	akdbgprt("\t[ak4954_writeMask] %s(%d): (addr,data)=(%x, %x)\n",__FUNCTION__,__LINE__, reg, newdata);
++
++    return(0);
++}
++
++// * for AK4954
++static int ak4954_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *codec_dai)
++{
++	int 	ret = 0;
++ //   struct snd_soc_codec *codec = codec_dai->codec;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	return ret;
++}
++
++
++static int ak4954_set_bias_level(struct snd_soc_codec *codec,
++		enum snd_soc_bias_level level)
++{
++	u8 reg;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++	case SND_SOC_BIAS_PREPARE:
++	case SND_SOC_BIAS_STANDBY:
++		reg = snd_soc_read(codec, AK4954_00_POWER_MANAGEMENT1);	// * for AK4954
++		snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1,			// * for AK4954
++				reg | AK4954_PMVCM);
++		break;
++	case SND_SOC_BIAS_OFF:
++		snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, 0x00);	// * for AK4954
++		break;
++	}
++	codec->dapm.bias_level = level;
++	return 0;
++}
++
++#define AK4954_RATES		(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++				SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
++				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
++				SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
++			    SNDRV_PCM_RATE_96000)
++
++#define AK4954_FORMATS		SNDRV_PCM_FMTBIT_S16_LE
++
++
++static struct snd_soc_dai_ops ak4954_dai_ops = {
++	.hw_params	= ak4954_hw_params,
++	.set_sysclk	= ak4954_set_dai_sysclk,
++	.set_fmt	= ak4954_set_dai_fmt,
++	.trigger = ak4954_trigger,
++};
++
++struct snd_soc_dai_driver ak4954_dai[] = {
++	{
++		.name = "ak4954-hifi",
++		.playback = {
++		       .stream_name = "Playback",
++		       .channels_min = 1,
++		       .channels_max = 2,
++		       .rates = AK4954_RATES,
++		       .formats = AK4954_FORMATS,
++		},
++		.capture = {
++		       .stream_name = "Capture",
++		       .channels_min = 1,
++		       .channels_max = 2,
++		       .rates = AK4954_RATES,
++		       .formats = AK4954_FORMATS,
++		},
++		.ops = &ak4954_dai_ops,
++	},
++};
++
++static int ak4954_write_cache_reg(
++struct snd_soc_codec *codec,
++u16  regs,
++u16  rege)
++{
++	u32	reg, cache_data;
++
++	reg = regs;
++	do {
++		cache_data = ak4954_read_reg_cache(codec, reg);
++		snd_soc_write(codec, (unsigned int)reg, (unsigned int)cache_data);
++		reg ++;
++	} while (reg <= rege);
++
++	return(0);
++}
++
++
++static int ak4954_set_reg_digital_effect(struct snd_soc_codec *codec)
++{
++
++	ak4954_write_cache_reg(codec, AK4954_0A_ALC_TIMER_SELECT, AK4954_0D_LCH_INPUT_VOLUME_CONTROL);
++	ak4954_write_cache_reg(codec, AK4954_22_LPF_COEFFICIENT0, AK4954_2F_EQ_COEFFICIENT5);
++	ak4954_write_cache_reg(codec, AK4954_32_E1_COEFFICIENT0, AK4954_4F_E5_COEFFICIENT5);
++	ak4954_write_cache_reg(codec, AK4954_50_DRC_MODE_CONTROL, AK4954_8F_DVLCH_HPF_COEFFICIENT3);
++	return(0);
++}
++
++static int ak4954_probe(struct snd_soc_codec *codec)
++{
++	struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
++	int ret = 0;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++#ifdef AK4954_CONTIF_DEBUG
++	codec->write = ak4954_i2c_write;
++	codec->read = ak4954_i2c_read;
++#endif
++	ak4954_codec = codec;
++
++	akdbgprt("\t[AK4954] %s(%d) ak4954=%x\n",__FUNCTION__,__LINE__, (int)ak4954);
++
++	snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, 0x00);
++	snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, 0x00);
++
++	ak4954_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	akdbgprt("\t[AK4954 bias] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak4954_set_reg_digital_effect(codec);
++
++	akdbgprt("\t[AK4954 Effect] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	snd_soc_add_codec_controls(codec, ak4954_snd_controls,
++	                    ARRAY_SIZE(ak4954_snd_controls));
++	ak4954->onDrc = 0;
++	ak4954->onStereo = 0;
++	ak4954->mic = 1;
++	/*Enable Line out */
++	snd_soc_update_bits(codec,AK4954_01_POWER_MANAGEMENT2,0x02,0x02);
++	snd_soc_update_bits(codec,AK4954_02_SIGNAL_SELECT1, 0xa0,0xa0);
++
++	/*Enable LIN2*/
++	snd_soc_update_bits(codec,AK4954_02_SIGNAL_SELECT1,0x18,0x08);//MPWR1
++	snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
++	snd_soc_update_bits(codec,AK4954_08_DIGITL_MIC,0x01,0x00);//AMIC
++	snd_soc_update_bits(codec,AK4954_1D_DIGITAL_FILTER_MODE,0x02,0x02);//ADC output
++	snd_soc_update_bits(codec,AK4954_1D_DIGITAL_FILTER_MODE,0x01,0x01);//ALC output
++	snd_soc_update_bits(codec,AK4954_02_SIGNAL_SELECT1,0x07,0x3);//Mic Gain
++	snd_soc_update_bits(codec,AK4954_0D_LCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
++	snd_soc_update_bits(codec,AK4954_0E_RCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
++
++	/*Enable LIN3*/
++	//snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
++
++    return ret;
++
++}
++
++static int ak4954_remove(struct snd_soc_codec *codec)
++{
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak4954_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++
++	return 0;
++}
++
++static int ak4954_suspend(struct snd_soc_codec *codec)
++{
++	ak4954_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	return 0;
++}
++
++static int ak4954_resume(struct snd_soc_codec *codec)
++{
++
++	ak4954_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return 0;
++}
++
++
++struct snd_soc_codec_driver soc_codec_dev_ak4954 = {
++	.probe = ak4954_probe,
++	.remove = ak4954_remove,
++	.suspend =	ak4954_suspend,
++	.resume =	ak4954_resume,
++
++	.set_bias_level = ak4954_set_bias_level,
++	.reg_cache_size = ARRAY_SIZE(ak4954_reg),
++	.reg_word_size = sizeof(u8),
++	.reg_cache_default = ak4954_reg,
++	.readable_register = ak4954_readable,
++	.volatile_register = ak4954_volatile,
++	.dapm_widgets = ak4954_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(ak4954_dapm_widgets),
++	.dapm_routes = ak4954_intercon,
++	.num_dapm_routes = ARRAY_SIZE(ak4954_intercon),
++};
++EXPORT_SYMBOL_GPL(soc_codec_dev_ak4954);
++
++static int ak4954_i2c_probe(struct i2c_client *i2c,
++                            const struct i2c_device_id *id)
++{
++	struct device_node *np = i2c->dev.of_node;
++	struct ak4954_priv *ak4954;
++	enum of_gpio_flags flags;
++	int rst_pin;
++	struct snd_soc_codec *codec;
++	int ret=0;
++
++	akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak4954 = devm_kzalloc(&i2c->dev, sizeof(struct ak4954_priv), GFP_KERNEL);
++	if (ak4954 == NULL)
++		return -ENOMEM;
++
++	rst_pin = of_get_gpio_flags(np, 0, &flags);
++	if (rst_pin < 0 || !gpio_is_valid(rst_pin))
++		return -ENXIO;
++
++	ak4954->rst_pin = rst_pin;
++	ak4954->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	codec = &ak4954->codec;
++	i2c_set_clientdata(i2c, ak4954);
++	codec->control_data = i2c;
++	ak4954_data = ak4954;
++
++	codec->dev = &i2c->dev;
++	snd_soc_codec_set_drvdata(codec, ak4954);
++
++	ret = snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_ak4954, &ak4954_dai[0], ARRAY_SIZE(ak4954_dai));
++	if (ret < 0){
++		kfree(ak4954);
++		akdbgprt("\t[AK4954 Error!] %s(%d)\n",__FUNCTION__,__LINE__);
++	}
++	return ret;
++}
++
++static int ak4954_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	kfree(i2c_get_clientdata(client));
++	return 0;
++}
++
++static struct of_device_id ak4954_of_match[] = {
++	{ .compatible = "ambarella,ak4954",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, ak4954_of_match);
++
++static const struct i2c_device_id ak4954_i2c_id[] = {
++	{ "ak4954", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, ak4954_i2c_id);
++
++static struct i2c_driver ak4954_i2c_driver = {
++	.driver = {
++		.name = "ak4954-codec",
++		.owner = THIS_MODULE,
++		.of_match_table = ak4954_of_match,
++	},
++	.probe		=	ak4954_i2c_probe,
++	.remove		=	ak4954_i2c_remove,
++	.id_table	=	ak4954_i2c_id,
++};
++
++static int __init ak4954_modinit(void)
++{
++	int ret;
++	akdbgprt("\t[AK4954] %s(%d)\n", __FUNCTION__,__LINE__);
++
++	ret = i2c_add_driver(&ak4954_i2c_driver);
++	if (ret != 0)
++		pr_err("Failed to register ak4954 I2C driver: %d\n",ret);
++	return ret;
++}
++
++module_init(ak4954_modinit);
++
++static void __exit ak4954_exit(void)
++{
++	i2c_del_driver(&ak4954_i2c_driver);
++}
++module_exit(ak4954_exit);
++
++MODULE_DESCRIPTION("Soc AK4954 driver");
++MODULE_AUTHOR("Diao Chengdong<cddiao@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/ak4954_amb.h b/sound/soc/codecs/ak4954_amb.h
+new file mode 100644
+index 00000000..2f3bc844
+--- /dev/null
++++ b/sound/soc/codecs/ak4954_amb.h
+@@ -0,0 +1,228 @@
++/*
++ * ak4954_amb.h  --  audio driver for AK4954
++ *
++ * Copyright 2014 Ambarella Ltd.
++ *
++ * Author: Diao Chengdong <cddiao@ambarella.com>
++ *
++ * History:
++ *	2014/03/27 - created
++ *
++ * 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.
++ */
++
++
++#ifndef _AK4954_AMB_H
++#define _AK4954_AMB_H
++
++#define AK4954_CLOCK_PLAYBACK	1
++#define AK4954_CLOCK_CAPTURE	2
++#define AK4954_CLOCK_OTHER		4
++
++#define AK4954_00_POWER_MANAGEMENT1		0x00
++#define AK4954_01_POWER_MANAGEMENT2		0x01
++#define AK4954_02_SIGNAL_SELECT1		0x02
++#define AK4954_03_SIGNAL_SELECT2		0x03
++#define AK4954_04_SIGNAL_SELECT3		0x04
++#define AK4954_05_MODE_CONTROL1			0x05
++#define AK4954_06_MODE_CONTROL2			0x06
++#define AK4954_07_MODE_CONTROL3			0x07
++#define AK4954_08_DIGITL_MIC			0x08
++#define AK4954_09_TIMER_SELECT			0x09
++#define AK4954_0A_ALC_TIMER_SELECT		0x0A
++#define AK4954_0B_ALC_MODE_CONTROL1		0x0B
++#define AK4954_0C_ALC_MODE_CONTROL2		0x0C
++#define AK4954_0D_LCH_INPUT_VOLUME_CONTROL		0x0D
++#define AK4954_0E_RCH_INPUT_VOLUME_CONTROL		0x0E
++#define AK4954_0F_RESERVED				0x0F
++#define AK4954_10_RESERVED				0x10
++#define AK4954_11_RESERVED				0x11
++#define AK4954_12_HP_OUTPUT_CONTROL		0x12
++#define AK4954_13_LCH_DIGITAL_VOLUME_CONTROL	0x13
++#define AK4954_14_RCH_DIGITAL_VOLUME_CONTROL	0x14
++#define AK4954_15_BEEP_FREQUENCY		0x15
++#define AK4954_16_BEEP_ON_TIME			0x16
++#define AK4954_17_BEEP_OFF_TIME			0x17
++#define AK4954_18_BEEP_REPEAT_COUNT		0x18
++#define AK4954_19_BEEP_VOLUME_CONTROL	0x19
++#define AK4954_1A_RESERVED				0x1A
++#define AK4954_1B_DIGITAL_FILTER_SELECT1		0x1B
++#define AK4954_1C_DIGITAL_FILTER_SELECT2		0x1C
++#define AK4954_1D_DIGITAL_FILTER_MODE			0x1D
++#define AK4954_1E_HPF2_COEFFICIENT0		0x1E
++#define AK4954_1F_HPF2_COEFFICIENT1		0x1F
++#define AK4954_20_HPF2_COEFFICIENT2		0x20
++#define AK4954_21_HPF2_COEFFICIENT3		0x21
++#define AK4954_22_LPF_COEFFICIENT0		0x22
++#define AK4954_23_LPF_COEFFICIENT1		0x23
++#define AK4954_24_LPF_COEFFICIENT2		0x24
++#define AK4954_25_LPF_COEFFICIENT3		0x25
++#define AK4954_26_FIL3_COEFFICIENT0		0x26
++#define AK4954_27_FIL3_COEFFICIENT1		0x27
++#define AK4954_28_FIL3_COEFFICIENT2		0x28
++#define AK4954_29_FIL3_COEFFICIENT3		0x29
++#define AK4954_2A_EQ_COEFFICIENT0		0x2A
++#define AK4954_2B_EQ_COEFFICIENT1		0x2B
++#define AK4954_2C_EQ_COEFFICIENT2		0x2C
++#define AK4954_2D_EQ_COEFFICIENT3		0x2D
++#define AK4954_2E_EQ_COEFFICIENT4		0x2E
++#define AK4954_2F_EQ_COEFFICIENT5		0x2F
++
++#define AK4954_30_DIGITAL_FILTER_SELECT3		0x30
++#define AK4954_31_RESERVED				0x31
++#define AK4954_32_E1_COEFFICIENT0		0x32
++#define AK4954_33_E1_COEFFICIENT1		0x33
++#define AK4954_34_E1_COEFFICIENT2		0x34
++#define AK4954_35_E1_COEFFICIENT3		0x35
++#define AK4954_36_E1_COEFFICIENT4		0x36
++#define AK4954_37_E1_COEFFICIENT5		0x37
++#define AK4954_38_E2_COEFFICIENT0		0x38
++#define AK4954_39_E2_COEFFICIENT1		0x39
++#define AK4954_3A_E2_COEFFICIENT2		0x3A
++#define AK4954_3B_E2_COEFFICIENT3		0x3B
++#define AK4954_3C_E2_COEFFICIENT4		0x3C
++#define AK4954_3D_E2_COEFFICIENT5		0x3D
++#define AK4954_3E_E3_COEFFICIENT0		0x3E
++#define AK4954_3F_E3_COEFFICIENT1		0x3F
++#define AK4954_40_E3_COEFFICIENT2		0x40
++#define AK4954_41_E3_COEFFICIENT3		0x41
++#define AK4954_42_E3_COEFFICIENT4		0x42
++#define AK4954_43_E3_COEFFICIENT5		0x43
++#define AK4954_44_E4_COEFFICIENT0		0x44
++#define AK4954_45_E4_COEFFICIENT1		0x45
++#define AK4954_46_E4_COEFFICIENT2		0x46
++#define AK4954_47_E4_COEFFICIENT3		0x47
++#define AK4954_48_E4_COEFFICIENT4		0x48
++#define AK4954_49_E4_COEFFICIENT5		0x49
++#define AK4954_4A_E5_COEFFICIENT0		0x4A
++#define AK4954_4B_E5_COEFFICIENT1		0x4B
++#define AK4954_4C_E5_COEFFICIENT2		0x4C
++#define AK4954_4D_E5_COEFFICIENT3		0x4D
++#define AK4954_4E_E5_COEFFICIENT4		0x4E
++#define AK4954_4F_E5_COEFFICIENT5		0x4F
++
++#define AK4954_50_DRC_MODE_CONTROL		0x50
++#define AK4954_51_NS_CONTROL			0x51
++#define AK4954_52_NS_GAIN_ATT_CONTROL	0x52
++#define AK4954_53_NS_ON_LEVEL			0x53
++#define AK4954_54_NS_OFF_LEVEL			0x54
++#define AK4954_55_NS_REFERENCE_SELECT	0x55
++#define AK4954_56_NS_LPF_COEFFICIENT0	0x56
++#define AK4954_57_NS_LPF_COEFFICIENT1	0x57
++#define AK4954_58_NS_LPF_COEFFICIENT2	0x58
++#define AK4954_59_NS_LPF_COEFFICIENT3	0x59
++#define AK4954_5A_NS_HPF_COEFFICIENT0	0x5A
++#define AK4954_5B_NS_HPF_COEFFICIENT1	0x5B
++#define AK4954_5C_NS_HPF_COEFFICIENT2	0x5C
++#define AK4954_5D_NS_HPF_COEFFICIENT3	0x5D
++#define AK4954_5E_RESERVED				0x5E
++#define AK4954_5F_RESERVED				0x5F
++#define AK4954_60_DVLC_FILTER_SELECT	0x60
++#define AK4954_61_DVLC_MODE_CONTROL		0x61
++#define AK4954_62_DVLCL_CURVE_X1			0x62
++#define AK4954_63_DVLCL_CURVE_Y1			0x63
++#define AK4954_64_DVLCL_CURVE_X2			0x64
++#define AK4954_65_DVLCL_CURVE_Y2			0x65
++#define AK4954_66_DVLCL_CURVE_X3			0x66
++#define AK4954_67_DVLCL_CURVE_Y3			0x67
++#define AK4954_68_DVLCL_SLOPE1			0x68
++#define AK4954_69_DVLCL_SLOPE2			0x69
++#define AK4954_6A_DVLCL_SLOPE3			0x6A
++#define AK4954_6B_DVLCL_SLOPE4			0x6B
++#define AK4954_6C_DVLCM_CURVE_X1		0x6C
++#define AK4954_6D_DVLCM_CURVE_Y1		0x6D
++#define AK4954_6E_DVLCM_CURVE_X2		0x6E
++#define AK4954_6F_DVLCM_CURVE_Y2		0x6F
++#define AK4954_70_DVLCM_CURVE_X3		0x70
++#define AK4954_71_DVLCM_CURVE_Y3		0x71
++#define AK4954_72_DVLCM_SLOPE1			0x72
++#define AK4954_73_DVLCM_SLOPE2			0x73
++#define AK4954_74_DVLCM_SLOPE3			0x74
++#define AK4954_75_DVLCM_SLOPE4			0x75
++#define AK4954_76_DVLCH_CURVE_X1		0x76
++#define AK4954_77_DVLCH_CURVE_Y1		0x77
++#define AK4954_78_DVLCH_CURVE_X2		0x78
++#define AK4954_79_DVLCH_CURVE_Y2		0x79
++#define AK4954_7A_DVLCH_CURVE_X3		0x7A
++#define AK4954_7B_DVLCH_CURVE_Y3		0x7B
++#define AK4954_7C_DVLCH_SLOPE1			0x7C
++#define AK4954_7D_DVLCH_SLOPE2			0x7D
++#define AK4954_7E_DVLCH_SLOPE3			0x7E
++#define AK4954_7F_DVLCH_SLOPE4			0x7F
++
++#define AK4954_80_DVLCL_LPF_COEFFICIENT0	0x80
++#define AK4954_81_DVLCL_LPF_COEFFICIENT1	0x81
++#define AK4954_82_DVLCL_LPF_COEFFICIENT2	0x82
++#define AK4954_83_DVLCL_LPF_COEFFICIENT3	0x83
++#define AK4954_84_DVLCM_HPF_COEFFICIENT0	0x84
++#define AK4954_85_DVLCM_HPF_COEFFICIENT1	0x85
++#define AK4954_86_DVLCM_HPF_COEFFICIENT2	0x86
++#define AK4954_87_DVLCM_HPF_COEFFICIENT3	0x87
++#define AK4954_88_DVLCM_LPF_COEFFICIENT0	0x88
++#define AK4954_89_DVLCM_LPF_COEFFICIENT1	0x89
++#define AK4954_8A_DVLCM_LPF_COEFFICIENT2	0x8A
++#define AK4954_8B_DVLCM_LPF_COEFFICIENT3	0x8B
++#define AK4954_8C_DVLCH_HPF_COEFFICIENT0	0x8C
++#define AK4954_8D_DVLCH_HPF_COEFFICIENT1	0x8D
++#define AK4954_8E_DVLCH_HPF_COEFFICIENT2	0x8E
++#define AK4954_8F_DVLCH_HPF_COEFFICIENT3	0x8F
++
++#define AK4954_MAX_REGISTERS	(AK4954_8F_DVLCH_HPF_COEFFICIENT3 + 1)
++
++/* Bitfield Definitions */
++
++/* AK4954_00_POWER_MANAGEMENT1 (0x00) Fields */
++#define AK4954_PMVCM				0x40
++
++/* AK4954_01_POWER_MANAGEMENT2 (0x01) Fields */
++#define AK4954_PMPLL				0x04
++#define AK4954_M_S					0x08
++
++/* AK4954_05_MODE_CONTROL1 (0x05) Fields */
++#define AK4954_DIF					0x07
++#define AK4954_DIF_24MSB_24LSB_MODE	(0 << 0)
++#define AK4954_DIF_24MSB_16LSB_MODE	(1 << 0)
++#define AK4954_DIF_24MSB_MODE		(2 << 0)
++#define AK4954_DIF_24_16_I2S_MODE	(3 << 0)
++#define AK4954_DIF_32MSB_MODE		(4 << 0)
++#define AK4954_DIF_32_I2S_MODE		(5 << 0)
++#define AK4954_BCKO					0x08
++
++#define AK4954_PLL					0x70
++#define AK4954_EXT_SLAVE			0
++#define AK4954_PLL_BICK32			(0 << 4)
++#define AK4954_PLL_BICK64			(1 << 4)
++#define AK4954_PLL_11_2896MHZ		(2 << 4)
++#define AK4954_PLL_12MHZ			(4 << 4)
++#define AK4954_PLL_24MHZ			(5 << 4)
++#define AK4954_PLL_13_5MHZ			(6 << 4)
++#define AK4954_PLL_27MHZ			(7 << 4)
++
++
++
++#define AK4954_MCLK_IN	0
++#define AK4954_BCLK_IN		1
++#define AK4954_MCLK_IN_BCLK_OUT 2
++
++
++
++/* AK4954_06_MODE_CONTROL2 (0x06) Fields */
++#define AK4954_FS				0x0F
++#define AK4954_FS_8KHZ			(0 << 0)
++#define AK4954_FS_11_025KHZ		(1 << 0)
++#define AK4954_FS_12KHZ			(2 << 0)
++#define AK4954_FS_16KHZ			(4 << 0)
++#define AK4954_FS_22_05KHZ		(5 << 0)
++#define AK4954_FS_24KHZ			(6 << 0)
++#define AK4954_FS_32KHZ			(8 << 0)
++#define AK4954_FS_44_1KHZ		(9 << 0)
++#define AK4954_FS_48KHZ			(10 << 0)
++#define AK4954_FS_64KHZ			(12 << 0)
++#define AK4954_FS_88_2KHZ		(13 << 0)
++#define AK4954_FS_96KHZ			(14 << 0)
++#define AK4954_FS_CM0			(1 << 6)
++#define AK4954_FS_CM1			(1 << 7)
++
++#endif
+diff --git a/sound/soc/codecs/ak7719_amb.c b/sound/soc/codecs/ak7719_amb.c
+new file mode 100644
+index 00000000..0de1c607
+--- /dev/null
++++ b/sound/soc/codecs/ak7719_amb.c
+@@ -0,0 +1,6416 @@
++/*
++ * sound/soc/ambarella/ak7719.c
++ *
++  * History:
++ *	2014/04/17 - [Ken He] Created file
++ *
++ * Copyright (C) 2014-2018, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/i2c.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/delay.h>
++#include <linux/skbuff.h>
++#include <linux/workqueue.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <plat/audio.h>
++
++#define DRIVER_NAME "AK7719"
++#define CRC16_CCITT (0x1021)
++//#define BY_PASS_DSP
++//#define AK7719_DEBUG
++
++#ifdef AK7719_DEBUG
++#define akdbgprt printk
++#else
++#define akdbgprt(format, arg...) do {} while (0)
++#endif
++
++static int crc_timeout = 10;
++module_param(crc_timeout, uint, 0664);
++
++static int aec = 1;
++module_param(aec, uint, 0664);
++
++struct ak7719_data {
++	unsigned int rst_pin;
++	unsigned int rst_active;
++	struct i2c_client	*client;
++	struct device		*dev;
++};
++
++struct ak7719_workqueue{
++	struct ak7719_data *data;
++	struct work_struct download_binary;
++};
++
++static struct ak7719_workqueue ak7719_work;
++static struct workqueue_struct *ak7719_wq;
++
++u8 pram_data[] = {
++	0x0C, 0xB4, 0xED, 0x1E, 0x42,
++	0x04, 0xA9, 0x1C, 0x6D, 0x49,
++	0x04, 0x44, 0x82, 0x1A, 0x44,
++	0x0F, 0x58, 0x7E, 0x4D, 0x88,
++	0x0D, 0x5A, 0x7E, 0x89, 0x1D,
++	0x03, 0x35, 0x1C, 0x03, 0x8C,
++	0x0F, 0x4A, 0x05, 0x6C, 0x68,
++	0x0A, 0x70, 0xFF, 0x60, 0xE7,
++	0x01, 0x83, 0x9B, 0x95, 0x72,
++	0x09, 0x79, 0x72, 0x83, 0xAE,
++	0x07, 0xAE, 0xA6, 0x4F, 0x67,
++	0x0E, 0xD9, 0xA5, 0xD2, 0x80,
++	0x00, 0x7B, 0xE2, 0xEA, 0x9E,
++	0x05, 0xDB, 0xB3, 0xF9, 0xAC,
++	0x0E, 0x38, 0x0C, 0xB8, 0x91,
++	0x03, 0x81, 0xB6, 0x89, 0xCA,
++	0x0C, 0xDF, 0x09, 0xD1, 0x5F,
++	0x0F, 0x78, 0x28, 0xDB, 0xF2,
++	0x06, 0x67, 0x95, 0x59, 0x5B,
++	0x0B, 0xF4, 0x98, 0x6B, 0x25,
++	0x0A, 0x72, 0xD4, 0x2D, 0xBB,
++	0x09, 0xAE, 0x33, 0x01, 0x57,
++	0x09, 0x6B, 0xBD, 0xBA, 0x4F,
++	0x01, 0x54, 0x86, 0x70, 0xBB,
++	0x0F, 0x53, 0xBC, 0x3F, 0xE7,
++	0x0B, 0xC4, 0x7B, 0x42, 0x4E,
++	0x08, 0x79, 0x17, 0x62, 0xAD,
++	0x0A, 0x33, 0xE5, 0x31, 0x10,
++	0x04, 0x47, 0xD3, 0x15, 0x7C,
++	0x01, 0x37, 0xC4, 0x85, 0x60,
++	0x00, 0xA2, 0x23, 0xE4, 0xD4,
++	0x07, 0x81, 0x74, 0x8D, 0x2F,
++	0x03, 0x31, 0xCD, 0x59, 0xE3,
++	0x02, 0x83, 0x5B, 0x76, 0x35,
++	0x00, 0xD5, 0x02, 0x95, 0xE5,
++	0x00, 0x0E, 0x1C, 0xDE, 0xA7,
++	0x03, 0xCC, 0xE5, 0x7B, 0x43,
++	0x07, 0x78, 0x7B, 0xC1, 0xF0,
++	0x07, 0x99, 0x68, 0x27, 0x75,
++	0x09, 0x26, 0xC9, 0x48, 0xCB,
++	0x0A, 0xE2, 0x66, 0x20, 0x0F,
++	0x00, 0x27, 0x5E, 0x03, 0x67,
++	0x04, 0x85, 0x12, 0xD3, 0xDD,
++	0x09, 0x6F, 0xCD, 0xA9, 0x87,
++	0x0C, 0x65, 0x18, 0x5F, 0xD1,
++	0x0F, 0xAC, 0xB4, 0x47, 0xD4,
++	0x0C, 0x76, 0x67, 0x16, 0x91,
++	0x0A, 0x05, 0x2B, 0x4B, 0xB2,
++	0x0C, 0xE9, 0x3F, 0x75, 0x12,
++	0x05, 0xC6, 0x96, 0xCD, 0x0A,
++	0x0A, 0x3C, 0x32, 0xDF, 0x24,
++	0x02, 0x09, 0x4E, 0xC1, 0xE5,
++	0x07, 0x49, 0x92, 0xC6, 0xE0,
++	0x04, 0xC4, 0x40, 0x31, 0x1A,
++	0x02, 0x55, 0x86, 0x34, 0xDF,
++	0x06, 0x15, 0xA2, 0xAC, 0x9B,
++	0x0F, 0x93, 0x51, 0x30, 0x18,
++	0x0A, 0x34, 0xBD, 0xA2, 0x8D,
++	0x05, 0x67, 0xD6, 0xFA, 0x10,
++	0x06, 0x58, 0x09, 0x7D, 0x54,
++	0x06, 0x51, 0x2E, 0x70, 0x0F,
++	0x0E, 0x7A, 0xAA, 0x64, 0x04,
++	0x09, 0xED, 0xDD, 0xDD, 0xD9,
++	0x03, 0x07, 0xB2, 0x2E, 0x5D,
++	0x09, 0x1D, 0x88, 0xCF, 0x9B,
++	0x09, 0x3C, 0x72, 0x57, 0xB8,
++	0x04, 0x80, 0xCF, 0x70, 0x95,
++	0x0B, 0x0D, 0xEB, 0xB9, 0x14,
++	0x0B, 0x4F, 0xD9, 0x29, 0xF5,
++	0x0A, 0xA6, 0xEE, 0xB1, 0x9D,
++	0x09, 0x7F, 0x47, 0x8E, 0xB8,
++	0x04, 0x1F, 0x74, 0x1A, 0xDB,
++	0x0C, 0x5A, 0xF9, 0x28, 0x1A,
++	0x07, 0x2E, 0x76, 0x7F, 0xA4,
++	0x09, 0xEA, 0x48, 0x67, 0x3A,
++	0x03, 0x35, 0xBB, 0xC3, 0x3E,
++	0x03, 0x7F, 0x5C, 0xC8, 0x17,
++	0x0B, 0x47, 0x9F, 0xB2, 0x20,
++	0x07, 0x1B, 0x57, 0x9F, 0x5B,
++	0x00, 0x84, 0x61, 0xB5, 0x1C,
++	0x0B, 0xD3, 0x72, 0xA4, 0x1C,
++	0x0F, 0xB2, 0x4B, 0xF2, 0x07,
++	0x0C, 0xC0, 0x63, 0xA4, 0x58,
++	0x0E, 0x8B, 0x1D, 0xE9, 0x14,
++	0x0E, 0xE8, 0x37, 0xBB, 0x2A,
++	0x0E, 0xF5, 0x50, 0x29, 0x5E,
++	0x0D, 0xC0, 0xE7, 0x47, 0xF6,
++	0x08, 0x90, 0xCA, 0x1A, 0x32,
++	0x08, 0x77, 0x85, 0xF2, 0x57,
++	0x00, 0x81, 0x10, 0x4A, 0xB6,
++	0x0F, 0x3E, 0x6E, 0x54, 0x84,
++	0x0C, 0x4E, 0x3D, 0xA2, 0x5D,
++	0x08, 0xC2, 0x72, 0xBA, 0x35,
++	0x0D, 0xE4, 0x50, 0xAD, 0x3F,
++	0x08, 0x96, 0xFC, 0x9A, 0x9F,
++	0x0C, 0xC6, 0x51, 0xA5, 0xFA,
++	0x0A, 0x25, 0x34, 0xC0, 0x4E,
++	0x08, 0x6B, 0xEE, 0xC8, 0x6B,
++	0x06, 0xA1, 0xD0, 0x3C, 0xA6,
++	0x08, 0x06, 0x73, 0xDB, 0x51,
++	0x08, 0x1A, 0xCB, 0x6C, 0x10,
++	0x05, 0x0F, 0xB8, 0xBD, 0xB1,
++	0x01, 0x20, 0x94, 0xE5, 0x1E,
++	0x00, 0xD8, 0x69, 0x1C, 0x64,
++	0x0C, 0x3C, 0xC4, 0x02, 0x11,
++	0x08, 0xE4, 0x87, 0xAF, 0x49,
++	0x04, 0xA0, 0xBA, 0x7E, 0xCD,
++	0x0D, 0xF9, 0x37, 0x35, 0x03,
++	0x0C, 0xA3, 0x49, 0xFE, 0x26,
++	0x09, 0x97, 0xF8, 0x3B, 0xBD,
++	0x0F, 0x5D, 0x62, 0xDB, 0xD5,
++	0x09, 0x03, 0x9B, 0x77, 0xC3,
++	0x05, 0x27, 0x2C, 0xA2, 0xC9,
++	0x04, 0x5F, 0x4F, 0xE1, 0xC3,
++	0x04, 0x75, 0x05, 0x66, 0x17,
++	0x0D, 0x28, 0x43, 0xBC, 0xE4,
++	0x0D, 0x51, 0x57, 0x1A, 0xBC,
++	0x04, 0x8B, 0x4C, 0x23, 0x0C,
++	0x01, 0x35, 0x47, 0x9B, 0x91,
++	0x02, 0xB4, 0xFF, 0x92, 0x5B,
++	0x02, 0x6A, 0x66, 0x07, 0x13,
++	0x0A, 0x97, 0x3D, 0x18, 0xE2,
++	0x00, 0xF1, 0x1D, 0x81, 0xA4,
++	0x0B, 0x05, 0xAF, 0xA8, 0x33,
++	0x0A, 0xF2, 0xEC, 0x05, 0x8E,
++	0x03, 0x5D, 0x87, 0x06, 0x79,
++	0x01, 0xB2, 0xC3, 0xBC, 0x22,
++	0x0C, 0xF6, 0x4B, 0xCC, 0x9F,
++	0x08, 0x31, 0xC6, 0x73, 0x93,
++	0x08, 0x70, 0x37, 0x31, 0x2C,
++	0x0C, 0x09, 0xA3, 0xD3, 0x96,
++	0x08, 0x3D, 0xD7, 0x22, 0x45,
++	0x00, 0x7A, 0xC4, 0xB7, 0xA4,
++	0x08, 0xCC, 0xC2, 0x32, 0x84,
++	0x0F, 0xE8, 0xBB, 0xD2, 0x87,
++	0x03, 0xEE, 0x81, 0x5F, 0x7C,
++	0x09, 0x5F, 0x5D, 0x0E, 0x55,
++	0x07, 0xDC, 0x0E, 0x72, 0xAD,
++	0x0A, 0x09, 0xAC, 0xE1, 0x7B,
++	0x06, 0xE7, 0xFA, 0x7F, 0xC1,
++	0x03, 0x8B, 0x53, 0x44, 0xAE,
++	0x08, 0xF3, 0xE6, 0xC3, 0x02,
++	0x0F, 0x6A, 0x33, 0xA2, 0x29,
++	0x00, 0x8C, 0x25, 0x2C, 0x89,
++	0x03, 0xBE, 0xA5, 0x06, 0xD3,
++	0x0F, 0xCF, 0x8F, 0xC9, 0x69,
++	0x02, 0x0C, 0x2F, 0x1A, 0x1F,
++	0x01, 0x63, 0xAC, 0xB5, 0xF4,
++	0x04, 0xDE, 0x52, 0xE0, 0x16,
++	0x07, 0x2C, 0xE1, 0x2B, 0x08,
++	0x02, 0x1C, 0xA4, 0x3D, 0x55,
++	0x0A, 0x19, 0x42, 0xFF, 0x4D,
++	0x0E, 0xF0, 0xFF, 0x83, 0xDF,
++	0x07, 0x32, 0x09, 0x4E, 0xD1,
++	0x05, 0xCD, 0x8A, 0x97, 0xC6,
++	0x09, 0xC5, 0x66, 0xC0, 0x3C,
++	0x08, 0x3E, 0xD7, 0x86, 0xF4,
++	0x00, 0x8A, 0xD1, 0xE7, 0xE5,
++	0x02, 0xDF, 0x91, 0x57, 0x3A,
++	0x03, 0x4F, 0x7B, 0x3F, 0xA2,
++	0x0C, 0xDC, 0x28, 0x0F, 0xBA,
++	0x01, 0x6D, 0x4A, 0x6D, 0x60,
++	0x08, 0x0A, 0x44, 0x57, 0x78,
++	0x02, 0x50, 0x3F, 0x6A, 0x24,
++	0x0F, 0x84, 0x68, 0x9A, 0x00,
++	0x0D, 0xFF, 0xDE, 0xBE, 0x27,
++	0x04, 0x12, 0x9D, 0xA3, 0x07,
++	0x0B, 0x15, 0x23, 0x89, 0xA1,
++	0x00, 0x68, 0x60, 0x4E, 0x30,
++	0x05, 0x2D, 0xEF, 0xE9, 0xF9,
++	0x0E, 0x2B, 0x19, 0x59, 0x05,
++	0x07, 0x26, 0x24, 0x62, 0xB1,
++	0x0E, 0x69, 0x17, 0xC5, 0x8F,
++	0x0A, 0xCF, 0x9D, 0x78, 0xDA,
++	0x07, 0xB1, 0xFD, 0x7A, 0xB5,
++	0x0F, 0x2A, 0x61, 0x60, 0x73,
++	0x0F, 0x70, 0x9B, 0xC8, 0x67,
++	0x07, 0xDA, 0xB7, 0x7B, 0xDE,
++	0x02, 0x0E, 0xFE, 0x5C, 0xD5,
++	0x07, 0x3B, 0x47, 0x99, 0x36,
++	0x06, 0x47, 0x04, 0x17, 0x21,
++	0x01, 0x70, 0x04, 0x61, 0x39,
++	0x06, 0x1B, 0xD1, 0x72, 0x28,
++	0x06, 0x9F, 0xB0, 0x4F, 0x74,
++	0x04, 0xCC, 0x2C, 0x63, 0xE8,
++	0x08, 0xFE, 0xE3, 0x9D, 0x45,
++	0x07, 0xBE, 0x08, 0x35, 0x77,
++	0x0A, 0xB5, 0x90, 0xD0, 0x09,
++	0x02, 0x5C, 0xA0, 0xE7, 0x54,
++	0x00, 0x2D, 0xF6, 0x42, 0x9F,
++	0x0A, 0x69, 0x13, 0xC7, 0xE1,
++	0x05, 0x7D, 0xD5, 0x96, 0x38,
++	0x0A, 0x8E, 0xD6, 0xEC, 0x50,
++	0x02, 0x37, 0x47, 0xA6, 0x27,
++	0x0A, 0x8D, 0xB0, 0xF4, 0x9E,
++	0x07, 0xA6, 0xE4, 0x54, 0x8F,
++	0x03, 0x65, 0xF2, 0xBC, 0x87,
++	0x05, 0x80, 0x1D, 0xD1, 0xAC,
++	0x06, 0x93, 0x56, 0xCD, 0x8E,
++	0x01, 0xD1, 0x82, 0xEE, 0xC5,
++	0x07, 0xEB, 0x48, 0x92, 0xB9,
++	0x00, 0x04, 0xBC, 0x15, 0xE5,
++	0x0B, 0x21, 0xF4, 0xAF, 0x6D,
++	0x0C, 0xEE, 0x68, 0x78, 0x20,
++	0x0D, 0x73, 0x36, 0x54, 0xE5,
++	0x05, 0xF9, 0xAE, 0xAF, 0x2E,
++	0x0D, 0x5C, 0x4C, 0x40, 0x60,
++	0x01, 0x84, 0xE5, 0x5C, 0xCD,
++	0x07, 0xC8, 0xC8, 0xDA, 0x7F,
++	0x09, 0x2D, 0xF9, 0x31, 0x11,
++	0x01, 0x8C, 0xA3, 0x4F, 0xD9,
++	0x00, 0x74, 0x14, 0xF8, 0xE6,
++	0x08, 0xD6, 0x51, 0x8E, 0xD7,
++	0x0D, 0x46, 0x29, 0x79, 0xB4,
++	0x09, 0x9D, 0x4A, 0xAE, 0xE2,
++	0x0B, 0x38, 0xDE, 0xD1, 0x10,
++	0x07, 0x1F, 0x30, 0x73, 0x62,
++	0x0C, 0x41, 0x47, 0xDA, 0x3D,
++	0x01, 0xB1, 0xD2, 0x30, 0x2B,
++	0x01, 0x98, 0x48, 0x0C, 0xE3,
++	0x00, 0x4A, 0x50, 0xDE, 0x5B,
++	0x0B, 0x42, 0xC5, 0x7D, 0xB2,
++	0x03, 0x72, 0xCA, 0x6A, 0x43,
++	0x05, 0x47, 0xF0, 0x74, 0x45,
++	0x07, 0x2D, 0x39, 0xF7, 0x45,
++	0x01, 0xBA, 0xD5, 0xEF, 0xAF,
++	0x0A, 0xCF, 0x88, 0x6E, 0x07,
++	0x06, 0x4E, 0xDE, 0xC4, 0x9B,
++	0x0C, 0xBC, 0x2E, 0xC3, 0xA1,
++	0x0D, 0xE0, 0xF7, 0xC3, 0xCC,
++	0x0E, 0x59, 0xB4, 0x79, 0xEF,
++	0x02, 0xD4, 0xF3, 0xB5, 0x71,
++	0x0D, 0x10, 0xCE, 0xC6, 0x1A,
++	0x05, 0x61, 0xBF, 0x33, 0x28,
++	0x0E, 0xEC, 0xB4, 0xA4, 0xB7,
++	0x0F, 0x51, 0x83, 0x86, 0x32,
++	0x01, 0x2F, 0x7A, 0xF1, 0xCB,
++	0x02, 0x61, 0xAB, 0x03, 0x53,
++	0x0A, 0x0A, 0xDA, 0x15, 0x1F,
++	0x09, 0xE4, 0x5C, 0x0E, 0x6A,
++	0x0E, 0xBA, 0x8D, 0x0C, 0x29,
++	0x0B, 0x66, 0x87, 0x7C, 0x75,
++	0x01, 0xEF, 0x8B, 0x99, 0xCC,
++	0x0B, 0x68, 0xDF, 0xA6, 0xCD,
++	0x08, 0xE3, 0x6A, 0xE0, 0xD9,
++	0x00, 0x10, 0x8E, 0x25, 0x90,
++	0x03, 0x7A, 0x6E, 0xCB, 0x80,
++	0x03, 0xF6, 0x41, 0xE1, 0x03,
++	0x05, 0x99, 0x8A, 0xE5, 0x07,
++	0x0F, 0xD1, 0x6B, 0x2C, 0x42,
++	0x07, 0xDD, 0x04, 0xB4, 0x5E,
++	0x0D, 0x3B, 0x7B, 0x07, 0x98,
++	0x07, 0xB9, 0x9A, 0xE9, 0x20,
++	0x09, 0x13, 0x9D, 0xC2, 0xEB,
++	0x0D, 0x0E, 0xF2, 0xFF, 0x47,
++	0x0D, 0x17, 0x32, 0x87, 0x04,
++	0x03, 0xE7, 0xCD, 0x04, 0x9B,
++	0x06, 0x25, 0x64, 0xC4, 0x40,
++	0x01, 0x68, 0xCC, 0x57, 0x34,
++	0x0D, 0x1C, 0x6A, 0x19, 0xA7,
++	0x05, 0x14, 0x3F, 0x93, 0x13,
++	0x0A, 0x18, 0x4F, 0x34, 0x9F,
++	0x0E, 0xC7, 0x99, 0x67, 0x86,
++	0x0A, 0x0D, 0x6F, 0xD8, 0x2D,
++	0x01, 0x54, 0xC0, 0x17, 0x9E,
++	0x08, 0x39, 0x50, 0x78, 0x6A,
++	0x08, 0x31, 0xA5, 0xED, 0x9E,
++	0x0D, 0xE1, 0xFF, 0x01, 0xFC,
++	0x02, 0x64, 0x9D, 0x5D, 0xA7,
++	0x03, 0x9B, 0x13, 0x63, 0x85,
++	0x0B, 0x89, 0x88, 0x80, 0xC8,
++	0x0C, 0x9C, 0xAB, 0x8D, 0xE1,
++	0x05, 0x15, 0x81, 0x4F, 0xC4,
++	0x0E, 0x3A, 0x69, 0x24, 0xE2,
++	0x0A, 0x11, 0x26, 0xFF, 0x45,
++	0x02, 0xB0, 0x10, 0xDF, 0x70,
++	0x06, 0xDA, 0x30, 0x5A, 0xE7,
++	0x08, 0x14, 0xAD, 0x28, 0xE2,
++	0x03, 0xA4, 0xF7, 0xD0, 0x42,
++	0x0B, 0x0A, 0x5C, 0xF4, 0x26,
++	0x08, 0x7B, 0xF9, 0x7C, 0xAD,
++	0x04, 0x25, 0xF2, 0x07, 0x96,
++	0x06, 0x2A, 0x45, 0x1B, 0x57,
++	0x03, 0x11, 0x00, 0x08, 0xEB,
++	0x09, 0x56, 0x19, 0xDF, 0xB8,
++	0x04, 0x57, 0x1D, 0x32, 0x56,
++	0x06, 0x4D, 0xC0, 0xCC, 0x63,
++	0x00, 0xD4, 0x72, 0x8B, 0xDD,
++	0x0F, 0x9E, 0xAC, 0xE8, 0x75,
++	0x0F, 0x60, 0x35, 0xFD, 0xA1,
++	0x00, 0x5E, 0x9D, 0xC8, 0x27,
++	0x03, 0xEB, 0x3B, 0x90, 0xCF,
++	0x0F, 0xB6, 0xE8, 0x7F, 0x36,
++	0x05, 0x1E, 0x38, 0xB1, 0x10,
++	0x03, 0xF6, 0x6F, 0x3E, 0xAC,
++	0x0E, 0x8E, 0xA0, 0x2E, 0x06,
++	0x0A, 0x81, 0xA8, 0xCE, 0x32,
++	0x00, 0x36, 0xC1, 0x64, 0x4D,
++	0x01, 0x3E, 0xBC, 0xD6, 0xF8,
++	0x06, 0x98, 0x60, 0x46, 0x54,
++	0x0E, 0x78, 0x6C, 0xBA, 0xCB,
++	0x00, 0x7C, 0x53, 0xAB, 0x73,
++	0x0D, 0x6B, 0xF8, 0x60, 0x5A,
++	0x0E, 0xBB, 0x83, 0x48, 0x93,
++	0x0B, 0x50, 0x81, 0x9C, 0x32,
++	0x0C, 0xA0, 0x6D, 0x0F, 0xF8,
++	0x01, 0xF1, 0xBD, 0x60, 0x9D,
++	0x0D, 0x1E, 0x7E, 0xDC, 0xA3,
++	0x07, 0xE8, 0x13, 0xCC, 0x44,
++	0x09, 0x94, 0xCB, 0x65, 0x58,
++	0x03, 0x4D, 0x5A, 0xE1, 0x47,
++	0x05, 0x4B, 0x68, 0x79, 0x35,
++	0x0F, 0x01, 0x73, 0x63, 0x43,
++	0x06, 0x2D, 0xF0, 0x56, 0x65,
++	0x0B, 0xA0, 0xD6, 0xD9, 0x88,
++	0x07, 0xD5, 0x40, 0xA5, 0xB1,
++	0x0B, 0x03, 0xB1, 0x67, 0xA6,
++	0x02, 0x43, 0x38, 0x5C, 0x62,
++	0x01, 0xDE, 0x1D, 0xF2, 0xC1,
++	0x02, 0xE6, 0x41, 0xA7, 0x10,
++	0x00, 0xF8, 0x31, 0x12, 0x25,
++	0x06, 0xB9, 0x12, 0xC8, 0x19,
++	0x03, 0x09, 0xCA, 0x30, 0x2F,
++	0x0B, 0x91, 0x40, 0xB6, 0x4F,
++	0x09, 0xDE, 0x2D, 0xE8, 0xD5,
++	0x0F, 0x18, 0xC2, 0xD7, 0xE9,
++	0x08, 0xEB, 0x2E, 0xF1, 0xF7,
++	0x03, 0xAD, 0xBB, 0x8B, 0xE5,
++	0x06, 0x81, 0xCA, 0x32, 0xF3,
++	0x07, 0x4A, 0xCD, 0x53, 0x4E,
++	0x0A, 0x70, 0xBB, 0x33, 0x4B,
++	0x07, 0xBD, 0xA1, 0xF7, 0xC5,
++	0x00, 0x83, 0x0C, 0x74, 0x7D,
++	0x0F, 0x63, 0x24, 0x31, 0xA8,
++	0x01, 0x31, 0x12, 0x0E, 0x44,
++	0x0F, 0x94, 0xEA, 0x3D, 0x2A,
++	0x02, 0x85, 0x6B, 0xFB, 0xD5,
++	0x0C, 0x61, 0x22, 0xCE, 0xB4,
++	0x0E, 0x8D, 0xFF, 0x28, 0xB8,
++	0x06, 0x59, 0xE1, 0xEE, 0x83,
++	0x0B, 0x76, 0x0B, 0xD3, 0xDF,
++	0x02, 0x95, 0xE7, 0xD0, 0xC4,
++	0x08, 0x9E, 0x2A, 0x89, 0x08,
++	0x0D, 0x79, 0x86, 0x87, 0x7C,
++	0x03, 0xC0, 0x6B, 0x4B, 0x84,
++	0x08, 0xA7, 0xBB, 0x73, 0xEF,
++	0x0D, 0x48, 0x63, 0x6A, 0x62,
++	0x00, 0x20, 0x10, 0x8C, 0xA7,
++	0x06, 0xC3, 0xE8, 0x2E, 0x58,
++	0x0A, 0xA2, 0x76, 0x49, 0x6F,
++	0x05, 0xA9, 0x8B, 0x4C, 0x6D,
++	0x01, 0xDD, 0x96, 0xE3, 0xAC,
++	0x03, 0xC7, 0xDF, 0x06, 0xB6,
++	0x0C, 0x16, 0xBC, 0xAE, 0x0F,
++	0x07, 0xCA, 0x1D, 0x1C, 0xF4,
++	0x06, 0xF0, 0x5D, 0x99, 0xC2,
++	0x0D, 0x48, 0x41, 0x70, 0xFF,
++	0x0F, 0xDE, 0x97, 0xF2, 0x14,
++	0x07, 0x51, 0x07, 0xC1, 0x8A,
++	0x08, 0x40, 0x37, 0xC4, 0x04,
++	0x00, 0x21, 0x1A, 0x4A, 0x5F,
++	0x0A, 0xF5, 0x53, 0x8A, 0x08,
++	0x0C, 0x69, 0xEC, 0x5B, 0x62,
++	0x0F, 0x31, 0x8A, 0x8A, 0x29,
++	0x03, 0xA1, 0x80, 0x99, 0x63,
++	0x03, 0xB9, 0x2D, 0x6D, 0xDD,
++	0x06, 0xF8, 0xCD, 0x0A, 0x57,
++	0x0B, 0x71, 0xBD, 0x52, 0x67,
++	0x06, 0x25, 0xDA, 0x45, 0xF0,
++	0x08, 0x1D, 0xE3, 0xF9, 0x07,
++	0x0E, 0x2E, 0x64, 0x12, 0x9D,
++	0x03, 0xBF, 0x1B, 0x91, 0x29,
++	0x0D, 0xAB, 0x89, 0x88, 0x80,
++	0x02, 0x30, 0x9E, 0xAF, 0x07,
++	0x02, 0x3C, 0x42, 0x2F, 0x4F,
++	0x05, 0x25, 0xBA, 0x26, 0xAF,
++	0x00, 0x31, 0x96, 0x65, 0x6E,
++	0x09, 0x8E, 0x32, 0xCF, 0x28,
++	0x0C, 0x99, 0xFB, 0xB2, 0xDA,
++	0x02, 0xA2, 0x34, 0xA2, 0xEE,
++	0x0A, 0x73, 0x7C, 0x75, 0xF4,
++	0x08, 0x67, 0x09, 0xDF, 0x7E,
++	0x03, 0xC2, 0x7E, 0x03, 0x7C,
++	0x06, 0xC9, 0x91, 0xBB, 0x67,
++	0x03, 0x36, 0x2A, 0x47, 0x12,
++	0x07, 0x13, 0x13, 0x00, 0x84,
++	0x01, 0x39, 0x56, 0x9B, 0xD3,
++	0x0A, 0x28, 0xD6, 0x1D, 0x32,
++	0x03, 0xFE, 0xED, 0xCE, 0x40,
++	0x0A, 0x28, 0x12, 0x7C, 0x0B,
++	0x04, 0xE5, 0x7E, 0xBC, 0x68,
++	0x05, 0xB7, 0x60, 0x37, 0x4E,
++	0x00, 0x29, 0x5E, 0xDF, 0x7A,
++	0x07, 0x49, 0xEB, 0x2A, 0x29,
++	0x0E, 0x17, 0xB6, 0xEA, 0xCF,
++	0x07, 0xFC, 0x1E, 0x7A, 0x0E,
++	0x00, 0x4A, 0x76, 0x0D, 0x88,
++	0x0C, 0x54, 0x8E, 0xB4, 0x1B,
++	0x06, 0x22, 0x01, 0x8A, 0x76,
++	0x02, 0xAC, 0x37, 0x24, 0x57,
++	0x00, 0xAD, 0x3F, 0xE6, 0x24,
++	0x0C, 0x9A, 0x99, 0x02, 0x77,
++	0x01, 0xA5, 0xFD, 0x94, 0x8A,
++	0x0B, 0x3C, 0x7D, 0x52, 0xED,
++	0x0E, 0xC1, 0x6B, 0x68, 0x27,
++	0x02, 0xBC, 0xB9, 0x83, 0x4A,
++	0x03, 0xD7, 0x51, 0x23, 0x19,
++	0x03, 0x6C, 0xD0, 0xEF, 0x31,
++	0x06, 0x3D, 0xF1, 0x73, 0x20,
++	0x0B, 0x6D, 0x1E, 0x7C, 0xD8,
++	0x05, 0x1C, 0x6D, 0x5C, 0x45,
++	0x04, 0x02, 0x13, 0x84, 0xE5,
++	0x08, 0x6F, 0x4D, 0x4E, 0xAB,
++	0x0A, 0x7E, 0xC9, 0xAB, 0xB3,
++	0x05, 0x33, 0x01, 0x0A, 0x29,
++	0x0B, 0xFA, 0x2C, 0xF3, 0x5C,
++	0x08, 0xFB, 0xA0, 0x58, 0x17,
++	0x02, 0xD7, 0xD5, 0xCE, 0x2F,
++	0x09, 0x77, 0x03, 0x13, 0x6D,
++	0x0E, 0xA2, 0x43, 0xB6, 0x54,
++	0x09, 0xA1, 0xDE, 0x92, 0x3A,
++	0x0B, 0xE2, 0xE6, 0xCC, 0xA3,
++	0x0A, 0x3C, 0xF9, 0x3C, 0x18,
++	0x08, 0xDA, 0xB8, 0x15, 0x82,
++	0x04, 0x23, 0x09, 0x46, 0x7A,
++	0x0E, 0x9B, 0x91, 0xCE, 0x3E,
++	0x0D, 0x92, 0x5B, 0x7E, 0x20,
++	0x06, 0x03, 0x19, 0xCA, 0x9D,
++	0x04, 0x58, 0xEB, 0xAF, 0x7B,
++	0x07, 0x41, 0xAD, 0x38, 0xCF,
++	0x0F, 0xAA, 0x81, 0xC9, 0xF8,
++	0x0E, 0x07, 0x38, 0x4C, 0x17,
++	0x0B, 0x06, 0x70, 0xBD, 0xB3,
++	0x03, 0xBC, 0x3D, 0xE0, 0xFD,
++	0x09, 0xCC, 0x82, 0x53, 0x8A,
++	0x05, 0xD3, 0x62, 0xA4, 0x4E,
++	0x09, 0x71, 0x31, 0x10, 0x0E,
++	0x0A, 0x03, 0x95, 0x61, 0xBA,
++	0x0B, 0x22, 0x95, 0x69, 0xC1,
++	0x08, 0xB6, 0x84, 0xD4, 0xFE,
++	0x0A, 0x3A, 0x4D, 0x2F, 0xDB,
++	0x0A, 0x57, 0x9A, 0xE3, 0xEE,
++	0x0F, 0x59, 0x16, 0x0B, 0x6D,
++	0x09, 0x08, 0x85, 0xE5, 0xEF,
++	0x02, 0x75, 0x1E, 0x3A, 0x94,
++	0x04, 0xE1, 0xF9, 0x6A, 0x87,
++	0x00, 0x79, 0x42, 0x6F, 0x4B,
++	0x01, 0x02, 0x25, 0x6A, 0x73,
++	0x0C, 0xC4, 0xC2, 0x63, 0x4A,
++	0x09, 0xE3, 0xE3, 0x10, 0x8C,
++	0x0B, 0x2A, 0xD1, 0x7A, 0x54,
++	0x09, 0x0A, 0xD3, 0xF6, 0x7B,
++	0x04, 0x48, 0x6A, 0x94, 0xBF,
++	0x09, 0x1A, 0x8F, 0xD1, 0x51,
++	0x07, 0x32, 0x04, 0xD1, 0xB5,
++	0x0A, 0xFC, 0x16, 0xBE, 0xAC,
++	0x09, 0x2B, 0xDB, 0xB8, 0x26,
++	0x05, 0x3D, 0x65, 0x12, 0x2B,
++	0x0E, 0xF7, 0xAD, 0x0E, 0xC3,
++	0x04, 0x02, 0x1C, 0x17, 0x32,
++	0x05, 0x4E, 0x31, 0xE7, 0xFF,
++	0x06, 0x90, 0x26, 0xD5, 0xF7,
++	0x0F, 0xC1, 0xE2, 0x18, 0x4E,
++	0x09, 0x86, 0xF1, 0x9C, 0x83,
++	0x05, 0xA7, 0xEE, 0x92, 0xDF,
++	0x0B, 0x1B, 0xB0, 0x14, 0xCA,
++	0x0C, 0xB9, 0x20, 0xC5, 0xD9,
++	0x0D, 0x8F, 0x50, 0x8D, 0x2D,
++	0x03, 0xAD, 0x6C, 0xD4, 0x0A,
++	0x0B, 0x97, 0xF0, 0x39, 0xE5,
++	0x06, 0xDA, 0x24, 0x33, 0xB7,
++	0x01, 0x9B, 0x7D, 0xE1, 0xFB,
++	0x0B, 0xBF, 0x8E, 0x64, 0x17,
++	0x06, 0x22, 0x13, 0x9B, 0x15,
++	0x0F, 0x8C, 0x4B, 0x89, 0x8C,
++	0x0C, 0x40, 0x10, 0x9C, 0xAE,
++	0x06, 0x68, 0x65, 0x14, 0x2B,
++	0x03, 0xD9, 0x25, 0xFF, 0x28,
++	0x0A, 0x60, 0x31, 0xD4, 0x51,
++	0x03, 0x44, 0xEE, 0xB2, 0xF6,
++	0x03, 0x74, 0x1E, 0xDB, 0x8A,
++	0x06, 0xFA, 0xA8, 0x14, 0x94,
++	0x06, 0xE0, 0xF3, 0xA4, 0xF5,
++	0x0F, 0xC9, 0x81, 0x8B, 0xDB,
++	0x04, 0x3B, 0xC3, 0xF0, 0x4B,
++	0x07, 0xDE, 0xF1, 0x26, 0x3E,
++	0x0B, 0x9E, 0xD6, 0x2A, 0x7E,
++	0x03, 0x57, 0x93, 0x11, 0x00,
++	0x0F, 0xE0, 0xDF, 0xD6, 0x1B,
++	0x03, 0x72, 0x28, 0x58, 0xDB,
++	0x09, 0xC9, 0x47, 0x4E, 0x49,
++	0x0C, 0x62, 0x48, 0xD2, 0xCC,
++	0x07, 0x1A, 0x9F, 0xDE, 0x0D,
++	0x04, 0x35, 0x37, 0x60, 0x82,
++	0x05, 0x50, 0x29, 0x52, 0xD9,
++	0x0B, 0x65, 0x1C, 0x67, 0x6D,
++	0x0C, 0xCF, 0xF7, 0xB6, 0x5A,
++	0x0B, 0x8F, 0xC6, 0x9E, 0xCB,
++	0x09, 0x90, 0x4A, 0x7A, 0x0B,
++	0x05, 0xEE, 0x01, 0x02, 0xF3,
++	0x02, 0x21, 0xD8, 0x41, 0x3D,
++	0x0E, 0x77, 0x4C, 0x77, 0x90,
++	0x08, 0x50, 0xED, 0x7F, 0x53,
++	0x0A, 0xFC, 0xA1, 0x59, 0xB8,
++	0x0A, 0x51, 0xE9, 0x3D, 0x2F,
++	0x06, 0xCB, 0xAC, 0x3D, 0xCD,
++	0x07, 0x4E, 0xC1, 0x6B, 0xD9,
++	0x0B, 0xD1, 0x47, 0x3B, 0x75,
++	0x02, 0x93, 0x9A, 0x51, 0x15,
++	0x00, 0x28, 0x96, 0x90, 0xD9,
++	0x03, 0xF8, 0x6E, 0x31, 0x4B,
++	0x0C, 0x95, 0xED, 0x1E, 0x45,
++	0x03, 0x2B, 0x78, 0x6D, 0x5C,
++	0x00, 0x45, 0x62, 0x11, 0xB6,
++	0x09, 0x5B, 0x8F, 0x4D, 0xFB,
++	0x0D, 0x5A, 0xFE, 0xC9, 0x1A,
++	0x02, 0xB7, 0xBB, 0x8C, 0xB5,
++	0x0F, 0x48, 0x1A, 0x2C, 0x47,
++	0x0A, 0x70, 0xC1, 0x20, 0xE5,
++	0x0D, 0x82, 0xD7, 0xD9, 0xC4,
++	0x0E, 0xFB, 0x22, 0x8F, 0x58,
++	0x0B, 0xAE, 0xEF, 0x43, 0x01,
++	0x05, 0x5B, 0x1F, 0x5E, 0x1F,
++	0x0C, 0x7A, 0x82, 0xE6, 0x73,
++	0x05, 0xD9, 0x5C, 0xF9, 0x82,
++	0x09, 0xBA, 0x52, 0x38, 0x98,
++	0x04, 0x07, 0x43, 0x09, 0xF8,
++	0x0C, 0xD6, 0xE1, 0x51, 0x71,
++	0x04, 0xFD, 0x92, 0x57, 0x76,
++	0x01, 0xE4, 0x56, 0x95, 0x83,
++	0x0B, 0xF5, 0x38, 0xEB, 0x1D,
++	0x0D, 0xF5, 0x21, 0xAD, 0x89,
++	0x09, 0xAC, 0xCA, 0x81, 0x79,
++	0x0E, 0xEE, 0x4A, 0x3A, 0x7B,
++	0x01, 0x44, 0x26, 0x70, 0x88,
++	0x0F, 0x43, 0x5C, 0x3F, 0xD6,
++	0x0B, 0xC5, 0xF5, 0xC2, 0x6B,
++	0x0F, 0xFA, 0xBD, 0xE2, 0xA4,
++	0x0D, 0xB5, 0x61, 0x31, 0x2A,
++	0x04, 0x47, 0x73, 0x95, 0x53,
++	0x01, 0x35, 0x42, 0x85, 0x5A,
++	0x00, 0xA5, 0x74, 0xE4, 0xD4,
++	0x04, 0x06, 0x32, 0x83, 0x58,
++	0x04, 0xB1, 0x9B, 0x59, 0xD7,
++	0x02, 0x84, 0xA1, 0x36, 0x3D,
++	0x03, 0x55, 0x51, 0x55, 0xDD,
++	0x00, 0x0F, 0x74, 0x9E, 0x83,
++	0x02, 0x8E, 0x85, 0x7B, 0x66,
++	0x0B, 0x7A, 0x1F, 0xC1, 0xDD,
++	0x07, 0x9A, 0x64, 0xA7, 0x5B,
++	0x03, 0xE6, 0xC5, 0x44, 0x27,
++	0x01, 0x61, 0x1F, 0xAC, 0x95,
++	0x00, 0x25, 0xCA, 0xC3, 0x4F,
++	0x02, 0x41, 0xEA, 0xD3, 0xC0,
++	0x05, 0x6F, 0x89, 0xA9, 0xAF,
++	0x00, 0x65, 0x7C, 0x1F, 0xE9,
++	0x0F, 0xAC, 0xB4, 0x47, 0xE4,
++	0x0A, 0xB6, 0xBC, 0x16, 0x84,
++	0x06, 0x04, 0x0B, 0xCB, 0x83,
++	0x07, 0x6A, 0xB8, 0x79, 0x26,
++	0x05, 0xC2, 0x76, 0xCD, 0x39,
++	0x0C, 0xCF, 0x83, 0xDF, 0x25,
++	0x0E, 0x0B, 0xAE, 0xD1, 0xE3,
++	0x01, 0x89, 0xB1, 0xC6, 0xD0,
++	0x0F, 0x45, 0x9C, 0x21, 0x18,
++	0x02, 0x55, 0x86, 0xB4, 0xD2,
++	0x06, 0x15, 0xA7, 0xAC, 0xAA,
++	0x03, 0x91, 0xB3, 0x30, 0x21,
++	0x06, 0x34, 0xBB, 0xA2, 0xFD,
++	0x05, 0x67, 0x8F, 0xBA, 0x36,
++	0x05, 0xD8, 0xAD, 0x7D, 0x54,
++	0x01, 0xD6, 0x71, 0xF0, 0x39,
++	0x02, 0x7A, 0xEA, 0x2A, 0x77,
++	0x0E, 0x6F, 0xA3, 0x1E, 0xE4,
++	0x03, 0x05, 0xDE, 0x2E, 0x56,
++	0x0E, 0x9A, 0x59, 0x8F, 0xA8,
++	0x05, 0x23, 0x8D, 0xA7, 0x0D,
++	0x03, 0x02, 0x17, 0xBC, 0x59,
++	0x07, 0x0A, 0x13, 0xF9, 0x10,
++	0x07, 0x47, 0xE3, 0xA5, 0xBA,
++	0x0A, 0xA6, 0x40, 0x71, 0xAC,
++	0x00, 0xE7, 0xA5, 0x83, 0x72,
++	0x04, 0x9C, 0xA5, 0x9A, 0xDB,
++	0x00, 0x5A, 0xFA, 0x88, 0x14,
++	0x0F, 0x2E, 0xE4, 0x53, 0xA4,
++	0x07, 0xD4, 0x44, 0x57, 0x8B,
++	0x09, 0x34, 0x3B, 0xC3, 0x7E,
++	0x0F, 0x7C, 0xDC, 0xC8, 0x25,
++	0x0B, 0x46, 0x1F, 0x36, 0x2A,
++	0x0B, 0x19, 0xB7, 0x13, 0x23,
++	0x0C, 0x8C, 0x5B, 0xB9, 0x65,
++	0x0B, 0xD3, 0x72, 0x3E, 0x54,
++	0x0F, 0xB2, 0x4B, 0x72, 0xC9,
++	0x07, 0x42, 0x36, 0xA4, 0x17,
++	0x02, 0x8B, 0x3D, 0xA5, 0xA6,
++	0x05, 0x6B, 0xEE, 0x37, 0x60,
++	0x09, 0xF2, 0xAA, 0x69, 0x6B,
++	0x01, 0xC5, 0x47, 0x49, 0xDD,
++	0x04, 0x90, 0x8E, 0x57, 0x81,
++	0x04, 0x77, 0xDE, 0xBC, 0x26,
++	0x04, 0xB9, 0x95, 0xCA, 0x4F,
++	0x04, 0xBC, 0xA3, 0x54, 0x8E,
++	0x0A, 0xAE, 0x07, 0x62, 0x1C,
++	0x04, 0xC2, 0xFC, 0x2C, 0x3E,
++	0x06, 0xE4, 0x52, 0xA1, 0x0B,
++	0x0D, 0x94, 0xF8, 0x9A, 0x59,
++	0x0A, 0xC7, 0x61, 0xA5, 0xED,
++	0x06, 0x3A, 0xCB, 0x3C, 0x49,
++	0x00, 0x6B, 0x6E, 0xCD, 0x59,
++	0x02, 0x21, 0xF1, 0xBE, 0x3B,
++	0x08, 0xCC, 0xB4, 0xD7, 0x91,
++	0x0B, 0x9D, 0x1D, 0xEC, 0xD4,
++	0x0F, 0x0F, 0xF8, 0x3D, 0xC3,
++	0x03, 0x20, 0x94, 0x6B, 0x14,
++	0x0C, 0xD8, 0xAB, 0x1A, 0x27,
++	0x00, 0x4E, 0xA4, 0x02, 0x24,
++	0x08, 0xE0, 0x78, 0x6F, 0x7B,
++	0x04, 0xA1, 0x1A, 0x7E, 0xFE,
++	0x01, 0xF9, 0x5F, 0xB3, 0x39,
++	0x00, 0xA3, 0x42, 0xFA, 0x15,
++	0x09, 0x96, 0x68, 0xFB, 0x9A,
++	0x0A, 0xDD, 0x62, 0xD7, 0xEE,
++	0x0B, 0x26, 0xFC, 0x77, 0x03,
++	0x01, 0x25, 0xCE, 0xA2, 0x76,
++	0x04, 0x5E, 0x99, 0xA1, 0xE9,
++	0x03, 0xF0, 0x09, 0x22, 0xDE,
++	0x0D, 0x29, 0xD0, 0xBC, 0xC0,
++	0x0D, 0x53, 0x18, 0xDA, 0x82,
++	0x04, 0x88, 0x54, 0x23, 0x32,
++	0x01, 0x33, 0x5B, 0x97, 0x25,
++	0x0E, 0xB4, 0x7D, 0x92, 0x6C,
++	0x0E, 0x5A, 0x66, 0x03, 0x2B,
++	0x0A, 0x95, 0x14, 0x58, 0xEF,
++	0x00, 0xF2, 0xD7, 0x41, 0xA8,
++	0x00, 0x84, 0x73, 0xAA, 0x81,
++	0x06, 0xF0, 0x8E, 0x07, 0x3E,
++	0x03, 0x5F, 0xE4, 0x86, 0x75,
++	0x06, 0x32, 0x9F, 0xBC, 0x3F,
++	0x0C, 0xF7, 0xC5, 0x8C, 0x8C,
++	0x0F, 0xB4, 0x79, 0xB3, 0x5A,
++	0x08, 0x73, 0x55, 0x71, 0x08,
++	0x0C, 0x08, 0x42, 0x13, 0xAF,
++	0x0D, 0xBD, 0x37, 0x22, 0xBE,
++	0x01, 0xFB, 0xA4, 0xB7, 0xE4,
++	0x0F, 0x4D, 0xE0, 0xB2, 0x8D,
++	0x0F, 0xE8, 0xB1, 0xD8, 0x1D,
++	0x08, 0x6C, 0xBA, 0x58, 0x73,
++	0x07, 0x5D, 0x35, 0x02, 0xAC,
++	0x0D, 0xDC, 0x8E, 0x74, 0x9E,
++	0x01, 0x08, 0xEA, 0x61, 0x7B,
++	0x06, 0x87, 0x78, 0x71, 0x85,
++	0x04, 0x09, 0xA0, 0x07, 0xA2,
++	0x04, 0xF1, 0x86, 0xC5, 0x7D,
++	0x0F, 0x69, 0x82, 0x62, 0x16,
++	0x0C, 0x8C, 0x1E, 0x6A, 0xFB,
++	0x06, 0x6E, 0x08, 0x0A, 0xEA,
++	0x0D, 0xCA, 0xDE, 0xC9, 0xA9,
++	0x04, 0x0D, 0x05, 0x1A, 0x6B,
++	0x0D, 0x63, 0x3D, 0xB3, 0xFF,
++	0x04, 0x96, 0x56, 0xE1, 0xD6,
++	0x0E, 0xAA, 0x05, 0x26, 0xCF,
++	0x03, 0x9F, 0x38, 0xB0, 0x30,
++	0x0E, 0x19, 0x53, 0x76, 0xF5,
++	0x07, 0x60, 0x1F, 0x8E, 0x1F,
++	0x0C, 0xB1, 0xD8, 0xCE, 0xD1,
++	0x0B, 0xCC, 0xEA, 0x91, 0xF4,
++	0x09, 0xC3, 0x3E, 0x00, 0x12,
++	0x08, 0x4E, 0x55, 0x8A, 0x70,
++	0x07, 0x08, 0x40, 0x2B, 0x29,
++	0x0E, 0xDE, 0x73, 0x53, 0x02,
++	0x04, 0xC2, 0x0E, 0x3F, 0x91,
++	0x07, 0x59, 0x67, 0x83, 0x3E,
++	0x06, 0xEF, 0x8D, 0xA1, 0xB8,
++	0x08, 0x0A, 0xC7, 0xD7, 0x6D,
++	0x05, 0xD2, 0xF7, 0x2A, 0x2D,
++	0x0B, 0x05, 0x4F, 0x9A, 0xDD,
++	0x09, 0x76, 0xA7, 0xBE, 0xEE,
++	0x0C, 0x02, 0x1E, 0x21, 0x4F,
++	0x03, 0x1C, 0xA3, 0x8F, 0x2B,
++	0x01, 0x99, 0x02, 0x40, 0xB0,
++	0x00, 0xAC, 0xF7, 0xA9, 0x8C,
++	0x08, 0x2E, 0xAF, 0x99, 0x13,
++	0x03, 0x26, 0xE6, 0x20, 0x06,
++	0x08, 0x69, 0x44, 0x85, 0xB6,
++	0x0E, 0xCF, 0x53, 0xB4, 0x23,
++	0x0B, 0xB0, 0x5A, 0xFC, 0x9B,
++	0x0F, 0x2C, 0xD5, 0x66, 0x07,
++	0x08, 0xF5, 0x99, 0x48, 0x53,
++	0x07, 0xD3, 0x0E, 0xBB, 0xF5,
++	0x02, 0x0F, 0x2F, 0x9C, 0xF0,
++	0x09, 0x3A, 0x47, 0x9F, 0x0F,
++	0x01, 0xC5, 0x7F, 0x57, 0x13,
++	0x0D, 0x01, 0xE4, 0x61, 0x0B,
++	0x0A, 0x18, 0x33, 0x72, 0x1B,
++	0x0A, 0x9F, 0x32, 0x4B, 0x49,
++	0x01, 0x4C, 0x8D, 0x63, 0x11,
++	0x09, 0x7C, 0x03, 0x9D, 0x65,
++	0x02, 0x3E, 0xD3, 0xF5, 0x8F,
++	0x0C, 0xB5, 0xB8, 0x50, 0x10,
++	0x05, 0xDF, 0x08, 0x67, 0x49,
++	0x07, 0xA9, 0xF0, 0xCE, 0x25,
++	0x0A, 0x6B, 0x97, 0x87, 0xCF,
++	0x05, 0x7A, 0x31, 0x10, 0x4A,
++	0x0A, 0x8F, 0x73, 0x6C, 0x6D,
++	0x05, 0xB4, 0x10, 0xA6, 0x22,
++	0x0D, 0x0A, 0xA2, 0x72, 0x9F,
++	0x0C, 0x24, 0x6C, 0xD0, 0xAD,
++	0x03, 0x66, 0xF6, 0xFC, 0xA8,
++	0x05, 0x88, 0xBC, 0x91, 0x96,
++	0x0D, 0x16, 0x3A, 0xC7, 0xB8,
++	0x06, 0x52, 0x3E, 0xE2, 0x04,
++	0x07, 0xE9, 0xC0, 0x52, 0x88,
++	0x07, 0x82, 0x2E, 0x93, 0xE2,
++	0x0D, 0x21, 0xBC, 0x6F, 0x54,
++	0x09, 0x7F, 0xEF, 0xF5, 0xFD,
++	0x01, 0x73, 0x20, 0x99, 0xE9,
++	0x05, 0xFF, 0x09, 0x24, 0x59,
++	0x01, 0x58, 0x2C, 0x44, 0x30,
++	0x0D, 0x83, 0x1F, 0x18, 0x5C,
++	0x0D, 0xC8, 0xA1, 0x56, 0xFA,
++	0x02, 0xAF, 0xAC, 0xB9, 0xF6,
++	0x0D, 0x8E, 0x43, 0x4B, 0xC8,
++	0x00, 0x7D, 0xAC, 0xF8, 0xC8,
++	0x00, 0xD6, 0xDD, 0x8E, 0x53,
++	0x0E, 0xC2, 0xF0, 0xF5, 0xB2,
++	0x0F, 0x95, 0x1D, 0x2E, 0x90,
++	0x0F, 0x30, 0x24, 0x19, 0x92,
++	0x02, 0x1F, 0xD0, 0xFB, 0xDA,
++	0x06, 0x41, 0x29, 0xD6, 0xB9,
++	0x02, 0x32, 0xBC, 0x34, 0x1E,
++	0x04, 0x98, 0x05, 0x84, 0x2A,
++	0x09, 0xCA, 0xB2, 0xDE, 0x9B,
++	0x01, 0x42, 0xB4, 0x7D, 0x92,
++	0x03, 0xFA, 0xE8, 0x64, 0x83,
++	0x01, 0x4F, 0x17, 0xF6, 0xD8,
++	0x07, 0x2B, 0x0B, 0xB7, 0x72,
++	0x01, 0xBD, 0x7D, 0x6F, 0x9E,
++	0x0D, 0x4A, 0xFE, 0xEE, 0x32,
++	0x06, 0x4F, 0x1D, 0x04, 0xB1,
++	0x0C, 0xBD, 0xF4, 0x83, 0x84,
++	0x04, 0x64, 0x81, 0xC3, 0xF5,
++	0x0E, 0x51, 0xB4, 0x79, 0xC2,
++	0x0E, 0xAC, 0x4B, 0x35, 0x43,
++	0x0D, 0x10, 0x45, 0x46, 0x27,
++	0x09, 0x66, 0x84, 0xB7, 0x17,
++	0x09, 0x69, 0xD9, 0x24, 0x8F,
++	0x08, 0xD4, 0x41, 0x86, 0x3B,
++	0x0D, 0x2F, 0xEA, 0xB1, 0xD6,
++	0x09, 0xE3, 0xEE, 0x03, 0x5B,
++	0x06, 0x0B, 0x5D, 0x57, 0xB5,
++	0x0E, 0x61, 0x10, 0x0C, 0xCD,
++	0x02, 0xBA, 0xC4, 0x0C, 0xD5,
++	0x07, 0x6E, 0xBD, 0xF8, 0x49,
++	0x0D, 0xEF, 0xCB, 0xD9, 0x33,
++	0x0B, 0x68, 0xA0, 0x26, 0xFD,
++	0x03, 0x61, 0x0E, 0xEE, 0x21,
++	0x0C, 0x12, 0x6C, 0x27, 0x1B,
++	0x0F, 0x7D, 0x57, 0xC5, 0x3F,
++	0x0F, 0xF2, 0x29, 0x6F, 0xFF,
++	0x02, 0x1D, 0x0B, 0x65, 0x1A,
++	0x03, 0xD1, 0xED, 0xEC, 0x84,
++	0x0B, 0xDD, 0x59, 0x76, 0xD4,
++	0x0D, 0x3D, 0x98, 0x05, 0x2B,
++	0x07, 0xBC, 0x7C, 0xE9, 0x0B,
++	0x09, 0x15, 0xE3, 0x82, 0xC5,
++	0x01, 0x0E, 0x70, 0xFF, 0xB4,
++	0x0F, 0x17, 0x32, 0x04, 0xCA,
++	0x0A, 0x65, 0x98, 0x06, 0x54,
++	0x0A, 0xD2, 0xFD, 0x44, 0x74,
++	0x0D, 0x1F, 0x37, 0x95, 0xB3,
++	0x08, 0xD4, 0xB0, 0x95, 0x91,
++	0x00, 0x92, 0x9F, 0xD3, 0x64,
++	0x0C, 0x18, 0xFD, 0xB4, 0x87,
++	0x09, 0x42, 0x4F, 0x67, 0x8F,
++	0x06, 0x0D, 0xE0, 0x58, 0x24,
++	0x0D, 0x54, 0x08, 0x57, 0xE6,
++	0x08, 0x31, 0x52, 0x74, 0xAA,
++	0x0C, 0x3A, 0x07, 0xEF, 0x1A,
++	0x01, 0xE1, 0xB2, 0x07, 0x8C,
++	0x02, 0x63, 0xE8, 0xDD, 0x90,
++	0x03, 0x9F, 0x75, 0x23, 0xBB,
++	0x07, 0x89, 0x98, 0x80, 0x75,
++	0x0C, 0x9C, 0x89, 0x0D, 0xD1,
++	0x02, 0x91, 0x07, 0xC9, 0xE0,
++	0x09, 0xBF, 0x36, 0xA6, 0x5A,
++	0x0D, 0x97, 0x09, 0x7F, 0x77,
++	0x02, 0xB6, 0xAF, 0x1F, 0x47,
++	0x01, 0x5A, 0x73, 0x5A, 0xFA,
++	0x02, 0x15, 0x38, 0x2E, 0xE1,
++	0x03, 0xA4, 0xF7, 0xD4, 0x48,
++	0x07, 0x0B, 0xD9, 0x34, 0x31,
++	0x08, 0x7F, 0xCC, 0x7C, 0x5C,
++	0x04, 0x25, 0x2B, 0x47, 0xAD,
++	0x0D, 0xAB, 0x84, 0x17, 0xE4,
++	0x0F, 0x01, 0x00, 0x84, 0x67,
++	0x05, 0x56, 0x9B, 0xD3, 0x45,
++	0x04, 0x66, 0x9F, 0xB2, 0x79,
++	0x02, 0x4D, 0x5C, 0xC0, 0x67,
++	0x04, 0xD2, 0xAE, 0x8B, 0x18,
++	0x0E, 0x1F, 0xE2, 0xE8, 0x35,
++	0x0B, 0x60, 0xB5, 0xB5, 0x5E,
++	0x05, 0x5E, 0x5D, 0x80, 0xDF,
++	0x05, 0xEB, 0xB8, 0x90, 0xF7,
++	0x0B, 0xB6, 0x6C, 0x77, 0xBD,
++	0x00, 0x1E, 0xF8, 0xB9, 0xAB,
++	0x02, 0x76, 0x0F, 0x3E, 0x6C,
++	0x0F, 0x0F, 0xD0, 0x2E, 0x26,
++	0x02, 0x01, 0x08, 0xCC, 0x36,
++	0x07, 0xB5, 0x9F, 0xE7, 0x55,
++	0x01, 0x3E, 0xE4, 0x16, 0xE1,
++	0x02, 0x99, 0x00, 0xCA, 0x51,
++	0x0D, 0xF3, 0x96, 0x3A, 0x0B,
++	0x00, 0x7C, 0x67, 0xAB, 0x56,
++	0x0A, 0xED, 0xFE, 0x24, 0x69,
++	0x00, 0xBB, 0x01, 0xCE, 0xA4,
++	0x0B, 0x61, 0x21, 0x9C, 0x1D,
++	0x00, 0xD8, 0x2F, 0x0F, 0xFC,
++	0x01, 0xF8, 0x73, 0x20, 0x91,
++	0x06, 0x9F, 0xA0, 0xD8, 0xA9,
++	0x00, 0x67, 0x4C, 0x4C, 0x40,
++	0x0E, 0x1B, 0xD4, 0xE5, 0x5D,
++	0x04, 0xCC, 0x14, 0xA1, 0x5A,
++	0x02, 0xC9, 0x2D, 0xB9, 0x3B,
++	0x0F, 0x01, 0x8C, 0xE3, 0x73,
++	0x06, 0x24, 0xB5, 0x96, 0x41,
++	0x07, 0xA0, 0xD2, 0xDD, 0xB8,
++	0x0B, 0xD5, 0x40, 0xA5, 0x42,
++	0x0F, 0x03, 0x1D, 0x27, 0xAE,
++	0x09, 0xC2, 0xDE, 0xDE, 0xD9,
++	0x0D, 0xD4, 0x0F, 0xF0, 0x42,
++	0x0A, 0xE6, 0xC1, 0x29, 0xDA,
++	0x07, 0x78, 0x57, 0xD2, 0x38,
++	0x06, 0xB9, 0x18, 0x08, 0x19,
++	0x0B, 0x09, 0x4A, 0xBC, 0xDE,
++	0x03, 0xB7, 0xC2, 0xB4, 0x3D,
++	0x0E, 0x5A, 0x32, 0xEA, 0x5E,
++	0x08, 0x9F, 0x52, 0x13, 0xCF,
++	0x04, 0xEA, 0xAC, 0xF1, 0xEA,
++	0x0D, 0xAD, 0xAB, 0x05, 0x9B,
++	0x06, 0x8B, 0x5A, 0xF2, 0xDB,
++	0x0B, 0x3B, 0x2F, 0x5D, 0x72,
++	0x0A, 0x70, 0x3D, 0xB3, 0x74,
++	0x00, 0x3E, 0x29, 0xB7, 0xFD,
++	0x00, 0x82, 0xBB, 0xB4, 0x40,
++	0x08, 0xE4, 0x64, 0x71, 0x4E,
++	0x0D, 0x31, 0x00, 0x08, 0x42,
++	0x08, 0x17, 0x58, 0xBE, 0x32,
++	0x0E, 0x85, 0x69, 0xBB, 0x2A,
++	0x0B, 0xE4, 0x54, 0xCC, 0x31,
++	0x0E, 0x8D, 0x2F, 0xA8, 0x89,
++	0x0A, 0x59, 0xF3, 0xEE, 0xBA,
++	0x07, 0x76, 0x0F, 0x5F, 0x6F,
++	0x0E, 0x95, 0xE5, 0xDC, 0x35,
++	0x0C, 0x9E, 0x3A, 0x85, 0x0C,
++	0x0A, 0xFA, 0x80, 0x07, 0x78,
++	0x03, 0xC9, 0x2F, 0x8B, 0xA0,
++	0x0C, 0xA7, 0xE8, 0xFF, 0xE6,
++	0x0E, 0xC9, 0x05, 0xEA, 0xE2,
++	0x0E, 0x2A, 0x00, 0x8C, 0x1E,
++	0x02, 0xC3, 0xFA, 0x62, 0x45,
++	0x01, 0x52, 0x10, 0xC9, 0x6F,
++	0x05, 0xA9, 0x18, 0x0C, 0x52,
++	0x06, 0x5F, 0xC1, 0x63, 0xA8,
++	0x0F, 0xC7, 0x8D, 0x06, 0xB3,
++	0x07, 0x97, 0x62, 0xAA, 0x37,
++	0x07, 0xC3, 0x78, 0x1C, 0xED,
++	0x01, 0x7C, 0x12, 0x19, 0xC7,
++	0x0D, 0x4C, 0xD2, 0xF0, 0xCD,
++	0x0F, 0xD5, 0x07, 0x32, 0x0D,
++	0x02, 0xDB, 0xB7, 0xCD, 0x8F,
++	0x0A, 0x47, 0x09, 0xC4, 0xF6,
++	0x0C, 0x21, 0x18, 0x4E, 0x6A,
++	0x09, 0x74, 0xDC, 0x8A, 0x15,
++	0x0B, 0xFC, 0x92, 0xDF, 0x95,
++	0x0F, 0x30, 0x18, 0xCA, 0x33,
++	0x03, 0xA2, 0x57, 0x59, 0x63,
++	0x03, 0xBA, 0x9D, 0x2D, 0xDD,
++	0x06, 0xFC, 0x9A, 0x8A, 0x57,
++	0x0B, 0x79, 0x79, 0xD2, 0x7E,
++	0x06, 0x25, 0xD3, 0xC5, 0xE8,
++	0x01, 0x9C, 0x2F, 0x7F, 0x07,
++	0x02, 0x24, 0xF4, 0x12, 0x99,
++	0x0F, 0xCD, 0x7B, 0x55, 0x26,
++	0x06, 0x2A, 0x47, 0x08, 0x80,
++	0x0E, 0x31, 0x1C, 0x2B, 0x10,
++	0x01, 0xB9, 0x94, 0x27, 0x4F,
++	0x01, 0x23, 0x3F, 0x26, 0x66,
++	0x0A, 0x30, 0x56, 0x69, 0x5F,
++	0x05, 0x8E, 0xB0, 0xCF, 0x1B,
++	0x0C, 0x52, 0x58, 0x3C, 0x5A,
++	0x02, 0xAE, 0x96, 0xAD, 0xAE,
++	0x0A, 0x72, 0x66, 0xF5, 0x94,
++	0x04, 0x67, 0x0B, 0xDB, 0x32,
++	0x01, 0x03, 0x5E, 0x8C, 0x02,
++	0x0C, 0xC8, 0x25, 0x2B, 0x45,
++	0x03, 0x36, 0xFA, 0x47, 0x1F,
++	0x0D, 0xD3, 0xB1, 0x83, 0x05,
++	0x01, 0x39, 0x56, 0x0B, 0xD1,
++	0x02, 0x28, 0x54, 0x9F, 0xB2,
++	0x0B, 0x7E, 0x4F, 0x40, 0xCA,
++	0x0F, 0x28, 0xD2, 0xFE, 0xB5,
++	0x02, 0xE5, 0x9E, 0x3E, 0xE8,
++	0x05, 0xB7, 0x60, 0xB9, 0x71,
++	0x00, 0x29, 0x5E, 0x51, 0x05,
++	0x0D, 0xA9, 0xF6, 0xAB, 0x0A,
++	0x0E, 0x17, 0xB6, 0x78, 0x77,
++	0x07, 0xFC, 0x1E, 0xE8, 0xB9,
++	0x00, 0x4A, 0x76, 0x9F, 0x8F,
++	0x0C, 0x54, 0x8E, 0x26, 0x1C,
++	0x06, 0x22, 0x01, 0x18, 0x71,
++	0x02, 0xAC, 0x37, 0xB6, 0x50,
++	0x00, 0xAD, 0x3F, 0x74, 0x23,
++	0x0C, 0x9A, 0x99, 0xA0, 0x70,
++	0x01, 0xA5, 0xFD, 0x16, 0x8D,
++	0x0B, 0x3C, 0x7D, 0xD0, 0xD3,
++	0x0E, 0xC1, 0x6B, 0xF6, 0xE2,
++	0x02, 0xBC, 0xBB, 0x9D, 0x4C,
++	0x03, 0xD7, 0x51, 0x3D, 0x5E,
++	0x0F, 0x6C, 0xD0, 0xF2, 0x0D,
++	0x08, 0x3D, 0xF1, 0x6E, 0x62,
++	0x04, 0xED, 0x1E, 0x61, 0x5A,
++	0x09, 0x1C, 0x6D, 0x41, 0x8E,
++	0x04, 0x02, 0x11, 0xAA, 0xE7,
++	0x06, 0xEF, 0x80, 0xC8, 0xA1,
++	0x01, 0x7E, 0xC9, 0x2D, 0xF9,
++	0x09, 0x0C, 0x81, 0x8C, 0xB0,
++	0x07, 0xFA, 0x6C, 0x75, 0x82,
++	0x02, 0x3B, 0x80, 0xD5, 0x6B,
++	0x02, 0xD7, 0xD5, 0x50, 0xA5,
++	0x09, 0x77, 0x03, 0x8D, 0x27,
++	0x06, 0xA2, 0xC3, 0x28, 0xDE,
++	0x01, 0x21, 0x7E, 0x5F, 0x70,
++	0x02, 0xE2, 0x26, 0x71, 0xA9,
++	0x03, 0xBC, 0x19, 0x81, 0xD2,
++	0x01, 0x5B, 0x58, 0xA8, 0x08,
++	0x0D, 0x22, 0xC9, 0x9A, 0x30,
++	0x06, 0x1A, 0x31, 0x52, 0x34,
++	0x05, 0x93, 0xDB, 0xE2, 0xEA,
++	0x06, 0x03, 0x19, 0x56, 0x26,
++	0x04, 0x58, 0xEB, 0x7C, 0x43,
++	0x07, 0x41, 0xAD, 0x8B, 0xB6,
++	0x0F, 0xAA, 0x81, 0x7A, 0x46,
++	0x0E, 0x07, 0x3A, 0x7F, 0x5D,
++	0x04, 0x86, 0x70, 0xA1, 0xF1,
++	0x03, 0xBC, 0x3F, 0xFC, 0x75,
++	0x05, 0xCC, 0x82, 0x4F, 0x76,
++	0x09, 0xF3, 0x62, 0x89, 0x73,
++	0x05, 0x71, 0x31, 0x04, 0x0A,
++	0x06, 0x13, 0x95, 0x75, 0xFF,
++	0x07, 0x22, 0x85, 0x7D, 0x79,
++	0x04, 0xB7, 0xE4, 0xF0, 0x0E,
++	0x0D, 0x32, 0x8D, 0x2F, 0xE8,
++	0x0D, 0xD7, 0x66, 0x23, 0xED,
++	0x0F, 0x5A, 0x76, 0x0B, 0x5C,
++	0x0D, 0x02, 0x15, 0xE5, 0x9C,
++	0x06, 0xF4, 0x3E, 0xBA, 0xC9,
++	0x05, 0x61, 0x9B, 0x66, 0x87,
++	0x04, 0x7F, 0xC1, 0xAF, 0x9A,
++	0x05, 0x3B, 0x58, 0xA8, 0xE3,
++	0x06, 0xC5, 0x48, 0xEF, 0xFC,
++	0x0A, 0x61, 0x20, 0x34, 0x91,
++	0x0F, 0xA8, 0x6B, 0x4E, 0x30,
++	0x07, 0x0A, 0xDB, 0xD6, 0xC9,
++	0x0D, 0xC9, 0xA9, 0xA8, 0x8C,
++	0x04, 0x5A, 0x9F, 0xD1, 0x63,
++	0x0D, 0xF3, 0x07, 0xDD, 0x06,
++	0x0F, 0x6D, 0xF6, 0xB2, 0xAA,
++	0x05, 0x2B, 0xCB, 0x9E, 0x9E,
++	0x09, 0x3D, 0x75, 0x34, 0x9B,
++	0x0C, 0x76, 0x00, 0x0E, 0xF0,
++	0x06, 0x89, 0xBF, 0x1A, 0xF2,
++	0x03, 0x4F, 0x0F, 0x67, 0xC9,
++	0x01, 0x91, 0xC6, 0xD5, 0xC4,
++	0x08, 0x40, 0x21, 0x98, 0x5E,
++	0x09, 0x96, 0xF4, 0xDC, 0x86,
++	0x09, 0xA6, 0x12, 0x52, 0xC2,
++	0x0B, 0x53, 0xB0, 0x1C, 0xD5,
++	0x0E, 0xBE, 0x48, 0xC7, 0x19,
++	0x0B, 0x8F, 0xBA, 0x0D, 0x61,
++	0x03, 0xAF, 0x7F, 0xD4, 0x0A,
++	0x07, 0x97, 0x70, 0x37, 0xDF,
++	0x03, 0x68, 0xC4, 0x33, 0x85,
++	0x05, 0x90, 0x7D, 0xEC, 0x3F,
++	0x0D, 0xBF, 0xD1, 0xE4, 0x1A,
++	0x05, 0x23, 0x6F, 0x96, 0xD5,
++	0x0B, 0x0F, 0x8B, 0x8C, 0x7A,
++	0x09, 0xC3, 0xD0, 0x92, 0xEB,
++	0x05, 0x68, 0x19, 0x1A, 0x6B,
++	0x0F, 0xD9, 0x25, 0xBA, 0xE2,
++	0x0A, 0x61, 0xCF, 0x54, 0x74,
++	0x0F, 0x45, 0x8E, 0xB7, 0x8A,
++	0x0F, 0x74, 0x1A, 0xFB, 0xB9,
++	0x02, 0xF2, 0x28, 0x14, 0x2F,
++	0x07, 0x6D, 0x93, 0x84, 0x75,
++	0x0C, 0x41, 0xE7, 0x0B, 0x5B,
++	0x0D, 0xB2, 0x23, 0xDE, 0x8F,
++	0x04, 0xD4, 0x68, 0x25, 0xBB,
++	0x0E, 0x97, 0xF6, 0x1A, 0xC7,
++	0x03, 0xDD, 0x33, 0x21, 0x80,
++	0x0D, 0x68, 0xFB, 0x76, 0x9B,
++	0x03, 0x72, 0x28, 0x60, 0x95,
++	0x0A, 0x4B, 0xEE, 0x7D, 0x8C,
++	0x0A, 0x62, 0xDE, 0x52, 0xDE,
++	0x0A, 0x18, 0xA5, 0x9E, 0x3E,
++	0x09, 0xB0, 0x57, 0x60, 0xB5,
++	0x0D, 0x50, 0xA1, 0x5C, 0xDD,
++	0x02, 0xE7, 0x49, 0xED, 0x28,
++	0x02, 0xCE, 0x17, 0x30, 0xA8,
++	0x04, 0x86, 0x7C, 0x98, 0x72,
++	0x0A, 0x11, 0xE2, 0x70, 0x45,
++	0x0F, 0xED, 0xB7, 0x0E, 0x36,
++	0x0F, 0x24, 0x6A, 0x81, 0x08,
++	0x02, 0x72, 0xAC, 0x37, 0xA6,
++	0x04, 0xD5, 0x06, 0xBF, 0x64,
++	0x06, 0xFE, 0x98, 0x99, 0x80,
++	0x06, 0xD0, 0x05, 0xFD, 0x16,
++	0x0A, 0xCA, 0xBC, 0x6B, 0x52,
++	0x0B, 0xEF, 0x61, 0x6D, 0x28,
++	0x09, 0xD0, 0x48, 0x97, 0x01,
++	0x0E, 0x93, 0xC7, 0x47, 0x23,
++	0x0C, 0x2F, 0x6C, 0xF6, 0xAD,
++	0x01, 0x78, 0xF0, 0xF1, 0x73,
++	0x0A, 0x95, 0x06, 0x1E, 0x7D,
++	0x04, 0xA8, 0xE2, 0xAD, 0x41,
++	0x0C, 0x44, 0x02, 0x11, 0x84,
++	0x0D, 0x58, 0xEF, 0x4D, 0x08,
++	0x0B, 0x58, 0x7C, 0xC9, 0x0D,
++	0x02, 0xB7, 0x31, 0x81, 0x8C,
++	0x08, 0x4B, 0xFA, 0x2C, 0x75,
++	0x0A, 0x78, 0xFB, 0x20, 0xE3,
++	0x04, 0x82, 0x17, 0xD5, 0x40,
++	0x0D, 0xF9, 0xD7, 0x03, 0x9D,
++	0x0D, 0xAC, 0xA7, 0x43, 0x39,
++	0x06, 0x58, 0x01, 0xD3, 0x5F,
++	0x08, 0x69, 0xC2, 0xEB, 0x81,
++	0x03, 0xD8, 0x28, 0x79, 0xB9,
++	0x0A, 0x3A, 0xFA, 0xBD, 0x18,
++	0x02, 0x06, 0x2E, 0x09, 0xC2,
++	0x08, 0xDE, 0x1B, 0x9F, 0x02,
++	0x0D, 0x34, 0x12, 0x5E, 0xB2,
++	0x02, 0x2F, 0x83, 0x1C, 0xC6,
++	0x07, 0xF4, 0x58, 0xEE, 0xE8,
++	0x0A, 0x75, 0x72, 0x28, 0xBE,
++	0x0D, 0xA7, 0x2A, 0x8C, 0x8A,
++	0x0A, 0xEF, 0x87, 0x37, 0x0F,
++	0x05, 0x45, 0x06, 0x7E, 0xFD,
++	0x0A, 0x8A, 0x3C, 0x3A, 0xA0,
++	0x0F, 0x8C, 0x4C, 0x87, 0xD3,
++	0x04, 0x79, 0xF3, 0x67, 0x60,
++	0x0A, 0x37, 0x42, 0xB4, 0x15,
++	0x00, 0x46, 0x93, 0x9B, 0x21,
++	0x04, 0xBE, 0xA2, 0x88, 0xA9,
++	0x03, 0x25, 0x37, 0xE9, 0x94,
++	0x05, 0xCF, 0xD2, 0x88, 0x6F,
++	0x00, 0xF8, 0x56, 0x5C, 0x63,
++	0x0E, 0x83, 0x5B, 0x73, 0xCF,
++	0x04, 0xD7, 0x31, 0x10, 0xE0,
++	0x05, 0x96, 0x94, 0x93, 0x7A,
++	0x00, 0x0B, 0x81, 0x7E, 0xE6,
++	0x0F, 0x7A, 0x3F, 0xC4, 0x2F,
++	0x01, 0x9B, 0x17, 0x27, 0x60,
++	0x0A, 0x6E, 0x25, 0x4D, 0x23,
++	0x00, 0xE0, 0x73, 0x20, 0x11,
++	0x02, 0xA7, 0xE7, 0xC3, 0x7A,
++	0x04, 0x47, 0x0E, 0x53, 0xF7,
++	0x09, 0x6F, 0xC9, 0xA7, 0xDC,
++	0x00, 0x65, 0x1A, 0xDF, 0xE4,
++	0x0A, 0xBC, 0x73, 0xCA, 0x1D,
++	0x0E, 0x36, 0x4C, 0x16, 0xBE,
++	0x0A, 0x05, 0x2B, 0xCF, 0x0E,
++	0x04, 0xEB, 0x1D, 0x7B, 0x92,
++	0x03, 0xC0, 0xC5, 0xCD, 0x06,
++	0x09, 0xFF, 0x43, 0xDF, 0x17,
++	0x0A, 0x0B, 0x0E, 0xDC, 0xA7,
++	0x07, 0x88, 0xA1, 0x46, 0xDD,
++	0x08, 0xC5, 0xBF, 0x21, 0x05,
++	0x0E, 0x55, 0x86, 0xF9, 0x43,
++	0x08, 0x15, 0xA7, 0xE9, 0x12,
++	0x06, 0x13, 0xB3, 0x30, 0x18,
++	0x0A, 0x4C, 0x3F, 0xAC, 0x10,
++	0x09, 0x67, 0x8F, 0xBA, 0x0D,
++	0x05, 0xF0, 0xAD, 0x78, 0x54,
++	0x0A, 0x57, 0x97, 0x70, 0x39,
++	0x02, 0x7A, 0xEA, 0x21, 0x3E,
++	0x0D, 0xA7, 0xFA, 0x10, 0x61,
++	0x05, 0x05, 0x91, 0xAE, 0x6C,
++	0x0E, 0x9C, 0x5C, 0xCF, 0x86,
++	0x05, 0x23, 0x8D, 0xAE, 0x56,
++	0x0A, 0x80, 0x42, 0x3D, 0xDC,
++	0x0B, 0x0D, 0xE9, 0xBC, 0xA7,
++	0x0B, 0x36, 0x19, 0x20, 0xCD,
++	0x0E, 0x27, 0xE0, 0x3C, 0xD4,
++	0x01, 0x7E, 0xC5, 0x80, 0xF2,
++	0x07, 0x9E, 0xD4, 0x14, 0x9B,
++	0x00, 0x5A, 0xFA, 0xAD, 0x10,
++	0x0F, 0x2E, 0xE0, 0x76, 0xE1,
++	0x05, 0xD4, 0x44, 0x42, 0xD4,
++	0x0B, 0x34, 0x2B, 0xD3, 0xF7,
++	0x06, 0x7C, 0x96, 0xF8, 0xA5,
++	0x09, 0x47, 0x9F, 0x86, 0xA0,
++	0x05, 0x1B, 0x54, 0xB3, 0x9B,
++	0x02, 0x84, 0xE9, 0x3B, 0xD6,
++	0x09, 0x53, 0xC2, 0x2A, 0xD6,
++	0x0F, 0xB0, 0x4B, 0x4E, 0x4D,
++	0x0C, 0x41, 0xC3, 0x18, 0xD2,
++	0x07, 0x0B, 0xFD, 0x65, 0x1E,
++	0x06, 0xEA, 0x75, 0x31, 0x6A,
++	0x0D, 0x77, 0x33, 0xAF, 0x14,
++	0x04, 0x41, 0x05, 0x4B, 0x6B,
++	0x01, 0x91, 0x0E, 0x35, 0x36,
++	0x08, 0x77, 0x87, 0xEA, 0x1C,
++	0x08, 0xB9, 0x90, 0x6C, 0x34,
++	0x0F, 0x3E, 0x6C, 0x42, 0x0C,
++	0x06, 0xAE, 0x26, 0x24, 0xC3,
++	0x00, 0x42, 0xD2, 0xA0, 0xB7,
++	0x0F, 0xE4, 0x90, 0xA1, 0xFF,
++	0x0D, 0x14, 0x1C, 0x9A, 0x59,
++	0x0E, 0x46, 0x9C, 0xA5, 0xFD,
++	0x0C, 0x38, 0xD5, 0x3C, 0x7C,
++	0x01, 0x69, 0xAE, 0xC1, 0x6B,
++	0x00, 0xA2, 0x4A, 0x3C, 0xBA,
++	0x09, 0x86, 0x13, 0xDA, 0x11,
++	0x08, 0x94, 0xEF, 0x61, 0x50,
++	0x0F, 0x0F, 0xF8, 0x38, 0xC4,
++	0x03, 0xA2, 0x34, 0xE8, 0xA8,
++	0x06, 0xDA, 0xBE, 0x1C, 0x6C,
++	0x07, 0x4C, 0x44, 0x02, 0x11,
++	0x04, 0xE5, 0x58, 0x7F, 0x4D,
++	0x08, 0xA1, 0x5A, 0x5E, 0xC9,
++	0x0D, 0xF9, 0x35, 0x23, 0xB0,
++	0x0C, 0xA3, 0x4B, 0xFA, 0x9E,
++	0x05, 0x96, 0x78, 0xFB, 0x13,
++	0x06, 0xDD, 0x82, 0xD7, 0x61,
++	0x00, 0xA5, 0x79, 0x42, 0xC7,
++	0x0D, 0x27, 0xAE, 0xBE, 0x01,
++	0x08, 0x5E, 0xD9, 0x8D, 0x5C,
++	0x0F, 0xF0, 0x7B, 0xFE, 0x24,
++	0x0A, 0x29, 0xDA, 0x31, 0xFB,
++	0x09, 0x52, 0xB8, 0xD9, 0xF8,
++	0x00, 0x8A, 0x04, 0x2F, 0x09,
++	0x06, 0xB0, 0xDE, 0x1B, 0x82,
++	0x02, 0xB4, 0xFD, 0x96, 0x5E,
++	0x08, 0xAA, 0x46, 0x07, 0x99,
++	0x06, 0x97, 0xF4, 0x18, 0xEB,
++	0x0C, 0xF1, 0xF7, 0x01, 0xAD,
++	0x03, 0x00, 0x2F, 0xEA, 0x01,
++	0x02, 0x77, 0x4E, 0x17, 0xBA,
++	0x06, 0x58, 0x84, 0xA6, 0xF0,
++	0x04, 0x36, 0xA3, 0xAC, 0xBF,
++	0x00, 0xF7, 0xC5, 0x8A, 0x80,
++	0x03, 0xB4, 0x79, 0xB5, 0x20,
++	0x04, 0x71, 0xB5, 0x37, 0xB3,
++	0x00, 0x08, 0x46, 0x35, 0x57,
++	0x0A, 0xBD, 0x37, 0x22, 0x85,
++	0x09, 0xFB, 0x24, 0xB1, 0xE7,
++	0x0C, 0xCC, 0x86, 0x32, 0x8D,
++	0x05, 0x28, 0xA9, 0xD2, 0xDC,
++	0x03, 0xA7, 0x07, 0xDB, 0x76,
++	0x0B, 0x16, 0xD1, 0x02, 0x95,
++	0x07, 0x95, 0x8E, 0xF4, 0xD4,
++	0x0A, 0xC0, 0x8C, 0xE1, 0x7B,
++	0x06, 0xCE, 0xF8, 0x7F, 0xC1,
++	0x04, 0x8B, 0x99, 0x04, 0xA7,
++	0x08, 0xF3, 0xE6, 0x45, 0x48,
++	0x0B, 0x6A, 0x62, 0xE4, 0x2A,
++	0x00, 0x8E, 0x27, 0x2A, 0xC3,
++	0x01, 0x6E, 0x45, 0x0A, 0xD3,
++	0x06, 0x49, 0x6F, 0x49, 0xA9,
++	0x08, 0x0C, 0x65, 0x1A, 0x5F,
++	0x01, 0x62, 0x2C, 0xB3, 0xC7,
++	0x0D, 0x06, 0xB6, 0xEC, 0x16,
++	0x0E, 0xAA, 0x05, 0x2B, 0xCB,
++	0x03, 0x1C, 0xE9, 0x3B, 0x7F,
++	0x02, 0x19, 0xC2, 0xF2, 0x50,
++	0x0E, 0xF0, 0xFF, 0x83, 0xDF,
++	0x0E, 0xB2, 0xE9, 0x4E, 0x11,
++	0x09, 0x4D, 0x47, 0x91, 0xC6,
++	0x05, 0xC4, 0xC4, 0x64, 0xBC,
++	0x08, 0x4E, 0x51, 0x86, 0xF4,
++	0x04, 0x8A, 0x95, 0xA7, 0x6C,
++	0x0A, 0xDD, 0x93, 0x53, 0xB0,
++	0x02, 0xC8, 0x64, 0xBF, 0xAA,
++	0x07, 0x59, 0x63, 0x8F, 0xBA,
++	0x0D, 0x6D, 0xD4, 0x2D, 0x7D,
++	0x06, 0x0A, 0x57, 0x91, 0x70,
++	0x01, 0xD2, 0xFA, 0xEA, 0xA4,
++	0x03, 0x84, 0x6D, 0x9A, 0x1D,
++	0x01, 0xFF, 0x07, 0xBE, 0x2E,
++	0x0D, 0x90, 0xFD, 0xAF, 0xCF,
++	0x0B, 0x15, 0x23, 0xAB, 0xA9,
++	0x03, 0x8A, 0xCC, 0x42, 0x20,
++	0x05, 0xAA, 0xCD, 0xE5, 0xF9,
++	0x0C, 0xA9, 0x6F, 0xD5, 0x25,
++	0x05, 0x24, 0xEC, 0xE0, 0x21,
++	0x0F, 0x69, 0x7F, 0x45, 0x8E,
++	0x02, 0xCF, 0x1F, 0x64, 0x1A,
++	0x0B, 0xB0, 0x5A, 0xC9, 0xD9,
++	0x02, 0xAF, 0x2E, 0xE0, 0xF3,
++	0x02, 0xF5, 0xD4, 0x48, 0xE7,
++	0x0B, 0xBB, 0xB4, 0x3B, 0xC3,
++	0x0E, 0xEF, 0xDC, 0x5C, 0xC8,
++	0x0C, 0xBB, 0xA7, 0x9F, 0x36,
++	0x0A, 0x47, 0x1B, 0x51, 0x20,
++	0x01, 0x00, 0x84, 0x67, 0x4B,
++	0x08, 0x9B, 0x1E, 0x72, 0x28,
++	0x06, 0x9F, 0xB2, 0x5B, 0x7E,
++	0x04, 0xCD, 0x20, 0x7F, 0x28,
++	0x04, 0xFE, 0x8B, 0x0D, 0xE5,
++	0x08, 0x3E, 0xE8, 0x25, 0x37,
++	0x06, 0xD5, 0x75, 0x40, 0xA9,
++	0x08, 0x3C, 0x40, 0xF7, 0xC9,
++	0x0D, 0x48, 0x30, 0xDE, 0x97,
++	0x00, 0x89, 0xD7, 0xA7, 0x7C,
++	0x09, 0x98, 0x79, 0x90, 0xCA,
++	0x01, 0xEE, 0xFE, 0x6C, 0xD4,
++	0x0E, 0x56, 0x2E, 0x30, 0x20,
++	0x01, 0x69, 0x42, 0x64, 0xEE,
++	0x07, 0xA6, 0xE4, 0x46, 0x2F,
++	0x06, 0x7E, 0xF6, 0xF1, 0x5A,
++	0x09, 0x80, 0xC6, 0x77, 0xA7,
++	0x07, 0x14, 0x60, 0xCB, 0x38,
++	0x0D, 0xD0, 0x6B, 0x42, 0x85,
++	0x0B, 0xEA, 0xA0, 0x7E, 0x3E,
++	0x00, 0x81, 0xCE, 0x9F, 0x15,
++	0x0D, 0x20, 0x9C, 0x2F, 0x5D,
++	0x00, 0xEF, 0x0F, 0xF6, 0x20,
++	0x08, 0x73, 0xE0, 0x9A, 0xAD,
++	0x07, 0x7D, 0x1C, 0xA9, 0xDC,
++	0x05, 0xDE, 0x0C, 0x48, 0x42,
++	0x0B, 0x86, 0x82, 0xD8, 0x6D,
++	0x04, 0xC8, 0x61, 0x56, 0x3E,
++	0x01, 0xAF, 0xBD, 0x35, 0xC1,
++	0x0B, 0x8E, 0xCA, 0x4B, 0xF2,
++	0x05, 0x75, 0x56, 0x74, 0x7B,
++	0x0C, 0xD6, 0xDD, 0x42, 0xD4,
++	0x05, 0x40, 0xA5, 0x74, 0xF3,
++	0x03, 0x9D, 0x27, 0xA8, 0x10,
++	0x0B, 0x38, 0xDE, 0xC4, 0x61,
++	0x06, 0x55, 0xF0, 0x6B, 0xA2,
++	0x0F, 0xC1, 0xC9, 0xCA, 0x3C,
++	0x09, 0xB1, 0x52, 0x3C, 0xE1,
++	0x06, 0x18, 0x45, 0x04, 0x23,
++	0x01, 0xCB, 0x50, 0xD3, 0x9B,
++	0x0D, 0x42, 0xB6, 0xBD, 0x9C,
++	0x0B, 0xF2, 0x68, 0x62, 0x0A,
++	0x09, 0x46, 0x97, 0x7A, 0x45,
++	0x03, 0x2C, 0xF5, 0x75, 0xC2,
++	0x05, 0xA3, 0x81, 0x2D, 0x2A,
++	0x09, 0x53, 0x72, 0x6C, 0x87,
++	0x02, 0x56, 0xDD, 0xC6, 0x06,
++	0x08, 0xA4, 0x31, 0xC1, 0x3C,
++	0x07, 0xF9, 0x74, 0xC7, 0x4C,
++	0x0A, 0xD1, 0xB0, 0x79, 0x33,
++	0x08, 0xA6, 0x02, 0x35, 0x61,
++	0x01, 0x10, 0x1C, 0x46, 0x13,
++	0x05, 0x61, 0xBD, 0x31, 0x28,
++	0x01, 0x69, 0xFB, 0x28, 0x37,
++	0x04, 0xD4, 0xCC, 0x06, 0x32,
++	0x0D, 0x77, 0x68, 0xB1, 0x9C,
++	0x05, 0xE9, 0xEE, 0x83, 0x42,
++	0x04, 0x0B, 0x5B, 0x51, 0x02,
++	0x05, 0xE5, 0xDC, 0x0E, 0x74,
++	0x0E, 0xE2, 0x09, 0x0C, 0xE1,
++	0x03, 0xE4, 0x87, 0x74, 0x3F,
++	0x0B, 0xED, 0xF2, 0x99, 0x06,
++	0x0F, 0x68, 0x73, 0xEA, 0x85,
++	0x00, 0x61, 0x6E, 0xE2, 0x97,
++	0x0A, 0x12, 0xF6, 0xA7, 0x22,
++	0x0B, 0x7A, 0xEE, 0x48, 0x4A,
++	0x0B, 0x76, 0xE9, 0x6F, 0xC9,
++	0x0B, 0x98, 0x08, 0x61, 0x1A,
++	0x05, 0x11, 0x60, 0x28, 0x4F,
++	0x06, 0xDD, 0xC6, 0xB6, 0xEC,
++	0x0A, 0xBE, 0xAB, 0x45, 0x1E,
++	0x0F, 0xB8, 0x1C, 0x6D, 0xBD,
++	0x07, 0x12, 0x1D, 0xC6, 0xF6,
++	0x0D, 0xA7, 0x50, 0xFF, 0x83,
++	0x06, 0x96, 0xD2, 0x05, 0x4E,
++	0x09, 0xE5, 0xAD, 0x84, 0x51,
++	0x06, 0xD5, 0xC6, 0xD2, 0x02,
++	0x0B, 0x1A, 0x22, 0xD5, 0x82,
++	0x0C, 0xDC, 0x08, 0x1B, 0x67,
++	0x04, 0x90, 0xDC, 0x9E, 0x13,
++	0x0A, 0xD8, 0xCB, 0xB1, 0xBB,
++	0x02, 0xC7, 0x5A, 0xE7, 0x85,
++	0x0A, 0x0D, 0x6D, 0xD5, 0xA9,
++	0x0D, 0x54, 0x0A, 0x5A, 0x9E,
++	0x0A, 0xF9, 0xD3, 0xFF, 0xE2,
++	0x04, 0x33, 0x85, 0x7D, 0x90,
++	0x07, 0x01, 0xE5, 0x82, 0xB4,
++	0x0E, 0x64, 0x12, 0x0D, 0xA3,
++	0x05, 0x7B, 0x1D, 0x26, 0x83,
++	0x0B, 0x89, 0x88, 0x80, 0x42,
++	0x00, 0x9C, 0xAB, 0x9D, 0x63,
++	0x09, 0x14, 0x2B, 0x4F, 0xD9,
++	0x05, 0xBF, 0x24, 0xA6, 0x60,
++	0x0A, 0x94, 0x69, 0x7F, 0x45,
++	0x0E, 0xB2, 0xCF, 0x13, 0xF0,
++	0x0A, 0xDB, 0xB0, 0x56, 0x3F,
++	0x01, 0x94, 0x4F, 0x2E, 0xE0,
++	0x0D, 0x24, 0x38, 0xD4, 0x48,
++	0x0E, 0x43, 0x1B, 0x38, 0x3B,
++	0x0A, 0xFF, 0xCD, 0x62, 0x15,
++	0x01, 0xA4, 0xDB, 0x5B, 0x9F,
++	0x02, 0x2A, 0x47, 0x8B, 0xD7,
++	0x07, 0x11, 0x00, 0xA4, 0xE1,
++	0x0D, 0x56, 0x99, 0xD3, 0xF2,
++	0x0C, 0xD6, 0x3F, 0xB2, 0xCB,
++	0x0F, 0x4D, 0x8C, 0xC4, 0xDA,
++	0x08, 0xD2, 0x7E, 0x9D, 0x1F,
++	0x05, 0x9E, 0x3E, 0xFE, 0x77,
++	0x07, 0x60, 0xB5, 0xE3, 0xD2,
++	0x09, 0x5E, 0x5D, 0xE6, 0xE5,
++	0x00, 0xF9, 0xC8, 0x9D, 0x0E,
++	0x0D, 0xB4, 0xE2, 0x77, 0x83,
++	0x0C, 0x1E, 0xF8, 0xB5, 0x14,
++	0x0A, 0x76, 0x8F, 0x22, 0xA8,
++	0x04, 0x8E, 0x34, 0xBE, 0x26,
++	0x02, 0x01, 0x0A, 0xC2, 0x72,
++	0x08, 0x37, 0xA6, 0xE4, 0xD0,
++	0x0D, 0x3F, 0x64, 0x96, 0xFC,
++	0x0A, 0x99, 0x00, 0xC6, 0x51,
++	0x05, 0xFD, 0x16, 0x3A, 0xCB,
++	0x0C, 0x7D, 0xD0, 0x6B, 0x6E,
++	0x0A, 0x6B, 0xEA, 0xA6, 0x50,
++	0x00, 0x91, 0x81, 0xCE, 0x8F,
++	0x07, 0x51, 0x2D, 0x98, 0x24,
++	0x04, 0x10, 0x47, 0x0E, 0x2F,
++	0x05, 0xD9, 0xF3, 0x26, 0x94,
++	0x01, 0x1E, 0xEE, 0x58, 0xB7,
++	0x0C, 0x6D, 0x5C, 0x48, 0x4F,
++	0x0A, 0xD0, 0x24, 0xE4, 0x8F,
++	0x07, 0x65, 0x48, 0xA7, 0x5A,
++	0x0E, 0xC9, 0x2D, 0xF9, 0x35,
++	0x03, 0x01, 0x8C, 0xA7, 0x40,
++	0x02, 0xED, 0xD5, 0x97, 0xAF,
++	0x03, 0x88, 0x56, 0xDB, 0x82,
++	0x0F, 0x54, 0xE0, 0xA9, 0x79,
++	0x0F, 0x4B, 0x1D, 0x23, 0xAE,
++	0x08, 0x41, 0xA7, 0x5E, 0xC9,
++	0x09, 0xDE, 0x9F, 0xF0, 0xBB,
++	0x08, 0xE4, 0xE8, 0x29, 0xDB,
++	0x04, 0xF8, 0x35, 0x52, 0xF8,
++	0x0A, 0xB8, 0x9C, 0x8A, 0x87,
++	0x01, 0x09, 0xCE, 0xB4, 0xD4,
++	0x03, 0x91, 0xC2, 0xB4, 0x3D,
++	0x02, 0x5A, 0x72, 0x6A, 0x66,
++	0x03, 0x19, 0x46, 0x97, 0xF4,
++	0x0C, 0xEB, 0x28, 0xF5, 0xF7,
++	0x09, 0xAD, 0x3B, 0x05, 0x6F,
++	0x0A, 0x80, 0xCA, 0xF2, 0xEE,
++	0x07, 0x3A, 0x4F, 0x5D, 0x44,
++	0x02, 0x70, 0xB9, 0xB7, 0x43,
++	0x04, 0x3F, 0x60, 0xF7, 0x05,
++	0x0C, 0x83, 0xD3, 0xB4, 0x79,
++	0x03, 0x62, 0xA4, 0x71, 0xB5,
++	0x05, 0x31, 0x10, 0x0C, 0x46,
++	0x0B, 0x17, 0x41, 0xB1, 0x77,
++	0x02, 0x9D, 0xE9, 0xFB, 0x24,
++	0x05, 0xE4, 0xD4, 0xC8, 0x46,
++	0x0E, 0x99, 0x2F, 0xE8, 0xA7,
++	0x06, 0x1B, 0xE3, 0xEE, 0xC9,
++	0x0B, 0x76, 0x03, 0x5F, 0x55,
++	0x09, 0x95, 0xE5, 0xDC, 0x0E,
++	0x0C, 0x9E, 0x32, 0x8F, 0x0C,
++	0x0B, 0x79, 0xCA, 0x07, 0x68,
++	0x07, 0xC1, 0x67, 0x8B, 0x99,
++	0x04, 0xA7, 0x64, 0xF3, 0xE6,
++	0x0E, 0x48, 0xE3, 0x6A, 0xE2,
++	0x0E, 0x20, 0x84, 0x8C, 0x39,
++	0x0A, 0xC3, 0x7A, 0x62, 0x06,
++	0x0A, 0xD3, 0xF6, 0x4B, 0xEC,
++	0x01, 0x29, 0x3C, 0x0C, 0xA5,
++	0x03, 0x5D, 0xD1, 0x6F, 0xAC,
++	0x09, 0xC5, 0x6C, 0x06, 0xBE,
++	0x00, 0x0A, 0xBE, 0xAA, 0x12,
++	0x03, 0xE3, 0x38, 0x1A, 0xE9,
++	0x05, 0xF4, 0xB2, 0x19, 0x02,
++	0x0A, 0xDB, 0x0E, 0xF0, 0xE8,
++	0x0F, 0xD7, 0x17, 0x32, 0x38,
++	0x07, 0xD3, 0xE3, 0xC1, 0xCA,
++	0x0B, 0xC4, 0x60, 0x44, 0xD4,
++	0x08, 0x8B, 0x38, 0x42, 0x55,
++	0x0E, 0xA4, 0x5C, 0x8C, 0x15,
++	0x0E, 0xEE, 0x92, 0xD3, 0xD3,
++	0x09, 0x32, 0xAB, 0xCA, 0x30,
++	0x05, 0xA0, 0x7E, 0x59, 0x66,
++	0x03, 0xA5, 0xF2, 0x91, 0xE9,
++	0x04, 0x7F, 0x54, 0x06, 0x17,
++	0x0D, 0x72, 0x80, 0xD2, 0x7E,
++	0x02, 0x8D, 0x93, 0x89, 0xED,
++	0x02, 0x0D, 0x61, 0xF9, 0x07,
++	0x07, 0x2C, 0x64, 0x1E, 0xDD,
++	0x09, 0xCD, 0x2C, 0x15, 0x2B,
++	0x0D, 0xAB, 0x89, 0x8E, 0x8A,
++	0x0A, 0x30, 0x18, 0xAB, 0xCD,
++	0x03, 0x79, 0x15, 0xAE, 0x37,
++	0x0D, 0x25, 0xBF, 0x22, 0xA6,
++	0x08, 0x31, 0x10, 0x69, 0xBF,
++	0x05, 0x8F, 0x32, 0xCB, 0x48,
++	0x04, 0x1A, 0xDB, 0xB4, 0x03,
++	0x0E, 0xA8, 0x14, 0xAB, 0x2E,
++	0x08, 0x5B, 0x2C, 0xF5, 0x14,
++	0x08, 0x4E, 0x87, 0xDB, 0x7E,
++	0x00, 0xC3, 0xFE, 0x0F, 0x0D,
++	0x0C, 0xC8, 0x25, 0x35, 0x0E,
++	0x07, 0xAE, 0x8A, 0x4A, 0xDB,
++	0x0B, 0x0C, 0xEE, 0xFC, 0x87,
++	0x09, 0x39, 0xD4, 0x1B, 0x93,
++	0x08, 0xC8, 0x5E, 0x1A, 0x38,
++	0x0B, 0x7E, 0x4D, 0xCC, 0xC0,
++	0x0B, 0xAA, 0xD2, 0x7C, 0x0B,
++	0x04, 0x67, 0x9E, 0xBC, 0x68,
++	0x0C, 0x35, 0x62, 0x37, 0x75,
++	0x08, 0xAB, 0x5E, 0x5F, 0x40,
++	0x07, 0x49, 0xEB, 0x2E, 0xDA,
++	0x0E, 0x17, 0xB6, 0xEE, 0xFD,
++	0x07, 0xFC, 0x1E, 0x7E, 0x73,
++	0x00, 0x4A, 0x76, 0x09, 0x74,
++	0x0C, 0x54, 0x8E, 0x36, 0xAE,
++	0x0E, 0xA0, 0x01, 0x0A, 0x42,
++	0x02, 0xAC, 0x37, 0xA6, 0xE4,
++	0x00, 0xAD, 0x3F, 0x64, 0x96,
++	0x0C, 0x9A, 0x9B, 0x86, 0x8C,
++	0x0A, 0xA5, 0xFD, 0x16, 0x3A,
++	0x0B, 0x3C, 0x7D, 0xDE, 0x76,
++	0x06, 0xC1, 0xE7, 0xE4, 0xE0,
++	0x0A, 0x34, 0x1B, 0x8C, 0x0E,
++	0x0A, 0xD7, 0x91, 0x21, 0x5C,
++	0x01, 0xEC, 0x1D, 0xEF, 0x0F,
++	0x08, 0x3D, 0xF3, 0x77, 0x29,
++	0x0C, 0xEC, 0x9E, 0x70, 0xD8,
++	0x00, 0x9E, 0x2D, 0x5E, 0xCC,
++	0x0E, 0x00, 0xDC, 0x04, 0xE1,
++	0x08, 0x6F, 0x4D, 0xCE, 0x2B,
++	0x02, 0xFC, 0xEB, 0x21, 0xF9,
++	0x0F, 0x31, 0xCB, 0x0C, 0xAB,
++	0x00, 0xFA, 0x2C, 0x75, 0x96,
++	0x08, 0xFB, 0xA0, 0xDB, 0x99,
++	0x09, 0x54, 0xDB, 0xCD, 0x20,
++	0x07, 0xF7, 0xCE, 0x9D, 0x27,
++	0x02, 0xA2, 0x41, 0x78, 0x5D,
++	0x01, 0xA1, 0x5E, 0x11, 0xF0,
++	0x03, 0xE3, 0x66, 0x41, 0x69,
++	0x02, 0xBC, 0x59, 0xBC, 0x12,
++	0x08, 0xDA, 0xB8, 0x9C, 0x95,
++	0x0C, 0xEA, 0xA9, 0xC7, 0x70,
++	0x06, 0x1A, 0x35, 0x42, 0x74,
++	0x04, 0x92, 0x9B, 0xF2, 0x6A,
++	0x0F, 0x83, 0xF9, 0x46, 0x97,
++	0x04, 0x58, 0xEF, 0x28, 0xB5,
++	0x07, 0x41, 0xA9, 0xBB, 0xC6,
++	0x0F, 0xAA, 0x81, 0x4A, 0x03,
++	0x04, 0xE7, 0x3A, 0xCA, 0xEF,
++	0x04, 0x86, 0x74, 0xBD, 0xB3,
++	0x01, 0xBC, 0x33, 0xE0, 0x77,
++	0x07, 0xCC, 0x82, 0x43, 0x34,
++	0x08, 0xF2, 0xA2, 0xA4, 0x71,
++	0x04, 0xF0, 0xD1, 0x10, 0x08,
++	0x06, 0x13, 0x93, 0x6F, 0xF4,
++	0x0D, 0xC2, 0x9D, 0xEC, 0x4C,
++	0x06, 0xB7, 0xE4, 0xC4, 0x4C,
++	0x06, 0x32, 0x8D, 0x2F, 0xE8,
++	0x00, 0x57, 0xB9, 0xE3, 0xEE,
++	0x0B, 0x5B, 0xF2, 0x09, 0xDF,
++	0x05, 0x02, 0x95, 0x65, 0xD6,
++	0x06, 0xF6, 0x9A, 0xBA, 0x49,
++	0x06, 0xE3, 0x9E, 0x66, 0x85,
++	0x00, 0xFD, 0x81, 0x6D, 0x0B,
++	0x09, 0x04, 0xA4, 0xEA, 0x79,
++	0x0C, 0xC7, 0xA8, 0x63, 0x62,
++	0x02, 0x62, 0x20, 0x90, 0x8C,
++	0x07, 0x2A, 0xC0, 0xFC, 0xE4,
++	0x05, 0x0A, 0xD2, 0xF0, 0xC3,
++	0x0F, 0xC9, 0xA9, 0x98, 0x0C,
++	0x0D, 0x98, 0x3F, 0x53, 0xE3,
++	0x0C, 0xB3, 0xC4, 0x5F, 0x8C,
++	0x0C, 0xEE, 0xF2, 0xBE, 0xA2,
++	0x05, 0x2B, 0xCB, 0x38, 0x1C,
++	0x09, 0x3D, 0x76, 0x94, 0xD3,
++	0x02, 0xF6, 0xCC, 0x08, 0x3A,
++	0x05, 0x81, 0x31, 0x97, 0x33,
++	0x01, 0x4F, 0x51, 0x6B, 0xCD,
++	0x02, 0x13, 0x86, 0x57, 0x44,
++	0x04, 0x40, 0x21, 0x9A, 0xFF,
++	0x05, 0x86, 0xF7, 0xDE, 0x38,
++	0x05, 0xA7, 0xEF, 0x90, 0x6C,
++	0x03, 0x53, 0x30, 0x9C, 0xC0,
++	0x0E, 0xBD, 0x4B, 0xC7, 0x51,
++	0x07, 0x8F, 0xBA, 0x0B, 0xE7,
++	0x00, 0xAF, 0x3D, 0xD8, 0x4A,
++	0x0D, 0x95, 0x9A, 0xB9, 0xDA,
++	0x0A, 0xEA, 0x24, 0x35, 0x0F,
++	0x05, 0x18, 0x7D, 0x6D, 0x7F,
++	0x0D, 0xBC, 0xC2, 0x64, 0x1A,
++	0x0D, 0xA3, 0xCF, 0x9D, 0xDF,
++	0x0B, 0x0F, 0xCB, 0x05, 0x48,
++	0x0A, 0x40, 0xDD, 0x1C, 0xA3,
++	0x0D, 0xE9, 0xB9, 0x12, 0xE1,
++	0x0F, 0xD9, 0x25, 0x3F, 0x26,
++	0x06, 0x60, 0x31, 0x94, 0x69,
++	0x07, 0x47, 0xCE, 0xB0, 0x4F,
++	0x05, 0x76, 0xEA, 0x5B, 0xB8,
++	0x0A, 0xFA, 0xAC, 0x14, 0xAF,
++	0x0E, 0xE0, 0x7F, 0xA4, 0xF5,
++	0x06, 0x48, 0x63, 0x0D, 0xDB,
++	0x0C, 0x3B, 0x45, 0x7C, 0x8F,
++	0x0C, 0x5D, 0x48, 0x25, 0x3B,
++	0x0F, 0x1D, 0x77, 0xA8, 0xC7,
++	0x03, 0xD5, 0x33, 0x11, 0xC0,
++	0x0E, 0x63, 0xCD, 0x56, 0x0B,
++	0x03, 0x72, 0x28, 0x50, 0x95,
++	0x02, 0x4B, 0x72, 0xCD, 0x4C,
++	0x00, 0x63, 0x24, 0xD2, 0xFE,
++	0x03, 0x1F, 0x05, 0x9C, 0xBE,
++	0x02, 0x37, 0x40, 0x60, 0xBD,
++	0x05, 0x50, 0x2D, 0x5E, 0x5D,
++	0x00, 0xE7, 0x45, 0xEB, 0xA8,
++	0x02, 0xCE, 0x13, 0xB0, 0x68,
++	0x0F, 0x87, 0x7B, 0x1C, 0x78,
++	0x09, 0x91, 0xCA, 0x76, 0x8F,
++	0x06, 0xEE, 0x35, 0x8C, 0xB6,
++	0x06, 0xA4, 0x06, 0x01, 0xC8,
++	0x08, 0x70, 0x56, 0xB7, 0xB6,
++	0x04, 0x50, 0xAD, 0x39, 0x6E,
++	0x0E, 0xFC, 0x1E, 0x99, 0x40,
++	0x0E, 0xD0, 0x22, 0x7F, 0x96,
++	0x0A, 0xCB, 0x3C, 0x7D, 0x13,
++	0x01, 0x6C, 0x3F, 0x6B, 0xE8,
++	0x02, 0x52, 0xBC, 0xBD, 0xC1,
++	0x0E, 0x93, 0xD7, 0x51, 0x21,
++	0x0D, 0xE5, 0x0C, 0xD0, 0xEF,
++	0x07, 0x79, 0xBD, 0x73, 0xF3,
++	0x0A, 0x97, 0xED, 0x9E, 0x7E,
++	0x0A, 0xA9, 0x1C, 0x6B, 0x1C,
++	0x0C, 0x44, 0x02, 0x11, 0x84,
++	0x04, 0x12, 0x2F, 0x4D, 0xC8,
++	0x09, 0x5A, 0xFA, 0xC9, 0x6D,
++	0x01, 0xB4, 0xB0, 0x83, 0x0C,
++	0x09, 0x48, 0xF9, 0xAC, 0x7D,
++	0x04, 0x78, 0xFB, 0xA6, 0x96,
++	0x0D, 0x82, 0xD7, 0xD5, 0x40,
++	0x04, 0xB3, 0x17, 0x03, 0x9D,
++	0x0F, 0x2F, 0x23, 0x41, 0xB8,
++	0x04, 0xDA, 0xA7, 0x5E, 0x17,
++	0x02, 0x7B, 0xE2, 0xE0, 0x01,
++	0x09, 0xDA, 0x3C, 0xF9, 0xB1,
++	0x03, 0x72, 0x9A, 0xB8, 0x98,
++	0x08, 0x04, 0x23, 0x09, 0xCA,
++	0x08, 0xD6, 0x1F, 0x97, 0x82,
++	0x0C, 0xF4, 0x12, 0x5D, 0x72,
++	0x02, 0xE4, 0x03, 0x19, 0x86,
++	0x0D, 0xF7, 0x51, 0xEB, 0x24,
++	0x09, 0xF7, 0xC1, 0xAD, 0x7B,
++	0x0D, 0x2D, 0xAE, 0x83, 0xCA,
++	0x08, 0xED, 0x0C, 0x3A, 0x47,
++	0x0D, 0x44, 0x82, 0x70, 0xBD,
++	0x03, 0x43, 0xB0, 0x3F, 0xE0,
++	0x05, 0xC5, 0xC8, 0x84, 0x13,
++	0x0C, 0xF9, 0x53, 0x60, 0x24,
++	0x01, 0x34, 0xD1, 0x31, 0x10,
++	0x08, 0x46, 0x13, 0x95, 0x61,
++	0x0D, 0x37, 0x22, 0x83, 0x5B,
++	0x0B, 0x24, 0xB5, 0xE2, 0x9E,
++	0x07, 0x06, 0x32, 0x8B, 0x5C,
++	0x01, 0x31, 0x36, 0x64, 0x23,
++	0x00, 0x03, 0x96, 0x76, 0x0B,
++	0x07, 0x50, 0x80, 0x98, 0x36,
++	0x0C, 0x0E, 0x74, 0x80, 0xA7,
++	0x09, 0x0C, 0xE1, 0x3F, 0x72,
++	0x0F, 0x40, 0xFB, 0xF1, 0x2F,
++	0x02, 0x98, 0x84, 0x87, 0xE8,
++	0x0B, 0x67, 0x45, 0x48, 0x63,
++	0x0A, 0xE2, 0x62, 0x20, 0x19,
++	0x0C, 0x27, 0x2E, 0x45, 0xF0,
++	0x0C, 0x45, 0x0E, 0x55, 0xBC,
++	0x0B, 0x6F, 0xC9, 0xAF, 0xD8,
++	0x0C, 0x65, 0x9A, 0x5B, 0x12,
++	0x03, 0x5C, 0x13, 0xC7, 0xDD,
++	0x0A, 0xB6, 0xCC, 0x16, 0x8F,
++	0x03, 0x87, 0x6B, 0xCD, 0xB8,
++	0x06, 0xEA, 0x2A, 0xF5, 0x1A,
++	0x00, 0xC2, 0x36, 0xCB, 0x0E,
++	0x09, 0x7D, 0xC3, 0xD9, 0x57,
++	0x08, 0x0A, 0x57, 0xD1, 0xE5,
++	0x04, 0x8A, 0x51, 0xC0, 0x95,
++	0x08, 0xF4, 0x40, 0x21, 0x2A,
++	0x0C, 0x55, 0x86, 0xF4, 0x5C,
++	0x08, 0x15, 0xA0, 0x6A, 0x18,
++	0x0E, 0x92, 0x93, 0x30, 0x18,
++	0x0B, 0x36, 0xFF, 0xA2, 0xC7,
++	0x00, 0xE5, 0xCF, 0xBC, 0x0D,
++	0x07, 0xDB, 0x30, 0x7D, 0x5C,
++	0x03, 0x57, 0x57, 0x76, 0x39,
++	0x0B, 0xF8, 0xAA, 0x22, 0x73,
++	0x0F, 0xEE, 0x84, 0x9D, 0xE3,
++	0x06, 0x07, 0x7E, 0x28, 0x24,
++	0x0A, 0x1C, 0x63, 0xCD, 0x1B,
++	0x0D, 0x23, 0x09, 0xAB, 0x49,
++	0x01, 0x00, 0xA2, 0x30, 0x9C,
++	0x0B, 0x0D, 0xE9, 0xBF, 0x4F,
++	0x0B, 0x4F, 0xD9, 0x22, 0x25,
++	0x0C, 0x66, 0x69, 0xB7, 0xD7,
++	0x09, 0x7F, 0x45, 0x8E, 0xB2,
++	0x07, 0x9D, 0x74, 0x1B, 0x5B,
++	0x0A, 0x59, 0xD9, 0x28, 0x1C,
++	0x07, 0x2E, 0x60, 0x72, 0x24,
++	0x0D, 0x54, 0xEB, 0xE5, 0x8B,
++	0x02, 0x36, 0x1B, 0xCF, 0xBE,
++	0x05, 0x7F, 0x7A, 0xC8, 0x2D,
++	0x03, 0xB7, 0x3F, 0x30, 0x6A,
++	0x0D, 0x18, 0x7F, 0x13, 0x10,
++	0x00, 0x84, 0x61, 0x3D, 0x1D,
++	0x02, 0x53, 0x92, 0x29, 0x81,
++	0x06, 0x33, 0xAB, 0x72, 0xCD,
++	0x04, 0x68, 0xC3, 0x2E, 0x92,
++	0x0E, 0x8B, 0x1C, 0x61, 0x49,
++	0x0A, 0xE8, 0x35, 0xB1, 0x60,
++	0x0C, 0xDD, 0x90, 0x2B, 0xDE,
++	0x0C, 0x40, 0x03, 0x49, 0x32,
++	0x08, 0x90, 0xCE, 0x11, 0xED,
++	0x08, 0x77, 0x87, 0xFB, 0x84,
++	0x08, 0xB9, 0x90, 0x6C, 0xB4,
++	0x05, 0xFE, 0x65, 0xD2, 0xD6,
++	0x06, 0xAE, 0x26, 0x23, 0x8B,
++	0x0C, 0xC2, 0x72, 0xEA, 0x37,
++	0x0E, 0xDC, 0xD4, 0xAD, 0xFF,
++	0x04, 0xBF, 0x78, 0x9A, 0x99,
++	0x0B, 0x44, 0xC7, 0x25, 0x0C,
++	0x0E, 0x3B, 0x4F, 0x3C, 0xBD,
++	0x09, 0xEB, 0x8E, 0xC1, 0x2B,
++	0x03, 0x22, 0x32, 0xB0, 0xBB,
++	0x01, 0xCE, 0x93, 0x81, 0x53,
++	0x01, 0x9C, 0x2D, 0x3C, 0xD0,
++	0x05, 0x0C, 0xF7, 0x3D, 0xE1,
++	0x08, 0x20, 0x94, 0xED, 0x1E,
++	0x00, 0xD8, 0xA9, 0xDC, 0x5B,
++	0x00, 0x4C, 0x47, 0x42, 0x12,
++	0x0D, 0xE5, 0x98, 0x61, 0x50,
++	0x01, 0xA0, 0x9E, 0x7E, 0x89,
++	0x05, 0x79, 0x91, 0x33, 0xC1,
++	0x04, 0xA3, 0xCF, 0xFA, 0xEC,
++	0x0D, 0x97, 0xF8, 0xF6, 0xA0,
++	0x06, 0xDD, 0x82, 0xD7, 0xE7,
++	0x00, 0xA5, 0x7B, 0x73, 0x37,
++	0x0D, 0x27, 0xAC, 0xA6, 0x30,
++	0x08, 0x5E, 0xD9, 0xA5, 0x43,
++	0x0F, 0xF0, 0x7B, 0xE6, 0x5D,
++	0x08, 0xA9, 0x3A, 0x3C, 0x39,
++	0x09, 0x52, 0xB8, 0xDA, 0xB8,
++	0x06, 0x08, 0xC9, 0x23, 0x09,
++	0x0A, 0xB0, 0xDE, 0x95, 0x8C,
++	0x0A, 0x34, 0x5B, 0x9F, 0x52,
++	0x0A, 0xEB, 0xC2, 0x0F, 0x19,
++	0x0F, 0x9F, 0x30, 0x5A, 0x6B,
++	0x05, 0xF8, 0x37, 0x41, 0x6D,
++	0x03, 0x05, 0xAF, 0xAE, 0xF5,
++	0x0A, 0xF2, 0xEE, 0x07, 0x3A,
++	0x09, 0x5D, 0x44, 0x80, 0xF0,
++	0x04, 0xA6, 0x83, 0xBC, 0xFF,
++	0x01, 0xF6, 0x0D, 0xC2, 0x5C,
++	0x03, 0xB4, 0x7D, 0xF7, 0x16,
++	0x08, 0x71, 0xB4, 0x31, 0x3F,
++	0x02, 0x08, 0x4E, 0x15, 0x15,
++	0x0D, 0x87, 0x37, 0x22, 0x9C,
++	0x09, 0xD2, 0xA4, 0xB7, 0xE4,
++	0x0D, 0x4E, 0x64, 0x3E, 0x8D,
++	0x05, 0xEB, 0x88, 0xD6, 0x49,
++	0x0A, 0xEE, 0x4B, 0x55, 0xB6,
++	0x07, 0x60, 0xAA, 0xC2, 0x85,
++	0x07, 0xDC, 0x06, 0x72, 0x9E,
++	0x02, 0x89, 0x80, 0xED, 0xFB,
++	0x06, 0xE6, 0xFA, 0x72, 0x08,
++	0x06, 0x8A, 0x5D, 0x09, 0x27,
++	0x00, 0x71, 0x46, 0xC9, 0x88,
++	0x03, 0x6A, 0xE2, 0x64, 0x12,
++	0x0A, 0x8F, 0x11, 0xAA, 0xD3,
++	0x0A, 0x6E, 0x41, 0x0A, 0xD3,
++	0x0E, 0x48, 0xFB, 0x49, 0x69,
++	0x00, 0x8E, 0x65, 0x1A, 0xAD,
++	0x0B, 0x60, 0xE5, 0xB3, 0xC5,
++	0x05, 0x06, 0x36, 0xE0, 0x96,
++	0x06, 0xA8, 0x05, 0x29, 0x4B,
++	0x02, 0x1F, 0xA2, 0x3D, 0x7D,
++	0x02, 0x19, 0xC6, 0xF6, 0xCD,
++	0x0E, 0xF0, 0xF3, 0x83, 0xDF,
++	0x05, 0x32, 0x09, 0x48, 0xD1,
++	0x0F, 0xCD, 0x0A, 0x93, 0x46,
++	0x05, 0xC5, 0x44, 0x40, 0x21,
++	0x08, 0x4E, 0x55, 0x86, 0xF4,
++	0x0C, 0x8A, 0x15, 0xA7, 0xEC,
++	0x02, 0xDF, 0x91, 0x55, 0x3A,
++	0x03, 0xCA, 0x34, 0xBF, 0xA2,
++	0x07, 0x59, 0x67, 0x83, 0xFE,
++	0x0D, 0x6D, 0xD8, 0x31, 0xF8,
++	0x0C, 0x0A, 0xD7, 0xB9, 0x6D,
++	0x01, 0x83, 0xFE, 0xC6, 0x24,
++	0x03, 0x85, 0xE9, 0x9A, 0xE4,
++	0x01, 0xFF, 0x03, 0xBA, 0x16,
++	0x0C, 0x12, 0x19, 0xAE, 0x0F,
++	0x03, 0x90, 0x83, 0x80, 0x6B,
++	0x01, 0x8A, 0x80, 0x4E, 0x30,
++	0x04, 0x29, 0x2D, 0xE5, 0xB9,
++	0x04, 0x2B, 0x4F, 0xDD, 0x1F,
++	0x0F, 0x26, 0xA6, 0x64, 0x4A,
++	0x04, 0x69, 0x7F, 0x45, 0x79,
++	0x0B, 0x07, 0xFF, 0x78, 0x1A,
++	0x05, 0x30, 0x97, 0xFA, 0xA8,
++	0x04, 0xAF, 0x2E, 0xEE, 0xE0,
++	0x04, 0xF5, 0xD4, 0x46, 0xB3,
++	0x03, 0xDA, 0xD4, 0x36, 0x83,
++	0x07, 0xC6, 0x9C, 0x50, 0xC8,
++	0x05, 0x3B, 0x47, 0x8B, 0x2B,
++	0x02, 0x47, 0x1F, 0x1A, 0xCA,
++	0x03, 0x00, 0x88, 0x71, 0xB9,
++	0x04, 0x1B, 0xD7, 0x22, 0xA8,
++	0x04, 0xB7, 0x32, 0x5B, 0xFE,
++	0x0F, 0x66, 0xCC, 0x23, 0xA8,
++	0x00, 0xD7, 0x0F, 0x0D, 0xE5,
++	0x0C, 0x17, 0x64, 0x65, 0x37,
++	0x02, 0x1D, 0x55, 0x40, 0xA9,
++	0x0C, 0xF4, 0x64, 0xA7, 0xC9,
++	0x09, 0x02, 0xBC, 0xDE, 0x97,
++	0x04, 0xC1, 0xD3, 0xD7, 0x7C,
++	0x0D, 0xD0, 0x79, 0x80, 0xCA,
++	0x05, 0xA6, 0xF2, 0x6C, 0xD4,
++	0x0D, 0x1F, 0x6E, 0x66, 0xA2,
++	0x00, 0x22, 0x86, 0x64, 0xAF,
++	0x05, 0x8E, 0x68, 0x00, 0x2D,
++	0x0D, 0x61, 0x16, 0xEC, 0x1A,
++	0x0B, 0xA9, 0x46, 0x71, 0x25,
++	0x0D, 0x3F, 0xBA, 0xDB, 0x3C,
++	0x0D, 0xF9, 0xEB, 0x7E, 0x83,
++	0x0B, 0xEA, 0xA0, 0x14, 0xFE,
++	0x0B, 0x81, 0xCE, 0x85, 0x55,
++	0x01, 0x21, 0x9C, 0x79, 0x6E,
++	0x09, 0xA5, 0x6F, 0xD6, 0x7D,
++	0x0B, 0x70, 0x75, 0x14, 0xE9,
++	0x02, 0x63, 0x27, 0x55, 0x29,
++	0x0D, 0x5C, 0x4C, 0x4A, 0x1F,
++	0x01, 0x84, 0xE1, 0x54, 0xEB,
++	0x0D, 0xC8, 0xA5, 0x76, 0xBB,
++	0x09, 0x2D, 0xFD, 0x15, 0xC4,
++	0x01, 0x8C, 0xA3, 0x6B, 0x0B,
++	0x0C, 0x75, 0x96, 0x58, 0x09,
++	0x09, 0x56, 0x3D, 0x8E, 0xD7,
++	0x0B, 0xC0, 0x68, 0x79, 0x77,
++	0x03, 0x9D, 0x27, 0xB0, 0x31,
++	0x03, 0x38, 0x5E, 0xE7, 0x75,
++	0x0E, 0x1F, 0xF0, 0x6B, 0x5A,
++	0x06, 0x41, 0x29, 0x9A, 0xBF,
++	0x0F, 0xB1, 0x52, 0x28, 0x5A,
++	0x0E, 0x98, 0x88, 0x54, 0xA3,
++	0x0F, 0x4A, 0x10, 0xCE, 0x1B,
++	0x07, 0xC3, 0x14, 0xDD, 0x12,
++	0x0A, 0xF0, 0x4A, 0x78, 0x01,
++	0x08, 0x44, 0xD7, 0xD4, 0x1A,
++	0x03, 0x2C, 0x71, 0xFA, 0x01,
++	0x05, 0x39, 0x25, 0xAF, 0xAA,
++	0x0B, 0x49, 0x84, 0x6E, 0x27,
++	0x02, 0x4F, 0xDD, 0x44, 0x86,
++	0x08, 0x04, 0x13, 0x4F, 0xFC,
++	0x06, 0xE2, 0xB7, 0xC5, 0xCC,
++	0x08, 0x50, 0xC2, 0xF9, 0xF1,
++	0x02, 0xA4, 0x71, 0xB3, 0x2A,
++	0x01, 0x10, 0x08, 0x41, 0x89,
++	0x0C, 0x60, 0x5D, 0x3A, 0xA2,
++	0x0F, 0xA9, 0xF2, 0xA2, 0x5F,
++	0x0C, 0xD4, 0x4C, 0x07, 0xB2,
++	0x06, 0xAD, 0x42, 0xB5, 0x4B,
++	0x0B, 0xE3, 0xEE, 0x85, 0x5B,
++	0x06, 0x0B, 0x5F, 0x58, 0xDB,
++	0x05, 0xCD, 0x5C, 0x0E, 0x74,
++	0x07, 0xB8, 0x89, 0x00, 0x61,
++	0x01, 0x65, 0xFF, 0x78, 0x77,
++	0x09, 0xEF, 0x0B, 0x95, 0x84,
++	0x0F, 0xE9, 0x13, 0xEB, 0xC5,
++	0x01, 0x62, 0x8A, 0xEE, 0x62,
++	0x09, 0x12, 0xEC, 0x29, 0x6A,
++	0x03, 0x7A, 0x6C, 0x41, 0x43,
++	0x03, 0xF6, 0x4B, 0x69, 0xC3,
++	0x03, 0x9B, 0x65, 0x65, 0x1E,
++	0x0F, 0xD1, 0x63, 0xA0, 0x77,
++	0x07, 0xDD, 0x04, 0xBB, 0xE5,
++	0x06, 0xBE, 0xA8, 0x05, 0x21,
++	0x0B, 0xB8, 0x1C, 0xF9, 0x3F,
++	0x0E, 0x12, 0x19, 0xC2, 0xF4,
++	0x04, 0x0E, 0x30, 0xF2, 0x83,
++	0x06, 0x97, 0xD2, 0x04, 0x8E,
++	0x08, 0x2D, 0xAD, 0x86, 0x91,
++	0x08, 0x55, 0x09, 0xC4, 0x40,
++	0x01, 0x18, 0x4C, 0x41, 0x0F,
++	0x0D, 0xDD, 0x4A, 0x39, 0xA7,
++	0x08, 0x92, 0xDF, 0x93, 0xD3,
++	0x04, 0x18, 0xCA, 0x34, 0x3F,
++	0x02, 0xC7, 0xD9, 0x67, 0x8F,
++	0x0A, 0x8D, 0xCD, 0xD8, 0x2D,
++	0x04, 0xD6, 0x6A, 0x5B, 0x97,
++	0x00, 0x39, 0xD2, 0x6C, 0xE8,
++	0x04, 0x33, 0x87, 0xCB, 0xD8,
++	0x07, 0xE2, 0x80, 0x07, 0xAE,
++	0x05, 0x64, 0x12, 0x9D, 0xA3,
++	0x0F, 0x9B, 0x15, 0x2E, 0x09,
++	0x0B, 0x89, 0x88, 0x8D, 0x07,
++	0x0A, 0x7C, 0xB0, 0x8A, 0xE6,
++	0x09, 0x14, 0x2B, 0x6F, 0xD9,
++	0x05, 0xBF, 0x26, 0x86, 0xE2,
++	0x01, 0x94, 0x69, 0x7C, 0x30,
++	0x06, 0x32, 0x6F, 0x11, 0x69,
++	0x02, 0xDB, 0x30, 0x54, 0x7A,
++	0x00, 0x16, 0xAF, 0x2E, 0x20,
++	0x0B, 0x7D, 0x55, 0xD8, 0x48,
++	0x07, 0x0B, 0xDB, 0x30, 0x01,
++	0x03, 0xFE, 0x0F, 0x78, 0x2F,
++	0x06, 0xA5, 0xF6, 0x47, 0x9F,
++	0x0A, 0x1E, 0x47, 0x1B, 0x4E,
++	0x0F, 0x25, 0x00, 0x84, 0x76,
++	0x09, 0x56, 0x1B, 0xDD, 0xB6,
++	0x08, 0x56, 0x9F, 0xBC, 0xCE,
++	0x0E, 0x4D, 0x4C, 0xCE, 0x7E,
++	0x08, 0xD2, 0xF6, 0x87, 0xC3,
++	0x0C, 0x16, 0xD2, 0xC8, 0xC4,
++	0x0E, 0xA9, 0x55, 0xE9, 0x41,
++	0x01, 0x5E, 0xDD, 0xC0, 0x67,
++	0x09, 0xEB, 0xA8, 0x90, 0x4D,
++	0x07, 0xB6, 0x68, 0x74, 0xFD,
++	0x06, 0xFE, 0xE0, 0x3E, 0xB3,
++	0x08, 0x24, 0x8B, 0x2E, 0xEC,
++	0x06, 0xDC, 0x32, 0x9E, 0xA6,
++	0x00, 0x53, 0x00, 0xE2, 0xF1,
++	0x0C, 0x65, 0xA6, 0xE7, 0x6B,
++	0x0D, 0x6D, 0x64, 0x98, 0x79,
++	0x02, 0x1A, 0xA0, 0xCB, 0x15,
++	0x0C, 0xFE, 0x56, 0x37, 0x4F,
++	0x0C, 0x7D, 0xD0, 0x6D, 0x6C,
++	0x01, 0x6B, 0xEA, 0xA6, 0x50,
++	0x0C, 0xBB, 0x81, 0xCA, 0xE6,
++	0x07, 0x51, 0x21, 0x98, 0x99,
++	0x0C, 0xD0, 0xED, 0x21, 0xB1,
++	0x0D, 0xF1, 0x73, 0x14, 0x65,
++	0x05, 0x9E, 0xDC, 0xDA, 0x29,
++	0x0A, 0x6D, 0x5C, 0x4C, 0x04,
++	0x04, 0x11, 0x84, 0xE5, 0x18,
++	0x0F, 0xE4, 0x68, 0xA1, 0xD9,
++	0x0E, 0x63, 0x09, 0xFA, 0x71,
++	0x0A, 0x28, 0x28, 0xA3, 0x8B,
++	0x03, 0x84, 0x95, 0x96, 0xB8,
++	0x0B, 0xA0, 0xD6, 0x5B, 0xC8,
++	0x07, 0xD5, 0x40, 0xA3, 0xE2,
++	0x07, 0x03, 0x9D, 0x20, 0x74,
++	0x0A, 0xC0, 0x18, 0x5C, 0x59,
++	0x08, 0xDC, 0x3B, 0xF0, 0xBB,
++	0x08, 0xE5, 0xDE, 0xA9, 0xD8,
++	0x04, 0x79, 0x11, 0xD2, 0x38,
++	0x0A, 0xB8, 0x9B, 0x04, 0x0E,
++	0x03, 0x09, 0xCA, 0x34, 0x94,
++	0x03, 0x11, 0xE2, 0xB9, 0xFD,
++	0x08, 0x58, 0x5C, 0x6A, 0x46,
++	0x03, 0x19, 0x46, 0x17, 0xF4,
++	0x00, 0x6B, 0x8C, 0x73, 0x77,
++	0x01, 0xAD, 0xBB, 0x07, 0x25,
++	0x00, 0x82, 0xEC, 0xF2, 0xCE,
++	0x0D, 0xFA, 0x4E, 0x5A, 0x03,
++	0x06, 0x70, 0xBD, 0xB3, 0x43,
++	0x0C, 0x3F, 0xE3, 0xF7, 0xC5,
++	0x0C, 0x82, 0x53, 0x34, 0x73,
++	0x03, 0x62, 0xA4, 0xF0, 0x3F,
++	0x01, 0x31, 0x10, 0x09, 0xCC,
++	0x07, 0x95, 0x61, 0x3B, 0x37,
++	0x0E, 0x95, 0x69, 0xFB, 0x27,
++	0x07, 0xE4, 0x57, 0x4C, 0x4C,
++	0x0E, 0x8D, 0x2F, 0xEC, 0xB2,
++	0x0F, 0xD1, 0x03, 0xEE, 0xC3,
++	0x02, 0x76, 0xCB, 0x53, 0x8B,
++	0x0B, 0xC7, 0xA5, 0xD0, 0x0E,
++	0x04, 0x9E, 0xBA, 0x8F, 0x06,
++	0x01, 0x7B, 0x66, 0x83, 0xE5,
++	0x07, 0xC1, 0x6F, 0x8B, 0x9B,
++	0x0C, 0x27, 0xC8, 0xF3, 0xE6,
++	0x0F, 0xA8, 0xFB, 0xED, 0xB9,
++	0x02, 0xE9, 0xF8, 0x18, 0x78,
++	0x0E, 0x52, 0xD1, 0xEE, 0xC5,
++	0x0A, 0x9A, 0x1E, 0xDD, 0x70,
++	0x0D, 0xB8, 0x13, 0x8C, 0xE5,
++	0x03, 0x5F, 0x11, 0x6E, 0x6C,
++	0x0A, 0xC5, 0x9D, 0x2A, 0xB6,
++	0x0C, 0x16, 0xBE, 0xAA, 0x47,
++	0x0B, 0xCB, 0xBA, 0x18, 0x5E,
++	0x07, 0x76, 0x99, 0x19, 0xD2,
++	0x0D, 0xCD, 0x0E, 0xF0, 0xFF,
++	0x03, 0xDF, 0x17, 0x3C, 0x14,
++	0x06, 0xD1, 0x61, 0xC3, 0xCA,
++	0x09, 0xC7, 0x55, 0xC4, 0x3E,
++	0x08, 0x23, 0x18, 0x4E, 0x95,
++	0x0F, 0xF4, 0x1C, 0x8A, 0x15,
++	0x07, 0xEC, 0x92, 0xDB, 0x9A,
++	0x0B, 0x30, 0x1B, 0x47, 0x70,
++	0x0F, 0xA2, 0xC7, 0x54, 0xE2,
++	0x0F, 0xBA, 0x09, 0x6F, 0x5B,
++	0x07, 0x9D, 0x55, 0x8D, 0x24,
++	0x05, 0x70, 0x39, 0xD6, 0xFA,
++	0x0A, 0x24, 0x33, 0x85, 0xED,
++	0x0B, 0xE5, 0x01, 0xF9, 0xCD,
++	0x07, 0x2F, 0xA4, 0x9E, 0x9D,
++	0x03, 0xCF, 0x9B, 0x15, 0x23,
++	0x09, 0xAB, 0x89, 0x8E, 0x40,
++	0x0B, 0xB1, 0x7C, 0xA9, 0x8D,
++	0x08, 0x3B, 0x74, 0x2B, 0x4F,
++	0x09, 0x25, 0xBF, 0x06, 0xA6,
++	0x00, 0x31, 0x94, 0x49, 0x7D,
++	0x05, 0x8E, 0xB2, 0xC9, 0xD5,
++	0x04, 0x1A, 0xDB, 0x94, 0x53,
++	0x0A, 0xA8, 0x13, 0x0F, 0x2C,
++	0x00, 0x73, 0xA2, 0xF5, 0x9E,
++	0x00, 0xE7, 0xAF, 0xDB, 0xCF,
++	0x03, 0xC1, 0xDA, 0x03, 0x7C,
++	0x04, 0x49, 0x81, 0x35, 0x07,
++	0x05, 0xD6, 0x22, 0x40, 0x9A,
++	0x07, 0x13, 0x11, 0x10, 0x84,
++	0x01, 0x39, 0x56, 0x3B, 0xD3,
++	0x02, 0x28, 0x56, 0x8F, 0xB0,
++	0x0B, 0x7E, 0x4D, 0x6C, 0xC2,
++	0x0A, 0xA8, 0x32, 0xFE, 0x4B,
++	0x03, 0xE5, 0x53, 0x3E, 0xE8,
++	0x0D, 0xB7, 0xE0, 0xBB, 0x75,
++	0x08, 0x2B, 0x5E, 0x43, 0x00,
++	0x07, 0x49, 0xEB, 0xBC, 0xD9,
++	0x0E, 0x17, 0xB6, 0x68, 0xC6,
++	0x07, 0xFC, 0x1C, 0xF8, 0x0B,
++	0x0C, 0x55, 0x89, 0x73, 0x0A,
++	0x06, 0xB4, 0x86, 0x31, 0x3A,
++	0x0E, 0xA0, 0x61, 0x0A, 0x42,
++	0x08, 0xAF, 0xF0, 0xA6, 0xEC,
++	0x00, 0xAD, 0x3F, 0x69, 0x9C,
++	0x08, 0x9A, 0x99, 0x1C, 0x86,
++	0x05, 0xA5, 0xFD, 0x1A, 0xBA,
++	0x0B, 0xBC, 0xDD, 0xD0, 0xDA,
++	0x0F, 0xC1, 0xAB, 0xEA, 0x12,
++	0x02, 0xBC, 0xBB, 0xA1, 0xCE,
++	0x03, 0xD7, 0x51, 0x37, 0xDE,
++	0x0F, 0x6C, 0xD0, 0xC9, 0x8D,
++	0x08, 0x3D, 0xF3, 0x73, 0x20,
++	0x0A, 0x6D, 0xD3, 0x7C, 0xD8,
++	0x01, 0x14, 0xED, 0x61, 0x8C,
++	0x0C, 0x00, 0x11, 0xBA, 0x65,
++	0x02, 0x6C, 0x9C, 0xC8, 0xA3,
++	0x00, 0x9E, 0xC1, 0x2A, 0x59,
++	0x05, 0x33, 0x01, 0x9C, 0xA3,
++	0x0B, 0xFA, 0x2C, 0x55, 0x96,
++	0x08, 0xFB, 0xA0, 0xD6, 0x6C,
++	0x02, 0xD7, 0xD5, 0x40, 0x17,
++	0x09, 0x77, 0x03, 0x81, 0x65,
++	0x0E, 0xA2, 0x43, 0x14, 0xDC,
++	0x07, 0x21, 0x13, 0x1F, 0xF0,
++	0x00, 0xE2, 0xE6, 0x41, 0x29,
++	0x04, 0xBC, 0x34, 0xB1, 0x52,
++	0x08, 0xDA, 0xB8, 0xB6, 0x95,
++	0x04, 0x23, 0x0D, 0xEA, 0xB0,
++	0x0C, 0x9B, 0x9D, 0x62, 0x34,
++	0x0F, 0x92, 0x5F, 0xD2, 0xEA,
++	0x04, 0x03, 0x95, 0x66, 0x17,
++	0x06, 0x59, 0x6F, 0x0C, 0x71,
++	0x05, 0xC1, 0x01, 0x9B, 0x85,
++	0x0D, 0x2B, 0x25, 0x6A, 0x72,
++	0x0D, 0x07, 0xF6, 0x7F, 0xDD,
++	0x07, 0x87, 0xB0, 0x8D, 0x33,
++	0x03, 0xBC, 0xBF, 0xD0, 0xF7,
++	0x05, 0xCD, 0x02, 0x63, 0xB4,
++	0x09, 0xF3, 0x62, 0xB2, 0x73,
++	0x05, 0x71, 0x31, 0x06, 0x4A,
++	0x06, 0x13, 0x95, 0x77, 0x3F,
++	0x07, 0x22, 0x85, 0x7F, 0xF9,
++	0x0D, 0x35, 0x84, 0xD8, 0xCC,
++	0x0C, 0x31, 0x5C, 0xAF, 0xF8,
++	0x0A, 0xD6, 0x59, 0xE3, 0xEE,
++	0x03, 0x5B, 0x76, 0x05, 0x42,
++	0x0C, 0x92, 0x75, 0xE8, 0x1C,
++	0x07, 0x74, 0x5E, 0xBA, 0x49,
++	0x02, 0x61, 0xB6, 0x66, 0x87,
++	0x08, 0x7F, 0xC3, 0xFF, 0x82,
++	0x09, 0x04, 0xA7, 0x5E, 0x79,
++	0x0E, 0xC5, 0xC8, 0xF3, 0xEA,
++	0x0A, 0xE2, 0x80, 0x30, 0x0C,
++	0x03, 0x2A, 0xC3, 0x6A, 0xEE,
++	0x01, 0x0A, 0xD3, 0xD6, 0xC9,
++	0x0B, 0xCB, 0xA9, 0xA8, 0x8C,
++	0x01, 0x98, 0x7F, 0xE1, 0xE3,
++	0x0C, 0xB2, 0x47, 0xD3, 0x1B,
++	0x06, 0x6D, 0xB2, 0xBE, 0xAA,
++	0x05, 0x2B, 0xCB, 0xB8, 0x1C,
++	0x0B, 0x3D, 0x75, 0x14, 0x19,
++	0x00, 0xF6, 0xCD, 0x08, 0xB0,
++	0x0F, 0x83, 0x5F, 0x17, 0x32,
++	0x09, 0xCE, 0x71, 0xE7, 0xCD,
++	0x03, 0x13, 0xA6, 0xD9, 0xC4,
++	0x04, 0x40, 0x21, 0x0E, 0x4C,
++	0x05, 0x86, 0xF6, 0xCA, 0xC8,
++	0x0F, 0xA4, 0x31, 0x92, 0xCF,
++	0x03, 0x53, 0x32, 0x38, 0xC3,
++	0x0C, 0xBF, 0x22, 0xE7, 0xD9,
++	0x03, 0x8F, 0xBA, 0x3D, 0xED,
++	0x0C, 0x2D, 0x7D, 0x54, 0x8A,
++	0x07, 0x95, 0x70, 0x39, 0xD2,
++	0x0A, 0xEB, 0xA4, 0x3D, 0x98,
++	0x0D, 0x9A, 0x19, 0xE1, 0xFF,
++	0x07, 0xBE, 0x2E, 0x64, 0x12,
++	0x0F, 0xA3, 0xCD, 0x9D, 0x15,
++	0x03, 0x8D, 0xAB, 0x89, 0x88,
++	0x00, 0x42, 0xB0, 0x9C, 0xAB,
++	0x0D, 0xE9, 0xB9, 0x14, 0x2B,
++	0x0F, 0xD9, 0x25, 0xBF, 0x26,
++	0x0D, 0x60, 0x31, 0x92, 0x6B,
++	0x06, 0xD5, 0x6E, 0xBF, 0x0F,
++	0x01, 0xF4, 0xD7, 0xDB, 0xB0,
++	0x0A, 0xFA, 0xA8, 0x0A, 0xB2,
++	0x0E, 0xE0, 0x73, 0x84, 0xF5,
++	0x06, 0x48, 0x67, 0x1B, 0x5B,
++	0x06, 0x3B, 0xC3, 0xFE, 0x8F,
++	0x0E, 0x54, 0x48, 0x25, 0xBB,
++	0x05, 0x17, 0x96, 0x1A, 0xC7,
++	0x0B, 0x5D, 0x13, 0x01, 0x00,
++	0x04, 0xEB, 0x19, 0x56, 0x1B,
++	0x0B, 0x73, 0xA8, 0x56, 0x1F,
++	0x0A, 0xCA, 0xDE, 0x4D, 0xCC,
++	0x09, 0xE1, 0x48, 0xEE, 0xFE,
++	0x0B, 0x1D, 0x65, 0x88, 0x3C,
++	0x08, 0x35, 0xB7, 0x46, 0xF7,
++	0x0F, 0x53, 0xC7, 0xDE, 0x4D,
++	0x00, 0xE7, 0x49, 0xC5, 0xB5,
++	0x00, 0xCE, 0x17, 0xB6, 0x68,
++	0x05, 0x87, 0xFC, 0x1E, 0x78,
++	0x0B, 0x90, 0x4A, 0x76, 0x0F,
++	0x0E, 0x64, 0xD4, 0x8E, 0x36,
++	0x0E, 0x2C, 0x22, 0x01, 0x08,
++	0x0A, 0x73, 0x2C, 0x37, 0x26,
++	0x04, 0x50, 0xAD, 0x3F, 0x64,
++	0x06, 0xFC, 0x9A, 0x99, 0x80,
++	0x06, 0x51, 0xA5, 0xDB, 0x14,
++	0x01, 0xCB, 0x3C, 0x7D, 0xD0,
++	0x02, 0x6E, 0x01, 0x65, 0xF7,
++	0x08, 0x52, 0x38, 0xB7, 0x41,
++	0x06, 0x13, 0x73, 0x51, 0xDB,
++	0x05, 0xAD, 0x6C, 0xD0, 0x1E,
++	0x05, 0xFC, 0x2D, 0xF1, 0x77,
++	0x09, 0x16, 0xED, 0x1E, 0x8E,
++	0x08, 0xA9, 0x1E, 0x63, 0x15,
++	0x06, 0x40, 0x0E, 0x11, 0x8C,
++	0x0C, 0xD8, 0x8F, 0x4F, 0x48,
++	0x0B, 0x5E, 0x73, 0xC9, 0x3D,
++	0x00, 0xB7, 0x37, 0x0D, 0x0C,
++	0x09, 0x4F, 0xF8, 0x2C, 0x77,
++	0x0E, 0x78, 0x7B, 0xAC, 0x56,
++	0x04, 0x00, 0xD3, 0xD9, 0x00,
++	0x0F, 0x7D, 0x74, 0x83, 0x95,
++	0x0F, 0xAE, 0x22, 0x4F, 0x78,
++	0x06, 0xDB, 0xA5, 0xD2, 0x9F,
++	0x0C, 0x7B, 0xE1, 0xE6, 0x42,
++	0x00, 0xDB, 0xF8, 0xF9, 0xF1,
++	0x00, 0x38, 0xDE, 0xBE, 0x98,
++	0x0A, 0x04, 0x23, 0x0F, 0xCA,
++	0x00, 0xAE, 0x1B, 0x95, 0xF9,
++	0x05, 0x0D, 0x72, 0x56, 0xB6,
++	0x0A, 0x66, 0x03, 0x84, 0xC3,
++	0x07, 0xF4, 0x58, 0x6D, 0x26,
++	0x01, 0xF7, 0x43, 0xAB, 0x71,
++	0x0E, 0x2B, 0xC2, 0x01, 0x4A,
++	0x0A, 0x6E, 0xA7, 0x34, 0xCF,
++	0x04, 0x44, 0x46, 0x7E, 0x7D,
++	0x08, 0xC7, 0xD4, 0xBF, 0xE0,
++	0x0E, 0xC5, 0x0C, 0x8C, 0x4E,
++	0x04, 0x79, 0xF5, 0x6C, 0xED,
++	0x09, 0xB5, 0xF5, 0x3D, 0xD0,
++	0x01, 0xC6, 0xF3, 0x97, 0xE1,
++	0x07, 0x33, 0x2F, 0x05, 0x6B,
++	0x02, 0xA6, 0xD7, 0xE8, 0xD4,
++	0x04, 0x84, 0x36, 0x8D, 0xEF,
++	0x02, 0xB5, 0xD9, 0x59, 0xE7,
++	0x07, 0x03, 0xBB, 0x76, 0xCB,
++	0x03, 0x5D, 0x02, 0x95, 0xD7,
++	0x0C, 0x0E, 0x7A, 0x9A, 0x70,
++	0x01, 0x8C, 0x45, 0x76, 0x26,
++	0x0F, 0xB1, 0xDB, 0xCC, 0x2F,
++	0x03, 0x9B, 0x04, 0xAB, 0x28,
++	0x09, 0xE2, 0xD3, 0x48, 0xEB,
++	0x06, 0xF2, 0x62, 0x20, 0x22,
++	0x0C, 0x27, 0x2A, 0xC7, 0x3E,
++	0x07, 0x8D, 0xEA, 0xD3, 0x36,
++	0x01, 0x6E, 0x29, 0xA4, 0x18,
++	0x06, 0x85, 0x1B, 0xD7, 0xF8,
++	0x03, 0xAC, 0xB3, 0xDB, 0x5F,
++	0x06, 0xB6, 0xEC, 0x12, 0xBA,
++	0x00, 0x01, 0x0C, 0xCB, 0xB9,
++	0x05, 0xB0, 0xFD, 0x79, 0x12,
++	0x00, 0x42, 0x16, 0xCD, 0xCE,
++	0x08, 0xFE, 0x63, 0xD2, 0x92,
++	0x02, 0x09, 0x4E, 0xD5, 0x5C,
++	0x0D, 0x8A, 0x91, 0xC2, 0xD1,
++	0x04, 0xC4, 0x40, 0x25, 0x69,
++	0x00, 0xD5, 0x4B, 0xF4, 0xDC,
++	0x06, 0x33, 0xA7, 0xEC, 0x85,
++	0x0F, 0x93, 0x53, 0x3E, 0xC5,
++	0x02, 0x64, 0x3F, 0x82, 0x47,
++	0x01, 0x4E, 0x0F, 0x9A, 0xCD,
++	0x04, 0xE0, 0xE9, 0x7D, 0x94,
++	0x03, 0x56, 0x57, 0x70, 0xB9,
++	0x02, 0x7A, 0xEA, 0x27, 0x30,
++	0x05, 0xED, 0x9A, 0x1B, 0xFA,
++	0x0F, 0x07, 0xBE, 0x29, 0xFE,
++	0x02, 0x9D, 0xA3, 0xC3, 0xDF,
++	0x0D, 0x6B, 0x0D, 0xA7, 0x09,
++	0x00, 0x02, 0x26, 0x30, 0x5C,
++	0x01, 0x09, 0xCD, 0x39, 0x04,
++	0x01, 0x8F, 0xDE, 0xAD, 0xFE,
++	0x0E, 0xA6, 0xE0, 0x30, 0x14,
++	0x02, 0xFD, 0xEF, 0x8E, 0xB2,
++	0x07, 0x9D, 0x70, 0x1A, 0x2A,
++	0x0A, 0x5E, 0xD9, 0xA8, 0x1C,
++	0x07, 0x2E, 0x60, 0x7F, 0xE4,
++	0x0D, 0x56, 0x4C, 0x67, 0xFA,
++	0x01, 0x30, 0x1F, 0x43, 0xFC,
++	0x07, 0x7C, 0xDC, 0xC4, 0x65,
++	0x02, 0xC5, 0xFF, 0x3A, 0x2A,
++	0x07, 0x1B, 0x57, 0x07, 0x13,
++	0x00, 0x84, 0x61, 0x3A, 0x67,
++	0x0B, 0xD3, 0x72, 0x28, 0x12,
++	0x05, 0xB6, 0x52, 0x7E, 0x5D,
++	0x00, 0xC0, 0x66, 0xA8, 0xD1,
++	0x0E, 0x8B, 0x1D, 0x66, 0x9B,
++	0x0E, 0xE8, 0x35, 0xBA, 0x24,
++	0x0D, 0x75, 0xF0, 0x27, 0xDE,
++	0x04, 0xC0, 0x27, 0x47, 0xEB,
++	0x01, 0x91, 0x0E, 0x17, 0xF6,
++	0x04, 0x77, 0x86, 0xBC, 0x2F,
++	0x03, 0x3B, 0xDA, 0xCE, 0xCD,
++	0x07, 0xBE, 0xCC, 0x5A, 0x0E,
++	0x0F, 0xAE, 0xE6, 0x2C, 0xC1,
++	0x08, 0xC2, 0x72, 0xAF, 0x05,
++	0x0D, 0x66, 0x1A, 0x2E, 0x4C,
++	0x08, 0x96, 0xFE, 0x9A, 0x97,
++	0x0C, 0xC6, 0x52, 0xA5, 0xFE,
++	0x0F, 0xBA, 0x2B, 0x32, 0x60,
++	0x09, 0xEA, 0x9A, 0xC1, 0x2B,
++	0x0A, 0xA0, 0x52, 0xB0, 0x3E,
++	0x01, 0xCE, 0x93, 0xD7, 0xA0,
++	0x01, 0x9C, 0x2F, 0x68, 0x0D,
++	0x0F, 0x0F, 0xFC, 0x39, 0x03,
++	0x0B, 0xA0, 0x34, 0xED, 0xDE,
++	0x05, 0x58, 0x49, 0x1C, 0xAD,
++	0x07, 0xC8, 0x0C, 0x02, 0x11,
++	0x04, 0xE5, 0x5A, 0x69, 0x47,
++	0x08, 0xA1, 0x5A, 0x7A, 0x70,
++	0x04, 0x7B, 0x55, 0x3F, 0x01,
++	0x06, 0xA7, 0x79, 0xFA, 0x3C,
++	0x0C, 0x16, 0x98, 0xE7, 0x3D,
++	0x0E, 0x5F, 0xA6, 0xDB, 0xD5,
++	0x0A, 0xA1, 0x48, 0xF7, 0x13,
++	0x06, 0xA3, 0xCA, 0x22, 0x43,
++	0x02, 0x5A, 0xE9, 0xA1, 0xCE,
++	0x06, 0xF2, 0x3B, 0xEF, 0x26,
++	0x01, 0x29, 0xDA, 0x3F, 0xBD,
++	0x01, 0x52, 0x38, 0xDE, 0x01,
++	0x08, 0x88, 0x04, 0x2F, 0xCC,
++	0x06, 0xB0, 0xDF, 0x5B, 0x9F,
++	0x0E, 0xB4, 0xFF, 0x12, 0x58,
++	0x0E, 0x6A, 0x65, 0x03, 0x1A,
++	0x0F, 0x17, 0x14, 0x56, 0xF6,
++	0x05, 0x70, 0x17, 0x41, 0xED,
++	0x03, 0x84, 0x4F, 0xAA, 0xC1,
++	0x0A, 0xF2, 0xFA, 0x07, 0xC0,
++	0x0F, 0x5D, 0x44, 0x82, 0x0B,
++	0x0D, 0xB3, 0x43, 0xBC, 0xCC,
++	0x00, 0xF7, 0xC5, 0xC8, 0x5F,
++	0x03, 0xB4, 0x7D, 0xF7, 0x90,
++	0x0C, 0xF1, 0x15, 0x71, 0xF1,
++	0x09, 0x88, 0xA6, 0x13, 0x55,
++	0x0A, 0x39, 0x7F, 0x22, 0x85,
++	0x0D, 0xFB, 0x24, 0xB1, 0xE4,
++	0x04, 0xCC, 0x06, 0x32, 0x8D,
++	0x0E, 0xE8, 0x71, 0xD2, 0xE0,
++	0x0B, 0xD4, 0xC3, 0x57, 0xB6,
++	0x01, 0x5B, 0x16, 0x82, 0x9D,
++	0x0C, 0xE4, 0xCE, 0x78, 0x5E,
++	0x0A, 0x89, 0x0C, 0xE1, 0x7B,
++	0x0F, 0x05, 0x18, 0x73, 0xC1,
++	0x0F, 0x8B, 0x9B, 0x02, 0x2D,
++	0x02, 0xF7, 0xD9, 0x45, 0x58,
++	0x0A, 0xEA, 0x02, 0x7E, 0xBD,
++	0x08, 0x0E, 0x03, 0x26, 0xC3,
++	0x00, 0x6A, 0x7A, 0x0A, 0xC3,
++	0x0D, 0xCD, 0x0B, 0x49, 0xA9,
++	0x02, 0x08, 0x58, 0x9A, 0x4F,
++	0x0A, 0x63, 0xAC, 0xB3, 0xC7,
++	0x03, 0x86, 0x7B, 0xEC, 0x16,
++	0x06, 0xAF, 0x85, 0x26, 0x18,
++	0x08, 0x1C, 0xE9, 0x33, 0xA8,
++	0x02, 0x19, 0xC6, 0xD2, 0xD9,
++	0x0E, 0xF0, 0xF9, 0xD3, 0xD6,
++	0x07, 0x32, 0x0D, 0x4E, 0x5B,
++	0x03, 0xCD, 0x88, 0x91, 0x46,
++	0x0D, 0xFC, 0x44, 0x4C, 0x61,
++	0x08, 0x07, 0xD5, 0x86, 0xF4,
++	0x00, 0x8A, 0x35, 0xA7, 0xEF,
++	0x0B, 0xDD, 0x93, 0x53, 0x70,
++	0x02, 0xCE, 0x7B, 0x3F, 0xAA,
++	0x0B, 0x59, 0x67, 0x8F, 0xAD,
++	0x05, 0x1D, 0x58, 0x2B, 0x7D,
++	0x0E, 0x0E, 0x05, 0x17, 0x71,
++	0x05, 0xE2, 0x7A, 0xEA, 0x27,
++	0x03, 0x85, 0xED, 0x9E, 0x16,
++	0x08, 0xFF, 0xC7, 0xBF, 0xF9,
++	0x0D, 0x13, 0x5D, 0xA3, 0x8F,
++	0x03, 0x3D, 0xA3, 0x8B, 0xAB,
++	0x09, 0x88, 0x80, 0x46, 0xA7,
++	0x05, 0x93, 0xCD, 0xE5, 0xFA,
++	0x04, 0x2B, 0x4F, 0xD9, 0x25,
++	0x0F, 0x26, 0xA6, 0x60, 0x31,
++	0x0D, 0x41, 0xBF, 0x43, 0x0E,
++	0x0B, 0xE6, 0xDF, 0x34, 0x9A,
++	0x09, 0xB0, 0x5E, 0xD7, 0xA8,
++	0x04, 0xAF, 0x2E, 0xD6, 0x68,
++	0x04, 0xAD, 0x54, 0x4F, 0xFD,
++	0x02, 0xD9, 0x34, 0x3B, 0x03,
++	0x0E, 0x0F, 0x7C, 0x5C, 0xC8,
++	0x03, 0x3B, 0x47, 0x9B, 0xB6,
++	0x0A, 0x47, 0x1B, 0x57, 0x13,
++	0x01, 0xF0, 0x24, 0x65, 0x7A,
++	0x0C, 0xDB, 0xD4, 0xFA, 0x9B,
++	0x0F, 0x9F, 0x72, 0x4A, 0xFE,
++	0x05, 0x4E, 0x80, 0x65, 0x19,
++	0x08, 0xFA, 0xD0, 0x9D, 0x67,
++	0x07, 0x3E, 0x28, 0x39, 0xF7,
++	0x08, 0xB7, 0xB1, 0x50, 0xD8,
++	0x04, 0x59, 0x9D, 0xE7, 0x41,
++	0x02, 0xA8, 0x50, 0xC2, 0x57,
++	0x0F, 0x6A, 0x37, 0x8B, 0xBC,
++	0x0E, 0xF8, 0xB9, 0x90, 0x4A,
++	0x00, 0x8F, 0x3E, 0x68, 0xD4,
++	0x0E, 0x36, 0xAE, 0x26, 0x22,
++	0x00, 0x78, 0x02, 0x72, 0xAC,
++	0x07, 0xA6, 0xE4, 0x50, 0xAD,
++	0x0F, 0x64, 0x96, 0xFA, 0xC1,
++	0x09, 0x80, 0xC6, 0x56, 0x3F,
++	0x07, 0xD6, 0x30, 0xC3, 0xFF,
++	0x05, 0xD0, 0xEB, 0x6F, 0x41,
++	0x00, 0x68, 0x0A, 0x52, 0xBC,
++	0x02, 0x81, 0x0C, 0x9D, 0x9E,
++	0x08, 0x20, 0x5C, 0xA3, 0x6C,
++	0x08, 0x6F, 0xAF, 0xF8, 0x7D,
++	0x0A, 0x73, 0x20, 0x94, 0x9C,
++	0x02, 0x7C, 0xD9, 0xE9, 0x1F,
++	0x04, 0x95, 0xAC, 0x48, 0x02,
++	0x09, 0x04, 0x45, 0x56, 0xAF,
++	0x05, 0xC8, 0x21, 0x54, 0xFE,
++	0x01, 0xAC, 0x59, 0x35, 0x73,
++	0x09, 0x8E, 0xA3, 0x47, 0xFA,
++	0x0C, 0x75, 0x96, 0x7C, 0x80,
++	0x0B, 0xD6, 0xDD, 0x86, 0xED,
++	0x05, 0x40, 0xA5, 0x7D, 0xEA,
++	0x0A, 0xD4, 0xE3, 0xA2, 0xA2,
++	0x0B, 0x38, 0xDA, 0xD9, 0x61,
++	0x0E, 0x1F, 0xF0, 0x7B, 0x10,
++	0x08, 0xC1, 0xE4, 0xDA, 0x3C,
++	0x00, 0x31, 0xB2, 0x08, 0xDA,
++	0x02, 0x78, 0x91, 0x0C, 0xF9,
++	0x09, 0xCA, 0xB0, 0xCE, 0x9B,
++	0x01, 0x42, 0xB4, 0xFD, 0x92,
++	0x02, 0x73, 0x8A, 0x66, 0x83,
++	0x09, 0x46, 0x95, 0xDA, 0x11,
++	0x0B, 0x2C, 0xF1, 0xF7, 0x41,
++	0x0D, 0xBB, 0x05, 0xAF, 0xAA,
++	0x08, 0xC8, 0x92, 0x6E, 0x87,
++	0x00, 0x4B, 0x2C, 0x44, 0x82,
++	0x00, 0xBD, 0xB3, 0xC3, 0xBC,
++	0x0F, 0xE0, 0xF4, 0x45, 0xCC,
++	0x06, 0x53, 0xB6, 0x7F, 0x33,
++	0x0B, 0x24, 0x91, 0xB5, 0xF1,
++	0x00, 0x91, 0xE8, 0x46, 0x13,
++	0x05, 0x61, 0xBD, 0x37, 0x22,
++	0x0D, 0x6B, 0xFB, 0x28, 0xB7,
++	0x04, 0xD4, 0xCC, 0x20, 0xF0,
++	0x07, 0x2B, 0x82, 0x31, 0xC6,
++	0x01, 0x61, 0xCE, 0x8F, 0x5B,
++	0x0C, 0x0F, 0x37, 0xD5, 0x12,
++	0x0E, 0xE5, 0xDC, 0x0E, 0x74,
++	0x02, 0xBA, 0x8A, 0x0C, 0xE2,
++	0x02, 0x66, 0x47, 0x76, 0x62,
++	0x08, 0xEE, 0x4F, 0x99, 0x44,
++	0x0F, 0xE8, 0x57, 0xE6, 0x3F,
++	0x00, 0xE3, 0xEE, 0xEC, 0x22,
++	0x09, 0x92, 0x8C, 0x27, 0xDB,
++	0x03, 0x7A, 0x6C, 0x48, 0x43,
++	0x09, 0xF2, 0xC2, 0x6F, 0xC1,
++	0x00, 0x18, 0xEC, 0x67, 0x9A,
++	0x05, 0xD5, 0xEF, 0xAC, 0xA3,
++	0x0E, 0x5F, 0x06, 0x36, 0x1E,
++	0x0C, 0xBA, 0xD6, 0x85, 0x23,
++	0x03, 0xB8, 0x9C, 0xE5, 0xBD,
++	0x0C, 0x90, 0x19, 0xCE, 0xB6,
++	0x07, 0x0A, 0x8E, 0xFF, 0x81,
++	0x07, 0x17, 0xB2, 0x05, 0x0E,
++	0x08, 0x65, 0xCD, 0x86, 0xD1,
++	0x06, 0xD5, 0xC4, 0xC0, 0xFB,
++	0x0D, 0x18, 0x4F, 0x95, 0xB7,
++	0x04, 0xDC, 0x88, 0x13, 0x6D,
++	0x0C, 0x92, 0xDF, 0x9F, 0x97,
++	0x0B, 0x9A, 0x80, 0xB9, 0xBA,
++	0x0A, 0x47, 0xF9, 0x69, 0x0F,
++	0x03, 0x0D, 0xAD, 0xD6, 0xED,
++	0x06, 0xD6, 0x40, 0xDA, 0xE1,
++	0x00, 0x39, 0xD0, 0x77, 0xA3,
++	0x04, 0x33, 0x85, 0x63, 0x87,
++	0x01, 0xE1, 0xFE, 0x47, 0xB0,
++	0x08, 0x64, 0x04, 0x9F, 0x23,
++	0x03, 0x91, 0x15, 0x23, 0x94,
++	0x0A, 0x21, 0x68, 0x80, 0x42,
++	0x08, 0x9C, 0x2B, 0x00, 0xEC,
++	0x01, 0x15, 0xAB, 0x42, 0x19,
++	0x07, 0xBF, 0x26, 0xA0, 0xA0,
++	0x01, 0x94, 0x69, 0x7B, 0x41,
++	0x0F, 0x32, 0x2F, 0x1F, 0x74,
++	0x02, 0x5B, 0x10, 0x54, 0x7A,
++	0x01, 0x14, 0x6F, 0x20, 0x20,
++	0x08, 0x20, 0x5A, 0x52, 0xB2,
++	0x07, 0x0B, 0xDF, 0x34, 0xCA,
++	0x03, 0xFE, 0x0D, 0x71, 0x15,
++	0x00, 0x25, 0xBB, 0x49, 0xDF,
++	0x0F, 0xAA, 0xA7, 0x19, 0xD7,
++	0x09, 0x15, 0x8C, 0x04, 0x63,
++	0x00, 0xD4, 0x7B, 0xDF, 0x72,
++	0x01, 0x54, 0x9B, 0xBE, 0x0B,
++	0x04, 0x49, 0xC2, 0xC0, 0x67,
++	0x01, 0x52, 0x1E, 0x8B, 0xDD,
++	0x09, 0x9E, 0x3D, 0xE8, 0x36,
++	0x07, 0x60, 0xB7, 0xF1, 0x9A,
++	0x00, 0x5E, 0x9D, 0xCE, 0xFA,
++	0x00, 0xEA, 0x68, 0x90, 0x8E,
++	0x0F, 0x36, 0xC8, 0x77, 0x47,
++	0x04, 0x1E, 0x78, 0xB5, 0x50,
++	0x03, 0xF6, 0x6F, 0x33, 0x6C,
++	0x0C, 0x8F, 0xB6, 0xA3, 0xE6,
++	0x0B, 0x80, 0xE8, 0xCF, 0xB2,
++	0x0C, 0x37, 0xA6, 0xE0, 0x54,
++	0x0D, 0x3F, 0x64, 0x92, 0x39,
++	0x06, 0x99, 0x81, 0x06, 0x60,
++	0x05, 0xFD, 0x16, 0x3E, 0x56,
++	0x0C, 0x7D, 0xD0, 0x6F, 0xD5,
++	0x09, 0x6B, 0x6A, 0xA0, 0x92,
++	0x02, 0x3B, 0x4C, 0xCE, 0x93,
++	0x0E, 0x51, 0xE3, 0x91, 0x66,
++	0x05, 0xD1, 0x2E, 0x23, 0xF8,
++	0x01, 0xF1, 0x71, 0x60, 0x9A,
++	0x09, 0x1E, 0x7C, 0xD8, 0x29,
++	0x08, 0x6D, 0x5E, 0x4C, 0xC4,
++	0x03, 0xF1, 0x64, 0xEB, 0x45,
++	0x0E, 0x2D, 0x1C, 0xA5, 0xEF,
++	0x02, 0xC9, 0x2C, 0xB9, 0x3B,
++	0x03, 0x01, 0x84, 0xAD, 0x95,
++	0x08, 0x2C, 0x61, 0x90, 0xF8,
++	0x0B, 0xA0, 0xD6, 0xD0, 0x51,
++	0x06, 0x57, 0x20, 0xE6, 0x3A,
++	0x0D, 0x07, 0x00, 0x27, 0xA6,
++	0x0B, 0xC3, 0xD8, 0x5E, 0xD9,
++	0x08, 0xDC, 0x7F, 0xF0, 0xFB,
++	0x08, 0xE2, 0xDE, 0x29, 0xD2,
++	0x0C, 0xF9, 0xB5, 0x52, 0x38,
++	0x0A, 0xB8, 0x94, 0x88, 0x04,
++	0x01, 0x09, 0xC2, 0xB6, 0x5E,
++	0x02, 0x91, 0x82, 0xB4, 0x7D,
++	0x03, 0x5A, 0x32, 0x6A, 0x66,
++	0x0B, 0x1B, 0x46, 0x9B, 0xF4,
++	0x08, 0xEB, 0x2C, 0xF1, 0xB2,
++	0x01, 0xAD, 0xBB, 0x23, 0x2D,
++	0x00, 0x85, 0xDF, 0x72, 0xFE,
++	0x0E, 0x3A, 0x8F, 0x53, 0x84,
++	0x0F, 0x71, 0x7D, 0xBF, 0x03,
++	0x04, 0xBD, 0xC0, 0xFB, 0xC5,
++	0x06, 0x86, 0xC7, 0xB4, 0x69,
++	0x03, 0x62, 0xA4, 0x7D, 0x71,
++	0x09, 0x31, 0x90, 0x45, 0x86,
++	0x03, 0x95, 0x61, 0xBD, 0x35,
++	0x0C, 0x05, 0xA4, 0xFB, 0x24,
++	0x0B, 0xE4, 0xD6, 0x4C, 0x08,
++	0x0B, 0xC0, 0xEF, 0xC5, 0x62,
++	0x06, 0x59, 0xE3, 0xF0, 0x9E,
++	0x0B, 0x76, 0x0B, 0x4B, 0xC1,
++	0x0B, 0x85, 0x25, 0xEC, 0x8E,
++	0x0D, 0x9F, 0x7A, 0xD9, 0x8C,
++	0x08, 0x6A, 0xB2, 0xB7, 0xF8,
++	0x0F, 0xC1, 0xEB, 0xCB, 0x99,
++	0x06, 0xA7, 0x6C, 0xB3, 0x66,
++	0x07, 0x48, 0xE3, 0x4C, 0x62,
++	0x03, 0x20, 0xD0, 0x8C, 0x27,
++	0x0B, 0xA2, 0xBA, 0x6E, 0x45,
++	0x02, 0xD1, 0xF6, 0x45, 0x6F,
++	0x01, 0x63, 0x98, 0x00, 0x65,
++	0x0A, 0x5F, 0xD1, 0x65, 0x2E,
++	0x09, 0xC3, 0x7B, 0x06, 0xA6,
++	0x0C, 0x16, 0xBE, 0xBA, 0x05,
++	0x00, 0xCB, 0xB8, 0x1C, 0xEB,
++	0x0D, 0x75, 0x12, 0x1D, 0x5F,
++	0x0A, 0xCF, 0x0E, 0xF0, 0xC4,
++	0x0B, 0xDF, 0x97, 0x32, 0xC9,
++	0x00, 0x51, 0x2A, 0xCD, 0x8A,
++	0x0D, 0xC6, 0xD4, 0x44, 0xCA,
++	0x00, 0x21, 0x18, 0x40, 0x48,
++	0x06, 0xF4, 0xC8, 0x8E, 0x8B,
++	0x07, 0xEC, 0x92, 0xDB, 0x10,
++	0x0A, 0x30, 0xD8, 0xEA, 0xB4,
++	0x06, 0x9B, 0x07, 0x59, 0xA7,
++	0x06, 0x38, 0x4D, 0x63, 0x18,
++	0x07, 0x79, 0xE3, 0x0A, 0x5F,
++	0x0B, 0x70, 0x39, 0xD2, 0x6D,
++	0x03, 0x44, 0xF3, 0x83, 0x6D,
++	0x00, 0x19, 0x5B, 0xFF, 0x06,
++	0x02, 0x16, 0x64, 0x12, 0x9E,
++	0x03, 0xCF, 0x9B, 0x11, 0xA8,
++	0x04, 0x2B, 0x69, 0x89, 0x57,
++	0x0B, 0xB1, 0x7C, 0xAB, 0x4D,
++	0x00, 0x91, 0xD4, 0x2D, 0xCF,
++	0x09, 0x25, 0xBF, 0x22, 0x71,
++	0x09, 0x89, 0x7C, 0x69, 0xBF,
++	0x05, 0x8E, 0xB2, 0xCB, 0x5C,
++	0x0C, 0x9A, 0x79, 0xBD, 0xD3,
++	0x03, 0x00, 0xF4, 0x29, 0xEE,
++	0x09, 0xDA, 0x44, 0x55, 0x54,
++	0x00, 0xE6, 0xAF, 0xD7, 0x34,
++	0x0B, 0xC3, 0xFA, 0x09, 0xE7,
++	0x0C, 0xC8, 0x21, 0x3C, 0x9D,
++	0x05, 0xF6, 0x20, 0x4E, 0x66,
++	0x0E, 0x13, 0xD1, 0x01, 0x04,
++	0x08, 0xBB, 0x12, 0x1B, 0x21,
++	0x08, 0x2C, 0x96, 0x1F, 0xB0,
++	0x02, 0x7E, 0x8D, 0x40, 0x40,
++	0x0A, 0xAA, 0x9A, 0xFE, 0x79,
++	0x07, 0x61, 0x5C, 0x3E, 0xE0,
++	0x0C, 0xB7, 0xA0, 0xB9, 0x75,
++	0x09, 0x2B, 0x1E, 0x5F, 0x40,
++	0x0D, 0x4D, 0x2F, 0xA8, 0x98,
++	0x0E, 0x17, 0xB2, 0x68, 0x77,
++	0x07, 0xFC, 0x12, 0xF8, 0xB9,
++	0x02, 0x4A, 0x7A, 0x89, 0xBE,
++	0x05, 0xD4, 0x62, 0x34, 0x2E,
++	0x07, 0x22, 0xCD, 0x06, 0x48,
++	0x02, 0xAC, 0x3B, 0xA2, 0x92,
++	0x08, 0x2D, 0x93, 0x64, 0xD6,
++	0x08, 0x9A, 0x99, 0x86, 0x46,
++	0x0D, 0xAF, 0xFD, 0x16, 0x23,
++	0x0A, 0x95, 0x9D, 0xD0, 0x6B,
++	0x07, 0xC1, 0xAB, 0xEA, 0xE0,
++	0x0A, 0xBE, 0xBB, 0x8D, 0xCE,
++	0x03, 0xD7, 0x53, 0x27, 0x56,
++	0x05, 0x68, 0x61, 0xEF, 0x1F,
++	0x01, 0x3C, 0x31, 0x7F, 0x60,
++	0x0C, 0x6F, 0x3E, 0x70, 0xD8,
++	0x03, 0x18, 0xC2, 0xDC, 0x5C,
++	0x0F, 0x02, 0x11, 0x84, 0xE5,
++	0x00, 0x6F, 0xCD, 0xC6, 0xBC,
++	0x02, 0x27, 0x4D, 0x21, 0xE8,
++	0x0D, 0xB0, 0x27, 0x81, 0xAA,
++	0x0B, 0xFA, 0x2A, 0x75, 0x9C,
++	0x08, 0xFB, 0xA4, 0xD2, 0xA9,
++	0x02, 0xD7, 0xD1, 0x4C, 0x61,
++	0x09, 0x77, 0x03, 0xB1, 0xA2,
++	0x0E, 0xA2, 0x43, 0x18, 0xA4,
++	0x09, 0xA1, 0xDE, 0x1B, 0xED,
++	0x0B, 0xE2, 0xE6, 0x45, 0x12,
++	0x03, 0xBC, 0x19, 0xB1, 0x92,
++	0x06, 0x5A, 0x75, 0x98, 0x88,
++	0x04, 0x23, 0x0B, 0xE4, 0xAD,
++	0x06, 0x9B, 0x91, 0x4C, 0x6A,
++	0x05, 0x2A, 0xFF, 0xF2, 0xAA,
++	0x0E, 0x82, 0xB9, 0x66, 0x17,
++	0x04, 0x58, 0xEB, 0x2C, 0xF1,
++	0x0F, 0x41, 0x29, 0xB6, 0xC5,
++	0x0D, 0xAA, 0x89, 0x4C, 0xB2,
++	0x0C, 0x07, 0x3E, 0x49, 0x1D,
++	0x04, 0x4E, 0xD8, 0xBD, 0xBA,
++	0x02, 0xF4, 0xF7, 0xE0, 0x3D,
++	0x0D, 0xCE, 0x82, 0x53, 0x74,
++	0x03, 0xF7, 0xBB, 0xA4, 0x75,
++	0x0D, 0xF1, 0x91, 0x16, 0x88,
++	0x06, 0x13, 0x95, 0x61, 0x77,
++	0x07, 0x22, 0x81, 0x5A, 0xF8,
++	0x04, 0xB7, 0xE4, 0xD4, 0xCC,
++	0x04, 0x32, 0x85, 0x29, 0xA8,
++	0x01, 0xD6, 0x59, 0xE3, 0xEE,
++	0x03, 0xBB, 0xD6, 0x0B, 0x5F,
++	0x05, 0x02, 0x95, 0xE5, 0xDC,
++	0x0E, 0x74, 0x9E, 0xBA, 0x89,
++	0x0E, 0xE1, 0x73, 0x60, 0xC7,
++	0x01, 0x7F, 0x01, 0xEF, 0x0B,
++	0x09, 0x24, 0x27, 0x65, 0xB7,
++	0x06, 0xC5, 0x48, 0xF3, 0x6A,
++	0x0B, 0x60, 0x60, 0x16, 0xCC,
++	0x0F, 0x28, 0x83, 0x7C, 0x5C,
++	0x0F, 0x0E, 0x32, 0xF6, 0x59,
++	0x06, 0xC9, 0x69, 0x94, 0x8C,
++	0x05, 0x1A, 0x5F, 0xD1, 0x63,
++	0x0E, 0xB3, 0xC7, 0xDD, 0x86,
++	0x04, 0xEC, 0x12, 0xB8, 0x2A,
++	0x04, 0x2A, 0x0B, 0xBB, 0x29,
++	0x08, 0x3F, 0x35, 0x1E, 0x08,
++	0x06, 0xF6, 0xCD, 0x08, 0xB0,
++	0x07, 0x80, 0xDF, 0x1A, 0x3B,
++	0x09, 0x87, 0x11, 0xE7, 0x89,
++	0x0A, 0x91, 0xC6, 0xD1, 0xF0,
++	0x06, 0x40, 0x29, 0x14, 0x0E,
++	0x05, 0x86, 0xF0, 0xDA, 0xD1,
++	0x05, 0x47, 0x4C, 0x95, 0x45,
++	0x09, 0x93, 0x3A, 0x11, 0x04,
++	0x0C, 0xBF, 0x22, 0xC6, 0xD9,
++	0x0C, 0x0D, 0x10, 0x0B, 0x27,
++	0x08, 0x2D, 0x79, 0x54, 0x0A,
++	0x05, 0x97, 0x74, 0x38, 0x52,
++	0x08, 0xEA, 0x24, 0x35, 0x85,
++	0x0D, 0x9A, 0x9D, 0xE1, 0xFF,
++	0x07, 0xBF, 0xAE, 0x64, 0x12,
++	0x05, 0x21, 0xCF, 0x99, 0x95,
++	0x09, 0x89, 0x47, 0x89, 0x8A,
++	0x00, 0x42, 0x30, 0x9A, 0xA1,
++	0x04, 0x6B, 0xDB, 0x18, 0x2B,
++	0x05, 0xDD, 0xF4, 0x3F, 0x36,
++	0x0E, 0x60, 0xB1, 0x9A, 0xA9,
++	0x07, 0x1C, 0x0E, 0xBE, 0xCF,
++	0x07, 0xF4, 0xBA, 0xD5, 0x30,
++	0x02, 0x78, 0x88, 0x18, 0xAF,
++	0x0E, 0xE0, 0x73, 0xA0, 0xCE,
++	0x04, 0x48, 0x67, 0x0F, 0xA1,
++	0x04, 0x3B, 0xC1, 0xF0, 0xD2,
++	0x0C, 0x5C, 0xCA, 0x25, 0x31,
++	0x0D, 0x9B, 0xE7, 0x2A, 0x57,
++	0x07, 0x57, 0x07, 0x11, 0x03,
++	0x0C, 0x61, 0xB9, 0x58, 0x1B,
++	0x0B, 0x73, 0xA8, 0x56, 0xDF,
++	0x0E, 0x54, 0x81, 0xB1, 0x7E,
++	0x00, 0x63, 0x2A, 0xD6, 0xE3,
++	0x03, 0x0D, 0xE1, 0x90, 0x7E,
++	0x08, 0x35, 0xB7, 0x60, 0x76,
++	0x0D, 0x52, 0x29, 0x5E, 0x9D,
++	0x0A, 0xE3, 0xBE, 0xEB, 0xAA,
++	0x08, 0xCE, 0x97, 0xBA, 0xE8,
++	0x0D, 0x82, 0xF8, 0x9E, 0xF9,
++	0x01, 0x98, 0xCA, 0x78, 0xCF,
++	0x06, 0x6E, 0x50, 0x8E, 0xC4,
++	0x04, 0x22, 0xD9, 0x81, 0x0A,
++	0x0A, 0x72, 0x28, 0x35, 0x26,
++	0x0C, 0x51, 0x2D, 0x3F, 0xA4,
++	0x0E, 0x7E, 0x9A, 0x99, 0x40,
++	0x0C, 0x55, 0x5E, 0xFD, 0x1E,
++	0x02, 0xCB, 0xBC, 0x7D, 0x10,
++	0x01, 0x6B, 0xC5, 0xEB, 0xEB,
++	0x08, 0x52, 0x3C, 0xB5, 0xC1,
++	0x06, 0x91, 0xD7, 0x5D, 0xA1,
++	0x06, 0x2A, 0x6C, 0x50, 0xED,
++	0x07, 0xF8, 0xB9, 0xF3, 0xF3,
++	0x08, 0x9D, 0x69, 0x1E, 0xBC,
++	0x08, 0xA9, 0x1C, 0x6D, 0x5C,
++	0x04, 0xC6, 0x02, 0x11, 0x44,
++	0x0F, 0x5D, 0x6F, 0x4D, 0xC0,
++	0x09, 0x5A, 0xFE, 0xC9, 0xED,
++	0x03, 0x30, 0x37, 0x81, 0x8D,
++	0x0F, 0x7F, 0xFA, 0x2C, 0x62,
++	0x0E, 0x78, 0x7B, 0xAE, 0x96,
++	0x05, 0xA8, 0xD7, 0xD9, 0xC0,
++	0x0F, 0x7C, 0x73, 0x03, 0x95,
++	0x0F, 0xAE, 0x22, 0x41, 0xB8,
++	0x06, 0xCB, 0xA1, 0xDE, 0xDF,
++	0x0A, 0x7E, 0xE6, 0x66, 0x40,
++	0x01, 0xDA, 0xBC, 0xFB, 0x31,
++	0x0A, 0xBA, 0xDA, 0xB8, 0xD2,
++	0x02, 0x01, 0x25, 0x09, 0xC8,
++	0x00, 0xDE, 0x9B, 0x97, 0x48,
++	0x04, 0xFD, 0x90, 0x5B, 0xF2,
++	0x01, 0x66, 0x03, 0x1B, 0xFC,
++	0x07, 0xF4, 0x58, 0xE6, 0xA8,
++	0x01, 0xF7, 0x41, 0x81, 0xFE,
++	0x0D, 0x2F, 0x0A, 0xAD, 0x8A,
++	0x0A, 0x6F, 0xA7, 0x16, 0x5E,
++	0x04, 0x47, 0xC6, 0x5D, 0xBD,
++	0x03, 0x43, 0xBC, 0x3B, 0x93,
++	0x0E, 0x45, 0x2C, 0x8F, 0x93,
++	0x0D, 0xB3, 0x93, 0x6E, 0xA4,
++	0x0F, 0x35, 0xBC, 0x31, 0x10,
++	0x08, 0x46, 0x11, 0x81, 0xE8,
++	0x04, 0x36, 0xE2, 0xA9, 0x69,
++	0x0F, 0x24, 0xB7, 0xE4, 0x54,
++	0x08, 0x06, 0x32, 0x8D, 0xAF,
++	0x0E, 0xB1, 0x56, 0x5B, 0x63,
++	0x0E, 0x03, 0xFB, 0x75, 0x08,
++	0x0F, 0x55, 0x82, 0x99, 0x21,
++	0x0C, 0x0E, 0x74, 0x88, 0xB8,
++	0x09, 0x0C, 0xE1, 0x5D, 0x24,
++	0x07, 0x78, 0x7D, 0xC1, 0xE7,
++	0x0B, 0x99, 0x04, 0xA1, 0x62,
++	0x07, 0xE6, 0xC5, 0x58, 0x63,
++	0x0A, 0xE2, 0x62, 0x20, 0x10,
++	0x0C, 0x27, 0xAA, 0xC0, 0x49,
++	0x0E, 0x45, 0x0A, 0xDE, 0xB2,
++	0x00, 0xED, 0xA9, 0xB5, 0x98,
++	0x0C, 0x65, 0x1A, 0x59, 0xD3,
++	0x03, 0xAC, 0xB3, 0xC4, 0xE8,
++	0x06, 0xB6, 0xEC, 0x16, 0xFA,
++	0x00, 0x00, 0x20, 0xCB, 0xA8,
++	0x07, 0xE9, 0x3D, 0x75, 0x12,
++	0x09, 0xC2, 0xF6, 0xC3, 0x13,
++	0x00, 0xFF, 0x83, 0xD2, 0x93,
++	0x02, 0x09, 0x4E, 0xDC, 0xE2,
++	0x07, 0x6A, 0x90, 0x4C, 0xE4,
++	0x0D, 0xC4, 0x80, 0x01, 0x1A,
++	0x0E, 0x55, 0x86, 0xD4, 0xDC,
++	0x02, 0x15, 0x23, 0xC1, 0x52,
++	0x07, 0x91, 0x57, 0x10, 0xE3,
++	0x0A, 0x34, 0xBF, 0x92, 0x1B,
++	0x09, 0x67, 0x8F, 0x8A, 0xBF,
++	0x07, 0x38, 0x25, 0x77, 0x14,
++	0x02, 0x57, 0x93, 0x56, 0xBB,
++	0x0A, 0xB8, 0xAA, 0x28, 0xB3,
++	0x0F, 0xE8, 0x84, 0x1D, 0xF1,
++	0x0F, 0x07, 0xB2, 0x2E, 0x64,
++	0x02, 0x9D, 0xA7, 0xCF, 0x9B,
++	0x07, 0x23, 0x8D, 0x8D, 0xC9,
++	0x08, 0x80, 0x4E, 0x30, 0x2E,
++	0x0A, 0x0F, 0xA9, 0xB9, 0x14,
++	0x0B, 0x4F, 0xD9, 0x25, 0xBF,
++	0x06, 0xA6, 0x60, 0x31, 0x94,
++	0x09, 0x7F, 0x45, 0x88, 0x30,
++	0x01, 0x9F, 0xB9, 0x1A, 0xDB,
++	0x00, 0x5A, 0xFA, 0xA5, 0x50,
++	0x0F, 0x2E, 0xE0, 0x7E, 0x21,
++	0x0F, 0x34, 0x55, 0xED, 0x4C,
++	0x0B, 0x34, 0x3B, 0xED, 0xE3,
++	0x06, 0x7C, 0x9C, 0xE8, 0x25,
++	0x0B, 0x47, 0x9B, 0x16, 0x2A,
++	0x07, 0x1B, 0x53, 0x33, 0x11,
++	0x00, 0x84, 0x65, 0x09, 0xE4,
++	0x0B, 0xD3, 0x76, 0x18, 0xE0,
++	0x05, 0x52, 0x43, 0x74, 0x1A,
++	0x0C, 0xC0, 0x63, 0x2E, 0x50,
++	0x06, 0x0B, 0xB9, 0x79, 0x1E,
++	0x07, 0xEA, 0x15, 0x9A, 0xE0,
++	0x0F, 0xF0, 0x79, 0xA9, 0x4E,
++	0x0D, 0xC0, 0xEB, 0x49, 0xEB,
++	0x08, 0x90, 0xCA, 0x17, 0xB6,
++	0x0A, 0x77, 0x87, 0xDA, 0x9E,
++	0x08, 0xB9, 0x9C, 0x7A, 0xC0,
++	0x0E, 0x3C, 0x4C, 0x54, 0x8E,
++	0x06, 0xAE, 0x26, 0x22, 0xB3,
++	0x08, 0xC2, 0x72, 0xAC, 0x37,
++	0x0D, 0xE4, 0x50, 0xAB, 0xBD,
++	0x0C, 0x96, 0x7C, 0x94, 0x84,
++	0x08, 0x9F, 0xD5, 0xA9, 0xFD,
++	0x06, 0x3A, 0xCF, 0x30, 0xB9,
++	0x00, 0x6B, 0x6A, 0xCC, 0x6E,
++	0x0A, 0xA0, 0x52, 0xB1, 0x48,
++	0x09, 0x4E, 0x37, 0xD9, 0x11,
++	0x09, 0x1E, 0x0B, 0x6C, 0x10,
++	0x03, 0x0F, 0xF9, 0xBD, 0xC8,
++	0x09, 0x25, 0xA5, 0x6D, 0x1A,
++	0x00, 0xD8, 0xA8, 0xDC, 0x54,
++	0x04, 0xCC, 0xE4, 0x02, 0xD1,
++	0x04, 0xE5, 0x58, 0x6B, 0x50,
++	0x08, 0xA1, 0x5A, 0x70, 0x87,
++	0x05, 0xA0, 0xA1, 0x3F, 0x01,
++	0x05, 0x23, 0xAB, 0xFA, 0xEC,
++	0x07, 0x96, 0x78, 0xF7, 0xE0,
++	0x06, 0xDD, 0x82, 0xD3, 0xD6,
++	0x01, 0xC5, 0xB9, 0x77, 0x03,
++	0x0D, 0x27, 0xAE, 0xA2, 0x43,
++	0x08, 0x5E, 0xD9, 0xA5, 0x6A,
++	0x01, 0x70, 0xB6, 0xE2, 0xE6,
++	0x01, 0x29, 0xD8, 0x12, 0xE4,
++	0x01, 0x52, 0x38, 0xF9, 0xBB,
++	0x08, 0x88, 0x04, 0x00, 0x4A,
++	0x0A, 0xB0, 0xDE, 0xB6, 0xD5,
++	0x0A, 0xB4, 0x7D, 0x82, 0xDB,
++	0x0A, 0x68, 0x66, 0x03, 0x99,
++	0x0F, 0xAD, 0xF4, 0x58, 0x2B,
++	0x06, 0xF4, 0xCC, 0xC1, 0xA5,
++	0x03, 0x3D, 0x2F, 0xAA, 0x41,
++	0x03, 0xF2, 0x2E, 0x07, 0xBA,
++	0x0F, 0x5D, 0x44, 0x85, 0x45,
++	0x0D, 0xB3, 0x43, 0xBA, 0x24,
++	0x00, 0xF7, 0xC5, 0xCB, 0x18,
++	0x03, 0xB4, 0x79, 0xFE, 0xE6,
++	0x04, 0x71, 0xB5, 0x5D, 0xF4,
++	0x08, 0x08, 0xC6, 0x1F, 0x1C,
++	0x09, 0xBC, 0xB7, 0xAE, 0x85,
++	0x03, 0x3B, 0x23, 0x3D, 0x64,
++	0x04, 0xCC, 0x06, 0x36, 0xBF,
++	0x07, 0xE8, 0x31, 0xF7, 0xD9,
++	0x08, 0x6C, 0x29, 0x5F, 0x35,
++	0x03, 0x5E, 0xD5, 0x2F, 0x95,
++	0x0C, 0xDE, 0x0E, 0x56, 0x1E,
++	0x00, 0x8C, 0x4F, 0x61, 0x7F,
++	0x06, 0x87, 0x78, 0x79, 0xCB,
++	0x0B, 0x8B, 0x99, 0x0A, 0x27,
++	0x00, 0x73, 0x46, 0xC5, 0x08,
++	0x03, 0x6A, 0x62, 0x62, 0x20,
++	0x00, 0x8C, 0x27, 0x2A, 0xC3,
++	0x0A, 0x6E, 0x45, 0x1A, 0xD3,
++	0x06, 0x49, 0x6F, 0xFF, 0xA3,
++	0x0C, 0x0C, 0x65, 0x1A, 0xDF,
++	0x05, 0x63, 0xAC, 0xB3, 0x47,
++	0x0D, 0x06, 0x36, 0xEF, 0x20,
++	0x0F, 0xAA, 0xC5, 0x38, 0xB8,
++	0x01, 0x9E, 0x89, 0x11, 0x75,
++	0x02, 0x19, 0xC2, 0xE0, 0xCF,
++	0x0E, 0xF0, 0xFD, 0xA5, 0x5D,
++	0x07, 0x32, 0x09, 0x4E, 0x94,
++	0x07, 0xCD, 0x8A, 0x91, 0x82,
++	0x0F, 0xC1, 0xF2, 0xC0, 0x31,
++	0x00, 0x4E, 0xD5, 0x86, 0xA9,
++	0x04, 0x08, 0x35, 0xAB, 0xEC,
++	0x08, 0xDA, 0xA1, 0xD3, 0x20,
++	0x08, 0xCA, 0x34, 0xB2, 0x66,
++	0x0D, 0xB9, 0x7A, 0x05, 0x27,
++	0x0D, 0x6D, 0xD8, 0x3D, 0x7F,
++	0x04, 0x0A, 0x57, 0x87, 0x72,
++	0x02, 0xD2, 0x7A, 0xEA, 0x24,
++	0x03, 0x85, 0xEF, 0x9A, 0x1D,
++	0x08, 0xDF, 0xC3, 0x38, 0x2E,
++	0x04, 0x12, 0x99, 0x23, 0xCF,
++	0x0B, 0x15, 0x27, 0x0F, 0x28,
++	0x09, 0xC0, 0x04, 0x42, 0x30,
++	0x0C, 0xE2, 0x89, 0xEB, 0x3A,
++	0x06, 0x62, 0xCC, 0x5F, 0xA5,
++	0x0F, 0x6F, 0x25, 0xE0, 0x7B,
++	0x04, 0x20, 0xFC, 0xC3, 0x04,
++	0x02, 0xCF, 0x1E, 0xF4, 0x50,
++	0x0B, 0xB0, 0x5A, 0xFA, 0xA8,
++	0x0C, 0xCF, 0xAC, 0xE6, 0x79,
++	0x0F, 0xF5, 0xD4, 0x48, 0x67,
++	0x07, 0xDA, 0xCB, 0xFB, 0xF2,
++	0x02, 0x03, 0x7C, 0x5C, 0xFA,
++	0x09, 0x13, 0x47, 0x9F, 0x2A,
++	0x06, 0x51, 0x1B, 0x57, 0x04,
++	0x01, 0x00, 0x80, 0x61, 0x39,
++	0x0E, 0xB3, 0x77, 0x72, 0xE8,
++	0x0E, 0x9F, 0x32, 0x4B, 0xBE,
++	0x06, 0xC9, 0x9D, 0x67, 0x7F,
++	0x0E, 0xE8, 0x8B, 0x1D, 0x72,
++	0x0E, 0x3E, 0xEC, 0x31, 0x97,
++	0x08, 0x1D, 0x51, 0x50, 0xE9,
++	0x06, 0x5D, 0x40, 0xE7, 0x89,
++	0x00, 0x2D, 0xCD, 0xCA, 0x40,
++	0x0D, 0x68, 0x77, 0x83, 0xDD,
++	0x07, 0xFE, 0x39, 0x9C, 0xCA,
++	0x0E, 0x09, 0xBE, 0x60, 0x14,
++	0x07, 0x76, 0x6E, 0x22, 0xA2,
++	0x0B, 0x0D, 0xA3, 0xF2, 0xEC,
++	0x0D, 0xA3, 0x87, 0xD0, 0xED,
++	0x0F, 0x64, 0x9E, 0xF8, 0xC4,
++	0x09, 0x80, 0xCE, 0x51, 0xA5,
++	0x05, 0x16, 0xB6, 0xCB, 0xFC,
++	0x07, 0xD5, 0x0E, 0xEE, 0xC0,
++	0x02, 0xE8, 0xE0, 0x5E, 0xBC,
++	0x01, 0x84, 0xAD, 0x13, 0xC7,
++	0x01, 0x21, 0x9C, 0x2B, 0x24,
++	0x0A, 0xEA, 0x6B, 0x78, 0x3C,
++	0x01, 0x73, 0x22, 0x90, 0xA4,
++	0x0E, 0x7C, 0xDA, 0xA9, 0x1C,
++	0x05, 0x5C, 0xCC, 0x46, 0x82,
++	0x01, 0x84, 0xE5, 0x58, 0x6F,
++	0x05, 0xE0, 0x21, 0x5E, 0x7E,
++	0x02, 0x2D, 0xF9, 0x35, 0x33,
++	0x08, 0x8C, 0x63, 0x4B, 0xF0,
++	0x04, 0xF5, 0x36, 0x74, 0x7B,
++	0x08, 0x5F, 0x7D, 0x82, 0x17,
++	0x0F, 0xA0, 0xA4, 0xF3, 0xA6,
++	0x02, 0x9C, 0xE3, 0x2E, 0xA2,
++	0x02, 0x39, 0x9A, 0x5F, 0xAB,
++	0x0F, 0x1E, 0x30, 0x7F, 0xAA,
++	0x07, 0x40, 0xE9, 0x5A, 0x3C,
++	0x08, 0xB0, 0x92, 0x38, 0xDA,
++	0x00, 0x18, 0x28, 0x06, 0xA3,
++	0x02, 0xCA, 0xB0, 0xDE, 0x9B,
++	0x01, 0x42, 0xB6, 0xFD, 0x92,
++	0x03, 0x52, 0xCE, 0xEA, 0x83,
++	0x09, 0x46, 0x93, 0x74, 0x58,
++	0x0B, 0x2C, 0xF5, 0x75, 0xC2,
++	0x0D, 0xF3, 0x81, 0xAF, 0xAA,
++	0x01, 0x03, 0x76, 0xEC, 0x84,
++	0x08, 0x06, 0xDE, 0xC2, 0xC6,
++	0x00, 0xF4, 0x30, 0xC3, 0xF6,
++	0x0F, 0xA9, 0x74, 0x43, 0x86,
++	0x02, 0x53, 0xB5, 0xF9, 0xB9,
++	0x02, 0xA4, 0x71, 0xB5, 0x71,
++	0x09, 0x70, 0x8A, 0x40, 0x19,
++	0x0E, 0x61, 0xBD, 0x37, 0x22,
++	0x0D, 0x69, 0x7B, 0x24, 0xB7,
++	0x0E, 0x14, 0xC8, 0x0C, 0xD5,
++	0x0F, 0x2E, 0x6C, 0x91, 0x56,
++	0x0B, 0xE2, 0x6E, 0xBF, 0xDB,
++	0x06, 0x0A, 0xDF, 0x59, 0x80,
++	0x05, 0xE4, 0x5C, 0x0E, 0x74,
++	0x05, 0xBA, 0x89, 0x0C, 0xE1,
++	0x02, 0x66, 0x47, 0x78, 0x7F,
++	0x09, 0x6F, 0x2B, 0x99, 0x04,
++	0x0D, 0xA8, 0xE3, 0x6C, 0x35,
++	0x09, 0xAA, 0xAE, 0x62, 0x62,
++	0x00, 0xD9, 0x28, 0x27, 0x2A,
++	0x00, 0x33, 0xAE, 0xC3, 0x00,
++	0x03, 0x3F, 0xE9, 0x6F, 0xC9,
++	0x08, 0xD1, 0xCC, 0x65, 0x1A,
++	0x04, 0xD1, 0x63, 0xAC, 0xB3,
++	0x0F, 0xDD, 0x86, 0xB6, 0xEC,
++	0x0C, 0x7E, 0x8A, 0x8F, 0xDC,
++	0x09, 0xB9, 0x98, 0xC9, 0xBD,
++	0x07, 0x13, 0x9D, 0xF4, 0xB6,
++	0x0F, 0x0F, 0x70, 0xF9, 0x03,
++	0x0F, 0x16, 0xB2, 0x2F, 0x0C,
++	0x01, 0xE6, 0x4D, 0xBA, 0x91,
++	0x0D, 0xD5, 0xC4, 0xC2, 0xC2,
++	0x08, 0x98, 0xAE, 0x59, 0xC6,
++	0x0E, 0xD9, 0x1F, 0x95, 0x87,
++	0x04, 0x11, 0x79, 0x95, 0x53,
++	0x00, 0x18, 0xCE, 0x34, 0xBF,
++	0x02, 0xC7, 0x5D, 0xE7, 0x8F,
++	0x08, 0x0D, 0x69, 0xDE, 0x6D,
++	0x0C, 0x54, 0xCD, 0xD7, 0x97,
++	0x03, 0x38, 0x12, 0x7C, 0xAA,
++	0x05, 0xB3, 0x65, 0xED, 0x9A,
++	0x0C, 0x60, 0x1F, 0x07, 0xBE,
++	0x07, 0x66, 0x72, 0x1B, 0x29,
++	0x0E, 0x98, 0xD5, 0x23, 0x8D,
++	0x02, 0x88, 0x48, 0x06, 0x88,
++	0x00, 0x9C, 0xAE, 0x0D, 0xE9,
++	0x09, 0x14, 0x2F, 0x43, 0xC8,
++	0x07, 0xBF, 0x22, 0xA0, 0xE0,
++	0x00, 0x94, 0xAD, 0x7F, 0xB6,
++	0x0F, 0xB3, 0x0F, 0x1F, 0x80,
++	0x03, 0x59, 0xF0, 0x5C, 0x0F,
++	0x00, 0x94, 0x0C, 0x2C, 0x60,
++	0x03, 0xA4, 0xF5, 0x52, 0xC2,
++	0x0E, 0x09, 0xFB, 0x39, 0x7B,
++	0x01, 0xFE, 0x0B, 0x7A, 0x9C,
++	0x01, 0xA6, 0x5B, 0xC5, 0x1F,
++	0x07, 0x28, 0x07, 0x1B, 0x65,
++	0x09, 0x14, 0x90, 0x84, 0x63,
++	0x00, 0xD6, 0xFC, 0xD3, 0x72,
++	0x08, 0x56, 0x9A, 0xB2, 0x4B,
++	0x0E, 0x4D, 0x4C, 0xC0, 0x63,
++	0x08, 0x52, 0x5E, 0x8B, 0x1D,
++	0x05, 0x1F, 0x9E, 0xE8, 0x35,
++	0x0E, 0x62, 0x95, 0xF5, 0x90,
++	0x03, 0x5B, 0xD2, 0x40, 0xEF,
++	0x01, 0x6B, 0x08, 0x90, 0x0E,
++	0x0D, 0xB3, 0xFA, 0xF7, 0x86,
++	0x05, 0x1C, 0x98, 0xB5, 0x50,
++	0x00, 0x73, 0x1D, 0xBE, 0x68,
++	0x00, 0x8E, 0x36, 0xA3, 0x26,
++	0x02, 0x01, 0x08, 0xC2, 0x72,
++	0x0C, 0xFF, 0x06, 0xE4, 0x50,
++	0x04, 0x3D, 0x47, 0x1B, 0xBC,
++	0x0A, 0x99, 0x80, 0x42, 0x9B,
++	0x0F, 0xF8, 0x82, 0xBA, 0xC3,
++	0x0C, 0x7D, 0xD0, 0x67, 0x5C,
++	0x01, 0x6B, 0xE8, 0xA6, 0x18,
++	0x07, 0xBB, 0x81, 0xCE, 0x93,
++	0x0F, 0xD1, 0x83, 0x9C, 0x1D,
++	0x0C, 0xD0, 0xEF, 0x8F, 0xF2,
++	0x0D, 0xF1, 0x73, 0xA0, 0x9E,
++	0x0D, 0x1E, 0x7C, 0x58, 0xA3,
++	0x0C, 0x6D, 0x5C, 0xCC, 0x4E,
++	0x02, 0x11, 0x86, 0xE5, 0x92,
++	0x04, 0x4D, 0xC8, 0xA1, 0x5A,
++	0x07, 0x49, 0xCD, 0xF5, 0x75,
++	0x09, 0x04, 0x36, 0x23, 0x6B,
++	0x02, 0x2F, 0xF7, 0xB2, 0x7A,
++	0x0B, 0xA0, 0xD6, 0x5D, 0x82,
++	0x0D, 0x15, 0x41, 0x2E, 0x42,
++	0x07, 0x03, 0x99, 0x27, 0xAE,
++	0x02, 0x43, 0x37, 0xDE, 0xD9,
++	0x03, 0xDE, 0x1E, 0xF6, 0x71,
++	0x02, 0xE6, 0xC1, 0x29, 0xDA,
++	0x0C, 0xF8, 0x31, 0x52, 0x38,
++	0x06, 0xB8, 0x18, 0x88, 0x07,
++	0x0A, 0x89, 0x2D, 0x32, 0x5E,
++	0x02, 0x93, 0x26, 0xB4, 0xBD,
++	0x0E, 0x5B, 0xF2, 0xAA, 0x69,
++	0x03, 0x19, 0x42, 0x97, 0x06,
++	0x02, 0xEE, 0x8D, 0x71, 0xE7,
++	0x01, 0xAD, 0xBB, 0x05, 0x5D,
++	0x0A, 0x81, 0x4E, 0xF2, 0xEE,
++	0x07, 0x3A, 0x4B, 0x5D, 0x44,
++	0x04, 0x70, 0xBD, 0xB5, 0x03,
++	0x00, 0x33, 0xE0, 0xF7, 0xDC,
++	0x0D, 0xA8, 0x53, 0xB2, 0x73,
++	0x09, 0x67, 0x0C, 0xF1, 0xB1,
++	0x08, 0x33, 0x10, 0x08, 0x86,
++	0x09, 0x90, 0xC9, 0x3D, 0x33,
++	0x02, 0x85, 0x6D, 0xFB, 0x2B,
++	0x03, 0xE4, 0xD0, 0xC8, 0xC6,
++	0x0B, 0x8D, 0xEB, 0xE8, 0x71,
++	0x07, 0x73, 0xA3, 0xEE, 0x71,
++	0x01, 0x73, 0xA3, 0xDF, 0x51,
++	0x02, 0x95, 0xE5, 0xDC, 0xFC,
++	0x04, 0x9E, 0xA2, 0x09, 0x0C,
++	0x01, 0x7B, 0x62, 0x87, 0x78,
++	0x0B, 0xC1, 0xEF, 0x87, 0x19,
++	0x04, 0xA7, 0x68, 0xF3, 0xE6,
++	0x04, 0x80, 0x03, 0x6A, 0xE2,
++	0x0B, 0x22, 0x74, 0x8C, 0xD5,
++	0x00, 0xC6, 0xD6, 0xEE, 0x4D,
++	0x03, 0x53, 0x16, 0x45, 0xEF,
++	0x00, 0xAB, 0xFC, 0x0C, 0x97,
++	0x00, 0x5A, 0x7F, 0x63, 0xAE,
++	0x0A, 0x47, 0x3D, 0x0A, 0x36,
++	0x0C, 0x16, 0xBA, 0xAA, 0x05,
++	0x0B, 0xCB, 0xBC, 0x1C, 0x1B,
++	0x0D, 0x75, 0x12, 0x19, 0x31,
++	0x06, 0xCD, 0x0E, 0xF6, 0x35,
++	0x07, 0xDF, 0x17, 0x92, 0x89,
++	0x0C, 0xD1, 0xE3, 0xCB, 0xCA,
++	0x01, 0x6E, 0x75, 0xC4, 0xC4,
++	0x01, 0x0B, 0x18, 0x4E, 0x55,
++	0x0C, 0xF1, 0x68, 0x8A, 0x11,
++	0x0E, 0xEE, 0x92, 0xDF, 0x53,
++	0x09, 0x35, 0xAC, 0xCA, 0x30,
++	0x0F, 0xA2, 0xC7, 0x55, 0x95,
++	0x0B, 0xBA, 0x09, 0x61, 0x58,
++	0x0D, 0x7D, 0x54, 0x0A, 0x57,
++	0x06, 0xB8, 0xD9, 0xD2, 0x7A,
++	0x03, 0x26, 0x53, 0x85, 0x2D,
++	0x00, 0x18, 0x59, 0xFF, 0x0F,
++	0x07, 0xAE, 0x84, 0x12, 0x5D,
++	0x03, 0xCF, 0x9B, 0x15, 0x23,
++	0x0D, 0xAB, 0x89, 0x88, 0x80,
++	0x02, 0x30, 0x9C, 0xAD, 0xC7,
++	0x0D, 0xB9, 0x14, 0x2F, 0x0F,
++	0x09, 0x25, 0xBF, 0x26, 0xA6,
++	0x00, 0x31, 0x16, 0x69, 0x7F,
++	0x0E, 0x8E, 0xB2, 0xCF, 0x1F,
++	0x08, 0x05, 0x24, 0x4C, 0x59,
++	0x06, 0xA8, 0x94, 0xAF, 0x2D,
++	0x00, 0x73, 0xA6, 0xF5, 0xD4,
++	0x08, 0x67, 0x0B, 0x5B, 0x3E,
++	0x0B, 0xC3, 0xFE, 0x8F, 0x76,
++	0x0C, 0xC8, 0x25, 0xBB, 0x4D,
++	0x0F, 0x36, 0x2A, 0xC7, 0x11,
++	0x07, 0x13, 0x11, 0x80, 0xCE,
++	0x01, 0x39, 0x54, 0x1B, 0x99,
++	0x09, 0x28, 0x56, 0x9F, 0xB2,
++	0x0B, 0x7E, 0x4B, 0x4C, 0x33,
++	0x0A, 0xA8, 0x32, 0xFE, 0x8B,
++	0x05, 0xE5, 0x3E, 0x32, 0xF9,
++	0x0D, 0x31, 0xC0, 0xB9, 0xB5,
++	0x0A, 0x2C, 0x96, 0x5D, 0xE0,
++	0x0F, 0x99, 0x4B, 0xA4, 0x90,
++	0x06, 0x91, 0x16, 0x64, 0x37,
++	0x0D, 0xF9, 0xD6, 0xF8, 0xF9,
++	0x08, 0xCA, 0xD6, 0x82, 0x3E,
++	0x06, 0x51, 0x4B, 0xB6, 0xEE,
++	0x0E, 0xA2, 0xA1, 0x04, 0x42,
++	0x08, 0xA9, 0xFF, 0xA6, 0xA4,
++	0x00, 0xAD, 0x3B, 0x64, 0x65,
++	0x05, 0x19, 0xF5, 0x82, 0x46,
++	0x08, 0xA7, 0x9D, 0x16, 0xFA,
++	0x01, 0x39, 0xB5, 0xD0, 0x7B,
++	0x02, 0xD1, 0x6B, 0xEA, 0x93,
++	0x02, 0xBC, 0xBB, 0x05, 0x04,
++	0x03, 0xD7, 0x51, 0x21, 0x9C,
++	0x0B, 0x6C, 0xD4, 0xE3, 0xCF,
++	0x08, 0x3D, 0xF5, 0x73, 0x20,
++	0x04, 0x25, 0xBE, 0x7C, 0xD8,
++	0x00, 0x1E, 0x4D, 0x5C, 0xBF,
++	0x0E, 0x07, 0xDD, 0x84, 0xED,
++	0x00, 0xEF, 0xED, 0xC4, 0x61,
++	0x0A, 0x7E, 0xC9, 0x2B, 0xF3,
++	0x01, 0x33, 0x01, 0x88, 0xE9,
++	0x0B, 0xFA, 0x2C, 0x75, 0x96,
++	0x08, 0xFB, 0x22, 0xD6, 0xDD,
++	0x09, 0xD7, 0xD5, 0x44, 0xD6,
++	0x05, 0x77, 0x03, 0x5D, 0x28,
++	0x0E, 0xA2, 0x59, 0x38, 0x5E,
++	0x09, 0xA1, 0xDE, 0x9F, 0xFA,
++	0x0B, 0xE2, 0xE4, 0x41, 0xE3,
++	0x01, 0x3C, 0xF9, 0xB1, 0xA1,
++	0x00, 0xDA, 0x38, 0x94, 0x88,
++	0x0C, 0x25, 0x89, 0xC6, 0xF0,
++	0x04, 0x9E, 0x4B, 0xC2, 0x94,
++	0x0D, 0x92, 0x5F, 0xF2, 0xA2,
++	0x06, 0x03, 0x19, 0x48, 0x39,
++	0x0C, 0x58, 0x6B, 0x22, 0x1F,
++	0x07, 0x41, 0xA9, 0xBB, 0xEB,
++	0x05, 0x2F, 0x6F, 0x41, 0x11,
++	0x04, 0x02, 0xE2, 0xCF, 0x1D,
++	0x04, 0x86, 0x70, 0xB7, 0x0A,
++	0x03, 0xBC, 0x3F, 0xEA, 0x4F,
++	0x0F, 0x49, 0x70, 0x58, 0x5F,
++	0x03, 0xF6, 0xBA, 0x24, 0x31,
++	0x0D, 0x71, 0xB1, 0x1C, 0x88,
++	0x0C, 0x16, 0x4C, 0xE1, 0xFD,
++	0x0E, 0xA2, 0x65, 0x69, 0xFB,
++	0x04, 0xB7, 0xE4, 0xD9, 0xC6,
++	0x06, 0x32, 0x8D, 0x2B, 0x06,
++	0x0A, 0xD6, 0x59, 0xE3, 0xC0,
++	0x03, 0x5B, 0x72, 0x0B, 0x97,
++	0x05, 0x02, 0x95, 0xE5, 0xF2,
++	0x0E, 0x74, 0x9E, 0xBA, 0xA7,
++	0x0C, 0xE1, 0x7B, 0x66, 0x69,
++	0x00, 0x07, 0x41, 0xE3, 0xA5,
++	0x03, 0xC4, 0xA5, 0xE3, 0x48,
++	0x06, 0xC5, 0x48, 0x63, 0x60,
++	0x02, 0x62, 0x20, 0x15, 0xA2,
++	0x07, 0x2A, 0xC3, 0x74, 0x97,
++	0x0E, 0x0A, 0xD3, 0xF6, 0x71,
++	0x07, 0xC9, 0x29, 0x94, 0x0C,
++	0x0D, 0x1C, 0xDF, 0xDD, 0x23,
++	0x06, 0xB6, 0x2E, 0xDD, 0x26,
++	0x06, 0xEC, 0x12, 0xBE, 0x62,
++	0x05, 0x2B, 0xCB, 0xB6, 0xB3,
++	0x01, 0x3D, 0xF5, 0x1C, 0xF6,
++	0x02, 0xF6, 0xC9, 0x0E, 0x1F,
++	0x05, 0x06, 0x31, 0x1C, 0xD1,
++	0x03, 0x4B, 0x36, 0xE7, 0x8D,
++	0x0A, 0x91, 0xC6, 0xDF, 0x3D,
++	0x04, 0x40, 0x21, 0x12, 0xB6,
++	0x0F, 0x03, 0x06, 0xD7, 0x61,
++	0x0F, 0xA2, 0x0B, 0x92, 0x9F,
++	0x0B, 0x53, 0xB0, 0x14, 0x4A,
++	0x0E, 0xBA, 0x4A, 0xC7, 0x19,
++	0x0E, 0x0F, 0x5A, 0x0D, 0x6D,
++	0x08, 0x2D, 0x7D, 0x59, 0x00,
++	0x07, 0x97, 0x70, 0x3D, 0x3D,
++	0x01, 0xEA, 0x24, 0x33, 0xAA,
++	0x0D, 0x9A, 0x19, 0xE1, 0x37,
++	0x07, 0xBE, 0x2E, 0x64, 0x3D,
++	0x0D, 0xA3, 0xCF, 0x9B, 0x3A,
++	0x03, 0x8D, 0xAB, 0x89, 0x67,
++	0x08, 0x3A, 0xB0, 0x90, 0x84,
++	0x07, 0x29, 0xBB, 0x9F, 0xF3,
++	0x0F, 0xD9, 0x25, 0x3F, 0x2C,
++	0x06, 0x60, 0x31, 0x91, 0x46,
++	0x0F, 0x45, 0x8E, 0xBC, 0x36,
++	0x04, 0x74, 0x1A, 0xDB, 0x88,
++	0x0A, 0xFA, 0xA9, 0x16, 0x16,
++	0x0E, 0xE0, 0x77, 0x20, 0xFF,
++	0x0D, 0xC8, 0x87, 0x0B, 0x1B,
++	0x0C, 0xB8, 0xE3, 0x7C, 0xBB,
++	0x0C, 0x5C, 0xC8, 0x25, 0x03,
++	0x07, 0x9F, 0x36, 0x2E, 0x0D,
++	0x03, 0x07, 0x93, 0x1D, 0x00,
++	0x0C, 0x67, 0xB9, 0x5A, 0x5B,
++	0x03, 0x72, 0x2C, 0x56, 0x48,
++	0x0B, 0x4B, 0xBE, 0x41, 0x8C,
++	0x0A, 0x66, 0xDD, 0xD2, 0xBE,
++	0x02, 0x1F, 0x45, 0x9E, 0xFE,
++	0x02, 0x30, 0x42, 0x60, 0xB7,
++	0x0C, 0xF8, 0xC9, 0x5A, 0x9D,
++	0x08, 0xBF, 0xC9, 0xE7, 0xA8,
++	0x08, 0xC8, 0x97, 0xBA, 0x28,
++	0x0F, 0x87, 0x7C, 0x12, 0xF8,
++	0x01, 0x96, 0xCA, 0x7A, 0xCF,
++	0x04, 0x6A, 0x44, 0x8E, 0x16,
++	0x06, 0x25, 0xA2, 0x0F, 0x88,
++	0x0A, 0xF1, 0x0E, 0x39, 0x66,
++	0x0D, 0x53, 0x69, 0x31, 0x24,
++	0x06, 0xFC, 0x96, 0x19, 0xB3,
++	0x04, 0x51, 0xA1, 0xFB, 0x16,
++	0x0A, 0xCB, 0xB0, 0xFD, 0xD0,
++	0x09, 0x6F, 0x45, 0x6D, 0xAA,
++	0x00, 0xD2, 0x1B, 0xBB, 0x81,
++	0x0C, 0x12, 0x7B, 0x57, 0xA1,
++	0x0F, 0x2F, 0xAC, 0xDC, 0x6F,
++	0x0E, 0xF9, 0xFD, 0x77, 0x79,
++	0x01, 0x76, 0xED, 0x98, 0x36,
++	0x02, 0xAC, 0xE3, 0x6D, 0x4C,
++	0x0C, 0x44, 0x00, 0x17, 0x0E,
++	0x0E, 0x58, 0x6F, 0x4D, 0xFA,
++	0x0A, 0xDC, 0xC9, 0xCF, 0xA7,
++	0x01, 0xB5, 0x90, 0x03, 0x0C,
++	0x08, 0xCD, 0x4D, 0x2A, 0x00,
++	0x0F, 0x7A, 0xDB, 0xAD, 0x96,
++	0x04, 0x80, 0x97, 0xD5, 0x80,
++	0x0F, 0x7F, 0x75, 0x83, 0x99,
++	0x07, 0xAE, 0xA2, 0x4F, 0x0B,
++	0x06, 0x59, 0x00, 0x5C, 0x9F,
++	0x0B, 0xFD, 0x55, 0xE0, 0x37,
++	0x01, 0x58, 0x1C, 0xF4, 0x31,
++	0x0A, 0x38, 0x5E, 0x3A, 0x18,
++	0x01, 0x06, 0x23, 0x09, 0x0A,
++	0x09, 0xDC, 0xD8, 0x17, 0x08,
++	0x0E, 0xFB, 0x9A, 0x5B, 0xF6,
++	0x08, 0x66, 0x07, 0x1F, 0xC6,
++	0x07, 0xF4, 0x5C, 0xE7, 0xDE,
++	0x01, 0x75, 0x45, 0xAD, 0xBB,
++	0x0F, 0xA9, 0xA1, 0x81, 0x4B,
++	0x02, 0xEE, 0x03, 0x36, 0x7D,
++	0x0D, 0x44, 0x82, 0xF0, 0xBD,
++	0x03, 0x43, 0xBB, 0xBF, 0xE0,
++	0x07, 0xC5, 0xCC, 0x82, 0x53,
++	0x04, 0xF9, 0x53, 0x62, 0xA4,
++	0x01, 0x34, 0xD1, 0x31, 0x10,
++	0x01, 0xC4, 0x37, 0x95, 0x95,
++	0x07, 0x31, 0x2E, 0x05, 0x6B,
++	0x03, 0xA4, 0x17, 0xE9, 0xD4,
++	0x05, 0x84, 0x16, 0x8D, 0xDB,
++	0x02, 0xB7, 0xD8, 0x59, 0xEB,
++	0x06, 0x03, 0xFB, 0x7B, 0x0B,
++	0x0F, 0x55, 0x03, 0x95, 0xE5,
++	0x0C, 0x0E, 0x77, 0x9A, 0x30,
++	0x09, 0x0C, 0xE3, 0x7D, 0x2C,
++	0x0C, 0x78, 0x7F, 0xC1, 0xEF,
++	0x07, 0x99, 0x06, 0xE7, 0x67,
++	0x03, 0xE6, 0xDF, 0x48, 0xD1,
++	0x0A, 0xE2, 0x62, 0xA0, 0x1A,
++	0x0C, 0x27, 0x2A, 0x43, 0x70,
++	0x0E, 0x45, 0x0A, 0x53, 0xFC,
++	0x09, 0x6F, 0xC9, 0x29, 0x52,
++	0x0C, 0x65, 0x1A, 0xDF, 0xDB,
++	0x03, 0xAC, 0xB1, 0xC7, 0xD7,
++	0x0D, 0xB6, 0xEC, 0x16, 0x8D,
++	0x0A, 0x05, 0x2B, 0xC5, 0xA5,
++	0x0C, 0xE9, 0x39, 0x75, 0x12,
++	0x09, 0xC2, 0xF2, 0xCD, 0xCA,
++	0x00, 0xFF, 0x87, 0xDF, 0xE3,
++	0x02, 0x09, 0x4A, 0xD1, 0x12,
++	0x0D, 0x8A, 0x91, 0xC6, 0x22,
++	0x0F, 0x42, 0xD9, 0xAC, 0x1D,
++	0x0E, 0x55, 0x86, 0xF9, 0xD8,
++	0x06, 0x15, 0xA7, 0xE8, 0x91,
++	0x07, 0x2B, 0xF3, 0x30, 0x58,
++	0x03, 0xB4, 0x5F, 0xA2, 0xC7,
++	0x07, 0xE7, 0x42, 0xBA, 0x0D,
++	0x04, 0x59, 0xCD, 0x71, 0x54,
++	0x03, 0x55, 0xB7, 0x70, 0xB9,
++	0x08, 0x7C, 0xF6, 0xA4, 0x31,
++	0x05, 0xED, 0x9A, 0x1B, 0xA3,
++	0x06, 0x0D, 0xDE, 0x33, 0xA4,
++	0x08, 0x9B, 0xB9, 0xCF, 0x9F,
++	0x09, 0x23, 0x8C, 0xAB, 0x87,
++	0x08, 0x80, 0x42, 0x3E, 0x81,
++	0x0B, 0x0D, 0xFD, 0xB5, 0x05,
++	0x07, 0x4F, 0xD8, 0xA5, 0x8C,
++	0x06, 0xA6, 0x66, 0x31, 0x5D,
++	0x02, 0xF9, 0xE6, 0x83, 0xB6,
++	0x0F, 0x1F, 0x74, 0x17, 0x9F,
++	0x08, 0xD9, 0xDA, 0xAA, 0x87,
++	0x06, 0x2C, 0xCC, 0x33, 0x57,
++	0x0F, 0xD2, 0x6B, 0x67, 0x0F,
++	0x03, 0xB4, 0x9B, 0xC3, 0xFE,
++	0x0F, 0x7C, 0x5C, 0xC5, 0x61,
++	0x0B, 0x47, 0x9F, 0x30, 0x28,
++	0x07, 0x1B, 0x55, 0x16, 0x5B,
++	0x00, 0x84, 0x61, 0x39, 0xA7,
++	0x03, 0x53, 0xD2, 0x38, 0xD6,
++	0x06, 0x32, 0xAB, 0x72, 0x4D,
++	0x02, 0x40, 0xAE, 0x28, 0xD2,
++	0x07, 0x0A, 0xFD, 0x69, 0x9E,
++	0x07, 0xEA, 0x15, 0xA7, 0xD2,
++	0x0F, 0xF3, 0x78, 0xA9, 0x5C,
++	0x05, 0x40, 0x47, 0x45, 0x6B,
++	0x01, 0x92, 0xAE, 0x1B, 0x76,
++	0x02, 0x71, 0xA1, 0xFC, 0x1A,
++	0x04, 0xB9, 0x91, 0xCA, 0x78,
++	0x0F, 0x3E, 0x6C, 0x5A, 0x93,
++	0x0E, 0x46, 0x92, 0x24, 0x42,
++	0x03, 0x44, 0xD5, 0xAF, 0x02,
++	0x06, 0xE4, 0x50, 0xA9, 0x85,
++	0x0D, 0x14, 0xB8, 0x9A, 0x6B,
++	0x0A, 0xC0, 0x7C, 0x25, 0xFF,
++	0x0F, 0x3A, 0x0B, 0x30, 0xFD,
++	0x09, 0xE9, 0x2A, 0xC1, 0x99,
++	0x00, 0xA6, 0x7D, 0xBC, 0xB3,
++	0x08, 0xCE, 0x53, 0xDB, 0xD1,
++	0x08, 0x1E, 0x6F, 0x60, 0x50,
++	0x07, 0x8F, 0x58, 0x3D, 0xB1,
++	0x01, 0x20, 0x90, 0xE9, 0xDE,
++	0x05, 0xD8, 0x69, 0x1F, 0x68,
++	0x0D, 0xCC, 0xA4, 0x0F, 0x15,
++	0x0D, 0xEC, 0x98, 0x62, 0x8D,
++	0x08, 0xA1, 0x5A, 0x7A, 0x30,
++	0x0F, 0xF9, 0x31, 0x35, 0x01,
++	0x05, 0x23, 0xAB, 0xFA, 0x1E,
++	0x05, 0x14, 0x58, 0xFE, 0x16,
++	0x0C, 0xDB, 0xC2, 0xD7, 0xC5,
++	0x0E, 0x25, 0xB4, 0x77, 0x03,
++	0x01, 0x27, 0xAC, 0xE2, 0x4D,
++	0x08, 0x5E, 0xD9, 0xBF, 0xC3,
++	0x06, 0x71, 0x8F, 0xCE, 0xE6,
++	0x09, 0x29, 0x4E, 0x2C, 0x79,
++	0x09, 0xD2, 0x98, 0xDA, 0x38,
++	0x00, 0x8A, 0x04, 0x23, 0x89,
++	0x00, 0xB6, 0xE7, 0x9B, 0x95,
++	0x0A, 0xB4, 0x7D, 0x92, 0x5B,
++	0x0A, 0xE8, 0x46, 0x33, 0x99,
++	0x0C, 0x91, 0xCE, 0xD8, 0xEF,
++	0x04, 0x71, 0x57, 0x41, 0xAD,
++	0x09, 0x05, 0xAF, 0xAC, 0x81,
++	0x02, 0xF2, 0x6E, 0x17, 0xBA,
++	0x0F, 0x5C, 0xC4, 0x86, 0x70,
++	0x0F, 0xB3, 0x43, 0xBA, 0x7F,
++	0x08, 0x77, 0x65, 0xFC, 0x02,
++	0x03, 0x35, 0xD9, 0xF3, 0x62,
++	0x0D, 0x63, 0xD5, 0x7C, 0xF1,
++	0x00, 0x08, 0x46, 0x05, 0x97,
++	0x01, 0xBD, 0x37, 0x04, 0xC7,
++	0x03, 0xFD, 0x10, 0x37, 0xE0,
++	0x0E, 0xCA, 0x4D, 0xB2, 0x8C,
++	0x01, 0x68, 0x7C, 0xD6, 0x59,
++	0x03, 0xEE, 0x81, 0x47, 0x3F,
++	0x02, 0xDE, 0xB4, 0xAE, 0x95,
++	0x0D, 0xDC, 0x8F, 0xF4, 0x1E,
++	0x02, 0x09, 0xAC, 0xE1, 0xFB,
++	0x0E, 0x85, 0x78, 0x7F, 0x41,
++	0x05, 0x8D, 0xDD, 0x84, 0xA3,
++	0x08, 0xF3, 0xE6, 0x45, 0x48,
++	0x03, 0x6A, 0xE1, 0xE2, 0x20,
++	0x04, 0x8C, 0x27, 0x3C, 0xC3,
++	0x02, 0x6E, 0xC5, 0x0A, 0x53,
++	0x06, 0x48, 0xEF, 0xC9, 0xA9,
++	0x00, 0x8E, 0x45, 0x1A, 0xDF,
++	0x0B, 0x65, 0xE4, 0xB3, 0xC3,
++	0x0D, 0x06, 0xB6, 0x6C, 0x16,
++	0x0E, 0xAA, 0x06, 0xAB, 0xCB,
++	0x0C, 0x1C, 0xE9, 0x3B, 0x35,
++	0x0A, 0x99, 0x62, 0xC6, 0x4D,
++	0x0E, 0x71, 0x5F, 0x83, 0xDF,
++	0x0E, 0x20, 0x69, 0x43, 0x11,
++	0x07, 0xCD, 0x8A, 0x87, 0xC4,
++	0x05, 0xC4, 0xC6, 0x66, 0x63,
++	0x02, 0x48, 0x15, 0x86, 0xF0,
++	0x04, 0x8A, 0x95, 0xAB, 0xEC,
++	0x0A, 0xD9, 0x13, 0x5D, 0xF0,
++	0x02, 0xCC, 0xB6, 0xBF, 0x82,
++	0x07, 0x59, 0x67, 0x81, 0xA7,
++	0x05, 0x6D, 0x58, 0x2D, 0x4E,
++	0x04, 0x0A, 0x57, 0x97, 0xB5,
++	0x09, 0xD2, 0x7A, 0xE4, 0x39,
++	0x0F, 0x85, 0xEC, 0x1A, 0x13,
++	0x09, 0x7E, 0x81, 0xB3, 0x2E,
++	0x0D, 0x13, 0x19, 0xAE, 0x8F,
++	0x02, 0x94, 0xA7, 0x80, 0x2B,
++	0x09, 0x88, 0x84, 0x47, 0x74,
++	0x0C, 0xAB, 0x19, 0xEC, 0x3D,
++	0x04, 0x2B, 0x4F, 0xD9, 0xEC,
++	0x0F, 0x26, 0xA6, 0xE5, 0xF5,
++	0x0D, 0x69, 0xBF, 0xC5, 0x04,
++	0x00, 0xCF, 0x1F, 0x74, 0x9A,
++	0x09, 0xB0, 0x5E, 0xFA, 0x28,
++	0x05, 0x4F, 0xCE, 0xEC, 0x62,
++	0x05, 0x97, 0x94, 0x48, 0x67,
++	0x01, 0xDD, 0x62, 0xBB, 0xCB,
++	0x07, 0x0F, 0xBC, 0x5C, 0xC8,
++	0x05, 0x3B, 0x47, 0x19, 0xFC,
++	0x06, 0x67, 0x1B, 0x57, 0x22,
++	0x08, 0x80, 0x64, 0x63, 0xB9,
++	0x0F, 0x9A, 0x33, 0xFE, 0x68,
++	0x07, 0x1A, 0x51, 0xCD, 0xF4,
++	0x05, 0xCC, 0x60, 0xEF, 0xE8,
++	0x06, 0xFE, 0x88, 0x1D, 0xE5,
++	0x0A, 0x3E, 0xE8, 0x33, 0x77,
++	0x01, 0xB5, 0x31, 0x50, 0xFE,
++	0x0F, 0x5C, 0x03, 0x67, 0x49,
++	0x02, 0x29, 0x50, 0xCC, 0x97,
++	0x06, 0x68, 0x77, 0x87, 0xFC,
++	0x0E, 0xF8, 0xB9, 0x90, 0x4A,
++	0x06, 0x8F, 0x3E, 0x6A, 0x8F,
++	0x0E, 0x36, 0xAE, 0x21, 0xB8,
++	0x0B, 0xC8, 0xCB, 0xFE, 0x11,
++	0x07, 0xA6, 0xE4, 0x50, 0xAD,
++	0x07, 0xCD, 0x36, 0x7D, 0x19,
++	0x0D, 0x80, 0xC2, 0x50, 0x25,
++	0x0D, 0x16, 0x3E, 0xCB, 0x3C,
++	0x0C, 0xD0, 0xAB, 0x68, 0xB2,
++	0x0A, 0x68, 0xE0, 0x52, 0xBC,
++	0x01, 0x87, 0xAA, 0x13, 0xD3,
++	0x09, 0xA1, 0x3B, 0xAE, 0xEC,
++	0x00, 0xEF, 0x0E, 0x78, 0x3D,
++	0x08, 0xF3, 0xC0, 0x96, 0x6D,
++	0x0F, 0x7C, 0x18, 0xA9, 0x1C,
++	0x07, 0x5A, 0x23, 0x44, 0x03,
++	0x08, 0x04, 0x0A, 0xDA, 0xEF,
++	0x01, 0xC8, 0xAE, 0x9A, 0x4F,
++	0x05, 0x2C, 0x17, 0xF5, 0x30,
++	0x01, 0x8C, 0xA3, 0x4D, 0x21,
++	0x0C, 0x75, 0x96, 0x7F, 0x61,
++	0x0A, 0x16, 0xD4, 0x0E, 0x18,
++	0x05, 0x40, 0xA5, 0x79, 0x77,
++	0x01, 0x9D, 0x23, 0xAF, 0x22,
++	0x0A, 0xB8, 0xBE, 0x5B, 0x21,
++	0x0F, 0x1F, 0x30, 0x7B, 0xE2,
++	0x0E, 0xC3, 0x69, 0xD6, 0x7C,
++	0x03, 0xB7, 0x39, 0x38, 0xD8,
++	0x01, 0x98, 0x48, 0x08, 0x63,
++	0x00, 0xCB, 0x78, 0xDE, 0xDB,
++	0x01, 0x42, 0xB4, 0xFD, 0x92,
++	0x0B, 0xF2, 0x6A, 0x63, 0x9D,
++	0x09, 0x46, 0x97, 0xF4, 0x58,
++	0x0B, 0x2C, 0xF8, 0xF7, 0x41,
++	0x0D, 0xBB, 0x05, 0xAF, 0xAA,
++	0x00, 0x4A, 0x32, 0xEE, 0x07,
++	0x02, 0xCF, 0xFD, 0x44, 0x86,
++	0x00, 0xBD, 0xB3, 0x45, 0x67,
++	0x0F, 0xE0, 0xF7, 0xC2, 0x56,
++	0x08, 0x93, 0xBD, 0xF5, 0x12,
++	0x02, 0xA4, 0x71, 0xB5, 0x71,
++	0x08, 0x11, 0xA8, 0x47, 0x93,
++	0x0C, 0xE3, 0xFD, 0xB7, 0x62,
++	0x09, 0x69, 0xFA, 0xA4, 0xB9,
++	0x0D, 0x54, 0x28, 0x06, 0xF2,
++	0x09, 0x2F, 0xEC, 0xB7, 0x16,
++	0x01, 0x60, 0xD9, 0x0F, 0xD4,
++	0x07, 0x09, 0x07, 0x5B, 0x48,
++	0x05, 0xE5, 0xDC, 0x0E, 0x74,
++	0x07, 0x38, 0xE9, 0x0C, 0x21,
++	0x01, 0x60, 0xF1, 0xF8, 0x77,
++	0x08, 0x6F, 0x6B, 0x99, 0x04,
++	0x0B, 0x64, 0xF3, 0xE6, 0xDC,
++	0x0C, 0xE3, 0x6A, 0xE6, 0xA2,
++	0x09, 0x90, 0x6C, 0x27, 0xEA,
++	0x02, 0xD3, 0x8E, 0x45, 0x0A,
++	0x03, 0xF6, 0x49, 0x6F, 0xC9,
++	0x00, 0x1A, 0x58, 0x61, 0xEB,
++	0x05, 0xD7, 0x19, 0x2C, 0xBB,
++	0x0E, 0xDD, 0xC6, 0xBA, 0xAC,
++	0x0F, 0x3C, 0xAA, 0x25, 0xEB,
++	0x01, 0xBE, 0x60, 0xE9, 0x7D,
++	0x05, 0x12, 0x19, 0xC7, 0x84,
++	0x0D, 0x0E, 0xF0, 0xEF, 0x83,
++	0x0F, 0x17, 0x32, 0x3F, 0xC4,
++	0x05, 0xE7, 0xCD, 0x8A, 0x11,
++	0x02, 0xD5, 0xC4, 0xC4, 0xC0,
++	0x00, 0x18, 0x8E, 0x55, 0x86,
++	0x05, 0x5C, 0x6A, 0x15, 0xA7,
++	0x04, 0x93, 0x5F, 0x9F, 0x53,
++	0x00, 0x18, 0xCA, 0x22, 0x3D,
++	0x02, 0xC7, 0x5B, 0x41, 0x4D,
++	0x04, 0x8D, 0xA0, 0xD8, 0x2D,
++	0x04, 0x5E, 0x0A, 0x5A, 0x57,
++	0x0A, 0x3F, 0x9C, 0xFA, 0xEE,
++	0x04, 0x33, 0x85, 0xE3, 0x87,
++	0x01, 0xC1, 0xFF, 0x07, 0x8F,
++	0x0E, 0x64, 0x12, 0x9D, 0x67,
++	0x04, 0x1D, 0x8C, 0xAE, 0x08,
++	0x0B, 0x89, 0x88, 0x8E, 0x5F,
++	0x08, 0x1C, 0x0B, 0x01, 0x29,
++	0x02, 0x92, 0x8C, 0x4F, 0x1D,
++	0x09, 0xBF, 0x27, 0xA6, 0x6E,
++	0x0D, 0x94, 0x6A, 0x7F, 0x4A,
++	0x06, 0x7A, 0x7B, 0x19, 0xF4,
++	0x02, 0x5A, 0x10, 0x56, 0xBA,
++	0x08, 0x91, 0x15, 0x2E, 0x29,
++	0x09, 0xA2, 0x7C, 0xD4, 0x58,
++	0x0F, 0x8B, 0x7B, 0x34, 0x3B,
++	0x0A, 0xFE, 0xCA, 0x7C, 0x9C,
++	0x01, 0xA4, 0xFA, 0x4B, 0xDF,
++	0x06, 0x2A, 0x47, 0x1D, 0x1D,
++	0x07, 0x11, 0x04, 0x80, 0xA1,
++	0x09, 0x56, 0x1F, 0xD3, 0x72,
++	0x09, 0x54, 0xDF, 0xA2, 0x49,
++	0x0F, 0xCD, 0xAF, 0x70, 0x61,
++	0x08, 0xD2, 0xFF, 0x8F, 0x97,
++	0x05, 0x9E, 0x39, 0x6C, 0xFF,
++	0x0F, 0x60, 0x31, 0xF5, 0x90,
++	0x01, 0xDC, 0x59, 0xC0, 0x27,
++	0x00, 0xEB, 0x6C, 0x90, 0x0E,
++	0x0E, 0xB4, 0x28, 0x77, 0x44,
++	0x08, 0x1E, 0xF8, 0xBD, 0xD0,
++	0x0E, 0x76, 0x8F, 0x3A, 0xEC,
++	0x04, 0x8C, 0x36, 0xAE, 0x26,
++	0x03, 0x01, 0xC8, 0xC2, 0x72,
++	0x05, 0x36, 0x67, 0xE4, 0x10,
++	0x0D, 0x3F, 0x64, 0x12, 0xF6,
++	0x0A, 0x99, 0x82, 0xC2, 0xDB,
++	0x0B, 0x7D, 0xDB, 0x3A, 0xCB,
++	0x07, 0x7D, 0xD0, 0x6B, 0x6E,
++	0x0D, 0x6B, 0xE8, 0xA0, 0x5C,
++	0x0C, 0xBB, 0x97, 0xCE, 0x93,
++	0x07, 0x51, 0x35, 0x1C, 0x25,
++	0x0C, 0xD0, 0xEA, 0x0F, 0xF2,
++	0x0D, 0xF1, 0x74, 0xA0, 0x5E,
++	0x0D, 0x1E, 0x79, 0xD8, 0xA3,
++	0x0C, 0x6D, 0x58, 0xCC, 0x4E,
++	0x02, 0x11, 0x80, 0x65, 0x52,
++	0x0F, 0x4D, 0xC8, 0x21, 0x90,
++	0x0E, 0xC9, 0x2F, 0xF9, 0xFF,
++	0x08, 0x01, 0x8C, 0xA3, 0x4B,
++	0x03, 0xAC, 0x95, 0x96, 0x78,
++	0x02, 0x21, 0x36, 0xC1, 0x82,
++	0x07, 0xD5, 0x40, 0xB5, 0x79,
++	0x01, 0x03, 0x9D, 0x37, 0x2E,
++	0x04, 0x43, 0x38, 0x4E, 0x59,
++	0x07, 0xAE, 0x9F, 0xE0, 0xFB,
++	0x04, 0x97, 0xC1, 0x39, 0x5A,
++	0x0A, 0x09, 0x11, 0x42, 0xB8,
++	0x0C, 0x49, 0x38, 0xA8, 0x84,
++	0x04, 0x79, 0x0A, 0xB0, 0x5E,
++	0x0C, 0xE0, 0x82, 0xB4, 0x7D,
++	0x02, 0x2B, 0x72, 0x7C, 0x64,
++	0x03, 0x68, 0xC6, 0x81, 0xB6,
++	0x08, 0xEB, 0x2C, 0xE7, 0x75,
++	0x08, 0xB7, 0xDB, 0x08, 0x6F,
++	0x0A, 0x81, 0x4A, 0xD4, 0xEC,
++	0x0D, 0x3C, 0xD5, 0x5D, 0x40,
++	0x08, 0xF0, 0x70, 0xB3, 0x43,
++	0x07, 0x3F, 0xE0, 0xF7, 0xC5,
++	0x05, 0x02, 0xB3, 0xB8, 0xAA,
++	0x0B, 0x62, 0x24, 0x31, 0xB5,
++	0x01, 0x31, 0x10, 0x08, 0x46,
++	0x0A, 0x14, 0x81, 0xB1, 0x37,
++	0x0A, 0xB4, 0xE9, 0xEB, 0xA4,
++	0x0E, 0xEE, 0xB4, 0xC1, 0xC6,
++	0x08, 0x8B, 0x8B, 0x68, 0xB5,
++	0x0D, 0x59, 0xE3, 0xEE, 0x83,
++	0x07, 0x77, 0xE7, 0x5F, 0x4B,
++	0x02, 0x95, 0xE9, 0xDE, 0x8D,
++	0x0D, 0x1C, 0x92, 0x85, 0x10,
++	0x0B, 0x7D, 0xCC, 0x07, 0x70,
++	0x03, 0xDD, 0xEF, 0x8B, 0x8E,
++	0x0C, 0x0F, 0xC8, 0xF5, 0xA6,
++	0x09, 0x7A, 0xE3, 0x6A, 0xFE,
++	0x0A, 0x20, 0x14, 0x88, 0x6C,
++	0x03, 0x43, 0x9A, 0x6E, 0x85,
++	0x03, 0x5D, 0x16, 0x48, 0xB8,
++	0x01, 0x01, 0x3C, 0x0A, 0x25,
++	0x02, 0xDD, 0xF5, 0x63, 0x6C,
++	0x0A, 0xC7, 0x1D, 0x06, 0x76,
++	0x0D, 0x93, 0x5E, 0xAE, 0x4F,
++	0x01, 0x0B, 0xBA, 0x91, 0x89,
++	0x09, 0x75, 0x12, 0x1D, 0x82,
++	0x04, 0xCD, 0x0A, 0xF4, 0xBF,
++	0x03, 0x5F, 0xB7, 0x32, 0x09,
++	0x0F, 0xD0, 0x27, 0xCD, 0x8A,
++	0x03, 0xC6, 0xD1, 0xC0, 0x84,
++	0x00, 0x21, 0x18, 0x4E, 0x55,
++	0x07, 0xF5, 0x1C, 0x8E, 0xC2,
++	0x0E, 0x6C, 0x72, 0xDE, 0x53,
++	0x0A, 0x18, 0xD8, 0xCE, 0xB4,
++	0x06, 0x24, 0x23, 0x59, 0xA7,
++	0x05, 0xBC, 0xB8, 0xED, 0xF8,
++	0x0F, 0x7D, 0x54, 0x0E, 0xD7,
++	0x07, 0x70, 0x39, 0xD2, 0x7A,
++	0x0B, 0x24, 0xF3, 0x85, 0xED,
++	0x0A, 0x1D, 0xE1, 0xFF, 0x4D,
++	0x07, 0x6E, 0xAC, 0x16, 0x1D,
++	0x08, 0xCF, 0x9B, 0x15, 0x23,
++	0x01, 0xAA, 0x63, 0x48, 0x9E,
++	0x0A, 0x30, 0x94, 0xAF, 0x46,
++	0x01, 0xB9, 0x14, 0x2A, 0x98,
++	0x01, 0x8D, 0x1F, 0x20, 0xE6,
++	0x0C, 0x21, 0x94, 0x69, 0x7C,
++	0x03, 0x8E, 0xB6, 0xCB, 0x5F,
++	0x0C, 0x1A, 0xDF, 0xB0, 0x5A,
++	0x09, 0x28, 0xF0, 0xAB, 0x6E,
++	0x09, 0x63, 0x64, 0xF5, 0x14,
++	0x0B, 0x76, 0xCB, 0xDF, 0xF4,
++	0x03, 0x41, 0xBE, 0x0E, 0xBC,
++	0x0C, 0x59, 0x81, 0x3B, 0x47,
++	0x0F, 0x36, 0x2A, 0x47, 0x1B,
++	0x07, 0x13, 0x11, 0x00, 0x84,
++	0x03, 0x39, 0x56, 0x1D, 0x93,
++	0x0A, 0xE0, 0xF6, 0x9F, 0xF2,
++	0x0B, 0xFF, 0xE5, 0x4C, 0xC0,
++	0x08, 0x28, 0xD2, 0xFE, 0x8B,
++	0x05, 0x65, 0x1E, 0x30, 0x28,
++	0x0D, 0x31, 0xE2, 0xB9, 0xF5,
++	0x0A, 0x2E, 0x14, 0x5D, 0xE0,
++	0x0B, 0x49, 0xEA, 0x28, 0x93,
++	0x06, 0x91, 0x36, 0x68, 0x37,
++	0x0D, 0xFB, 0x55, 0xF8, 0xF9,
++	0x08, 0xCA, 0xD4, 0x82, 0x7E,
++	0x04, 0xD5, 0x2E, 0x3B, 0x6E,
++	0x0E, 0xAB, 0xA1, 0x05, 0x02,
++	0x02, 0xAC, 0x37, 0xAB, 0xE0,
++	0x00, 0xAD, 0x3F, 0x60, 0xD3,
++	0x07, 0x1D, 0xD7, 0x84, 0xBD,
++	0x0A, 0x23, 0x5A, 0x1B, 0x7E,
++	0x00, 0xBB, 0x33, 0xD6, 0xE8,
++	0x05, 0x47, 0xCC, 0xE4, 0xBD,
++	0x02, 0xBC, 0xBD, 0x8F, 0x87,
++	0x03, 0xD7, 0x51, 0xA1, 0xD6,
++	0x0F, 0x6C, 0xD0, 0x69, 0x85,
++	0x08, 0x3D, 0xF1, 0x70, 0x64,
++	0x0C, 0x6E, 0x3D, 0x7E, 0x4B,
++	0x01, 0x1E, 0x4D, 0x1C, 0x98,
++	0x0E, 0x04, 0xDA, 0x04, 0xE1,
++	0x00, 0xEF, 0xED, 0xC8, 0xA1,
++	0x0A, 0x7E, 0xC9, 0xAD, 0x0B,
++	0x05, 0x33, 0x01, 0x5E, 0x21,
++	0x0B, 0xFA, 0x2C, 0x77, 0x14,
++	0x08, 0xFB, 0xA0, 0xD5, 0x99,
++	0x09, 0x50, 0x82, 0xC4, 0xEF,
++	0x02, 0xF0, 0x54, 0x1B, 0x54,
++	0x0E, 0xA2, 0x47, 0x36, 0x17,
++	0x09, 0xA1, 0xDB, 0x9C, 0xF5,
++	0x00, 0x65, 0xBB, 0x4F, 0xED,
++	0x0A, 0x3C, 0xF5, 0x37, 0x98,
++	0x03, 0x5D, 0xE5, 0x9E, 0xFB,
++	0x04, 0x23, 0x0E, 0x4C, 0x7A,
++	0x0C, 0x9B, 0x94, 0xC4, 0x74,
++	0x0D, 0x92, 0x5B, 0xF1, 0x29,
++	0x06, 0x63, 0x99, 0x4A, 0xAD,
++	0x04, 0xB8, 0x4B, 0x2C, 0xC3,
++	0x0E, 0xC2, 0xCD, 0x39, 0x85,
++	0x06, 0xA8, 0x81, 0x4C, 0x72,
++	0x04, 0x01, 0xEC, 0xCF, 0x55,
++	0x04, 0x86, 0x77, 0x3D, 0xB9,
++	0x03, 0xBC, 0x3F, 0xE4, 0x3D,
++	0x0F, 0xCA, 0x5B, 0xD3, 0xB5,
++	0x00, 0x70, 0x02, 0x26, 0xF1,
++	0x0C, 0x73, 0x55, 0x10, 0xC8,
++	0x06, 0x13, 0x96, 0xE3, 0x07,
++	0x07, 0x22, 0x86, 0xED, 0x31,
++	0x0E, 0xB1, 0x3D, 0x54, 0xCE,
++	0x06, 0x32, 0x8D, 0x2F, 0xD2,
++	0x08, 0xD6, 0x98, 0xE1, 0x6E,
++	0x0A, 0xD9, 0x32, 0x0B, 0x9F,
++	0x0F, 0x04, 0x4E, 0x65, 0xCC,
++	0x0E, 0x74, 0x9E, 0xB6, 0xBB,
++	0x0C, 0xE1, 0x7A, 0xE8, 0x0D,
++	0x08, 0x7F, 0xC1, 0xE1, 0xC2,
++	0x09, 0x04, 0xA7, 0x6A, 0x40,
++	0x0F, 0x45, 0xAC, 0xE3, 0x5B,
++	0x0B, 0x60, 0x06, 0x12, 0x0C,
++	0x0D, 0x2C, 0x22, 0x7A, 0x6C,
++	0x0C, 0x0A, 0x13, 0xF8, 0xC9,
++	0x05, 0xCF, 0x48, 0x98, 0x4C,
++	0x0C, 0x1A, 0x9F, 0xDD, 0xA3,
++	0x06, 0xB5, 0x26, 0xDD, 0x46,
++	0x06, 0xEC, 0x16, 0xB2, 0x9B,
++	0x0B, 0xAB, 0x06, 0xB8, 0x1C,
++	0x09, 0x3D, 0x75, 0x3C, 0x04,
++	0x0E, 0xF6, 0xCC, 0xCE, 0xFE,
++	0x07, 0x03, 0x6B, 0x17, 0xB2,
++	0x01, 0xCC, 0xF1, 0xE7, 0x4D,
++	0x00, 0x97, 0x20, 0x55, 0xC0,
++	0x0D, 0x40, 0xE1, 0x14, 0x0E,
++	0x0F, 0x80, 0x11, 0x5C, 0xCA,
++	0x0D, 0x27, 0x4C, 0x92, 0xDF,
++	0x03, 0x53, 0x34, 0x18, 0xCA,
++	0x04, 0xBF, 0xAE, 0xC7, 0x59,
++	0x05, 0x8F, 0xBE, 0x0B, 0x2D,
++	0x00, 0xAD, 0xD9, 0x54, 0x8A,
++	0x07, 0x06, 0xD0, 0x37, 0x9B,
++	0x03, 0x6B, 0xC4, 0x3F, 0x85,
++	0x04, 0x90, 0x7D, 0xEC, 0x3F,
++	0x07, 0xBE, 0x2E, 0x42, 0x50,
++	0x07, 0xA5, 0x2E, 0x9B, 0x11,
++	0x03, 0x8D, 0xAB, 0x87, 0x4C,
++	0x00, 0x42, 0x32, 0x9C, 0xEE,
++	0x06, 0x6E, 0xD9, 0x99, 0xA8,
++	0x07, 0xD9, 0xA4, 0x33, 0xA6,
++	0x0C, 0x66, 0xDC, 0x94, 0x49,
++	0x06, 0x45, 0x4E, 0xB2, 0x0F,
++	0x07, 0xF4, 0xBF, 0xD9, 0x30,
++	0x01, 0x7D, 0xC8, 0x90, 0x25,
++	0x0E, 0xE0, 0x73, 0xA2, 0x46,
++	0x02, 0x48, 0x65, 0x09, 0x5B,
++	0x0C, 0x33, 0x43, 0xF3, 0xCF,
++	0x0D, 0x04, 0x08, 0x25, 0xC9,
++	0x07, 0x9F, 0x36, 0x2E, 0x76,
++	0x05, 0xD7, 0xDE, 0x11, 0x00,
++	0x04, 0x61, 0x3B, 0x76, 0x12,
++	0x03, 0x72, 0x28, 0x7A, 0xCC,
++	0x0A, 0xCB, 0xDE, 0x4D, 0xC6,
++	0x09, 0xE3, 0xC8, 0xD2, 0x7E,
++	0x0B, 0x1D, 0x65, 0xAD, 0x3D,
++	0x08, 0x35, 0xB7, 0x26, 0xEE,
++	0x05, 0x50, 0x29, 0x59, 0x87,
++	0x0C, 0xF8, 0xB6, 0x17, 0xAB,
++	0x09, 0xCE, 0xD7, 0xB6, 0x28,
++	0x03, 0x87, 0xFC, 0x18, 0x7B,
++	0x01, 0x10, 0xEA, 0x76, 0x0F,
++	0x0E, 0xB6, 0x74, 0x83, 0xB2,
++	0x04, 0x20, 0xDC, 0x81, 0x0A,
++	0x0A, 0xF2, 0x0C, 0x39, 0x26,
++	0x0E, 0x56, 0x53, 0xBF, 0x44,
++	0x0E, 0x7E, 0xFA, 0x9B, 0x00,
++	0x0C, 0x57, 0x5E, 0xFD, 0x1E,
++	0x00, 0x0B, 0x3F, 0xF0, 0x24,
++	0x03, 0xEE, 0x61, 0x6A, 0x6A,
++	0x0B, 0xD4, 0x1B, 0xBB, 0x81,
++	0x0E, 0x93, 0xD7, 0x5D, 0xAB,
++	0x08, 0x2F, 0x6C, 0xD6, 0x6F,
++	0x0F, 0xF8, 0x3D, 0xF1, 0x73,
++	0x01, 0x94, 0x2D, 0x1E, 0x7C,
++	0x00, 0x2B, 0x5C, 0x61, 0x9C,
++	0x06, 0x42, 0xFC, 0x91, 0x8C,
++	0x0C, 0x58, 0xAF, 0x41, 0x08,
++	0x08, 0x5A, 0xBE, 0xC9, 0x6D,
++	0x01, 0x37, 0x33, 0x0D, 0x8C,
++	0x03, 0x4B, 0xFA, 0x3A, 0xF7,
++	0x06, 0x78, 0xFB, 0xA3, 0xE0,
++	0x0D, 0x82, 0xD5, 0xD5, 0x04,
++	0x0F, 0x7F, 0x87, 0x83, 0x8D,
++	0x0B, 0xAE, 0xA3, 0xC3, 0x09,
++	0x06, 0xD1, 0x21, 0xD3, 0xDF,
++	0x08, 0x79, 0xE2, 0xEA, 0x01,
++	0x05, 0xDA, 0x39, 0xB9, 0xB2,
++	0x0A, 0xB8, 0x7A, 0xB6, 0x98,
++	0x00, 0x85, 0x83, 0x09, 0x8A,
++	0x00, 0xDE, 0x9B, 0x91, 0x06,
++	0x04, 0xFD, 0x92, 0x58, 0x81,
++	0x01, 0xE1, 0x64, 0x94, 0xC3,
++	0x09, 0x74, 0x95, 0xEB, 0x2C,
++	0x01, 0xF7, 0x41, 0x99, 0xE6,
++	0x05, 0xAF, 0xAE, 0xBD, 0x19,
++	0x00, 0xEE, 0x03, 0x0A, 0xCF,
++	0x0F, 0x44, 0x82, 0x30, 0x3D,
++	0x00, 0x43, 0x7C, 0x0F, 0x60,
++	0x04, 0xC4, 0x00, 0xB2, 0xD3,
++	0x07, 0x78, 0x3F, 0x52, 0x24,
++	0x02, 0xB4, 0xBD, 0x11, 0x90,
++	0x0B, 0x47, 0xD3, 0x95, 0xE1,
++	0x0C, 0x36, 0xE2, 0x85, 0x69,
++	0x0A, 0x25, 0x77, 0xE4, 0xD4,
++	0x05, 0xD7, 0x92, 0x81, 0x2F,
++	0x00, 0xB3, 0xD6, 0x55, 0xE3,
++	0x0E, 0x83, 0x5B, 0x50, 0x89,
++	0x05, 0x52, 0x04, 0x95, 0xF5,
++	0x07, 0x89, 0x13, 0x1A, 0x79,
++	0x09, 0x0C, 0xE1, 0x78, 0x54,
++	0x07, 0x78, 0x7F, 0xCC, 0xEA,
++	0x03, 0x99, 0x84, 0xA7, 0x68,
++	0x0B, 0x66, 0x65, 0x48, 0xE3,
++	0x04, 0x62, 0xAF, 0x20, 0x10,
++	0x0C, 0x27, 0x28, 0xED, 0x67,
++	0x06, 0x44, 0x8A, 0xCF, 0xF6,
++	0x0F, 0x6F, 0xC9, 0x89, 0x18,
++	0x0A, 0x65, 0x1A, 0x5F, 0x51,
++	0x04, 0xAC, 0x73, 0xC7, 0x5D,
++	0x07, 0xB6, 0x2C, 0x12, 0xBD,
++	0x0B, 0x85, 0xCB, 0xCB, 0xB1,
++	0x0C, 0xE9, 0x3D, 0x73, 0x98,
++	0x01, 0xC0, 0xF6, 0xCD, 0xCE,
++	0x0A, 0xF8, 0x9B, 0xDF, 0x15,
++	0x06, 0x09, 0x4E, 0xD7, 0x67,
++	0x09, 0x8A, 0x91, 0xC0, 0x15,
++	0x04, 0x45, 0xE0, 0x2F, 0x51,
++	0x0E, 0xD4, 0x27, 0x74, 0xDC,
++	0x02, 0x15, 0x26, 0x6C, 0xD2,
++	0x06, 0x99, 0x51, 0x3D, 0xD8,
++	0x00, 0x33, 0xAF, 0x22, 0xC3,
++	0x02, 0xE1, 0x28, 0xB6, 0x89,
++	0x0D, 0xD8, 0x2F, 0x7D, 0x09,
++	0x02, 0x5F, 0x12, 0x7D, 0xF9,
++	0x00, 0x7A, 0xEC, 0xA2, 0xB3,
++	0x05, 0xED, 0x98, 0x9D, 0xE1,
++	0x0E, 0x07, 0x7B, 0xAE, 0x64,
++	0x03, 0x9C, 0x66, 0x4F, 0xA0,
++	0x0D, 0xA1, 0xCD, 0xAB, 0x49,
++	0x08, 0x62, 0x62, 0x30, 0x6D,
++	0x0B, 0x0D, 0xE9, 0x3F, 0x9E,
++	0x0B, 0x4F, 0xDB, 0x21, 0xF5,
++	0x0C, 0xA1, 0x44, 0x31, 0x96,
++	0x09, 0x7F, 0x45, 0x82, 0x89,
++	0x01, 0x9F, 0xB9, 0x1A, 0xDB,
++	0x09, 0xDA, 0x1A, 0xA8, 0x94,
++	0x06, 0x2C, 0x80, 0x7F, 0xE4,
++	0x0F, 0xD3, 0x6A, 0xE7, 0x03,
++	0x0B, 0x34, 0x3B, 0xCF, 0xBC,
++	0x07, 0x7E, 0x5C, 0xD4, 0x25,
++	0x01, 0x40, 0xBF, 0x36, 0x3A,
++	0x0F, 0x13, 0xD7, 0x1E, 0xD1,
++	0x0C, 0x84, 0x66, 0xB9, 0x55,
++	0x02, 0x53, 0x92, 0x26, 0x56,
++	0x06, 0x33, 0xAB, 0x7E, 0x0D,
++	0x05, 0xC0, 0xA3, 0x24, 0x17,
++	0x07, 0x81, 0x5D, 0x68, 0x5E,
++	0x0E, 0xE8, 0x35, 0xBB, 0xE4,
++	0x05, 0xF5, 0x50, 0x2D, 0xEC,
++	0x03, 0x40, 0x2A, 0x49, 0xEB,
++	0x08, 0x90, 0xCE, 0x33, 0x6B,
++	0x00, 0xF7, 0x27, 0xFC, 0x9E,
++	0x08, 0xB9, 0x94, 0x4A, 0x87,
++	0x07, 0xBC, 0x48, 0x54, 0x0E,
++	0x0F, 0xAE, 0xE6, 0x2C, 0xC1,
++	0x02, 0xC5, 0x18, 0x2C, 0x77,
++	0x0F, 0xE4, 0x94, 0xAB, 0x7F,
++	0x0E, 0x91, 0x96, 0x1A, 0x9B,
++	0x09, 0xC6, 0x95, 0xAB, 0x7D,
++	0x0C, 0x3D, 0xA1, 0xBC, 0x5D,
++	0x00, 0x6B, 0x6A, 0xC1, 0x6B,
++	0x00, 0xA7, 0x38, 0x3C, 0xBA,
++	0x09, 0xCC, 0x93, 0xDB, 0x51,
++	0x01, 0x9C, 0x2B, 0x4A, 0x92,
++	0x05, 0x08, 0xDF, 0xBD, 0xE1,
++	0x03, 0x20, 0x94, 0xE1, 0xDA,
++	0x0C, 0xD8, 0xA9, 0x11, 0x68,
++	0x0C, 0x4C, 0x44, 0x02, 0xE2,
++	0x0D, 0x65, 0xB8, 0x6F, 0x4D,
++	0x00, 0xA9, 0xDA, 0x73, 0x09,
++	0x03, 0x79, 0xF8, 0x33, 0x01,
++	0x0C, 0xA3, 0x49, 0xDA, 0x25,
++	0x05, 0x96, 0x78, 0xE7, 0xF7,
++	0x0F, 0x74, 0x62, 0xE7, 0x5F,
++	0x04, 0xA5, 0x79, 0x77, 0x83,
++	0x09, 0x27, 0xAE, 0xA2, 0xC3,
++	0x08, 0xDE, 0x79, 0xAF, 0x97,
++	0x0E, 0xF0, 0xBA, 0x62, 0xE6,
++	0x09, 0x2B, 0xDB, 0xB0, 0xF9,
++	0x01, 0x52, 0x39, 0x4C, 0xFA,
++	0x08, 0x88, 0x06, 0x05, 0x8B,
++	0x00, 0xB7, 0xEC, 0x9B, 0x81,
++	0x02, 0xB4, 0xFF, 0x9E, 0xDF,
++	0x0A, 0xE8, 0x06, 0x8F, 0xD9,
++	0x06, 0x97, 0xF4, 0xD6, 0x21,
++	0x0C, 0xF1, 0xF5, 0x45, 0x67,
++	0x01, 0x02, 0xE3, 0xAA, 0x89,
++	0x0A, 0xF2, 0xEE, 0x0A, 0x7F,
++	0x07, 0x4D, 0xC4, 0x8B, 0xB0,
++	0x03, 0x33, 0x8E, 0xBC, 0x3F,
++	0x08, 0x77, 0x65, 0xDC, 0x02,
++	0x08, 0x32, 0xDE, 0xF3, 0x6E,
++	0x0C, 0xF1, 0x15, 0x51, 0xB1,
++	0x0B, 0x8E, 0xE1, 0x15, 0x24,
++	0x01, 0xBD, 0x27, 0x20, 0x48,
++	0x05, 0xC1, 0x24, 0xB7, 0xFD,
++	0x04, 0xCC, 0x0E, 0x30, 0x40,
++	0x0F, 0xE8, 0xB9, 0xD6, 0x59,
++	0x01, 0xEE, 0x8B, 0x57, 0x36,
++	0x09, 0x5F, 0x5D, 0x0E, 0xD5,
++	0x07, 0x74, 0xBE, 0x72, 0x1E,
++	0x09, 0xA1, 0xCC, 0xE7, 0xFB,
++	0x07, 0x2F, 0x98, 0x7F, 0xC1,
++	0x0F, 0x23, 0x39, 0x12, 0xE5,
++	0x08, 0xF3, 0xE6, 0xD3, 0xCA,
++	0x03, 0x6A, 0xE2, 0x74, 0xE2,
++	0x00, 0x8C, 0x27, 0x0C, 0x81,
++	0x02, 0x6C, 0x45, 0x06, 0xD3,
++	0x0C, 0x4E, 0x54, 0x49, 0xB9,
++	0x03, 0x0C, 0x65, 0x1A, 0x5F,
++	0x0D, 0x7C, 0x53, 0x4F, 0xF6,
++	0x01, 0x03, 0x66, 0xEC, 0x12,
++	0x04, 0x6A, 0x85, 0x25, 0x44,
++	0x08, 0x1C, 0xE9, 0x21, 0x37,
++	0x0E, 0x1F, 0xF2, 0xF6, 0xC9,
++	0x04, 0x30, 0xBF, 0x8D, 0x4D,
++	0x07, 0x32, 0x09, 0x52, 0x93,
++	0x0C, 0xCD, 0x8A, 0x91, 0xC6,
++	0x09, 0xC4, 0x2D, 0xC0, 0x28,
++	0x08, 0x4E, 0x55, 0x86, 0xFE,
++	0x00, 0x8A, 0xFF, 0x67, 0xE5,
++	0x02, 0xDF, 0x91, 0x53, 0x3A,
++	0x08, 0xCA, 0x34, 0xB2, 0xE6,
++	0x0D, 0xB9, 0x7C, 0x01, 0x20,
++	0x0D, 0x6D, 0xD8, 0x3D, 0x7F,
++	0x0F, 0x0A, 0x57, 0x97, 0x70,
++	0x01, 0x52, 0xDA, 0xEA, 0x24,
++	0x0A, 0x05, 0x0D, 0x9A, 0x1D,
++	0x0F, 0x7F, 0xCA, 0xBE, 0x2E,
++	0x04, 0x12, 0x9D, 0xBD, 0xD2,
++	0x02, 0x94, 0xC3, 0xA1, 0xBA,
++	0x0F, 0x88, 0x80, 0x42, 0xB0,
++	0x0A, 0xAB, 0x0D, 0xE9, 0x39,
++	0x04, 0x5B, 0xCF, 0xD9, 0x25,
++	0x0F, 0x57, 0x26, 0x60, 0x31,
++	0x0D, 0x6B, 0x1F, 0x45, 0x4E,
++	0x08, 0xC8, 0x4B, 0x74, 0x18,
++	0x03, 0x01, 0xFA, 0xFC, 0xA8,
++	0x0C, 0xA7, 0xAE, 0xE6, 0x73,
++	0x0C, 0xFC, 0x54, 0x48, 0xE7,
++	0x02, 0xD1, 0x54, 0x36, 0x03,
++	0x0E, 0x0F, 0x7C, 0x5C, 0xC8,
++	0x05, 0x3B, 0x47, 0xB9, 0x34,
++	0x00, 0x40, 0x54, 0x57, 0x17,
++	0x0A, 0x00, 0x84, 0x61, 0x39,
++	0x0F, 0x9B, 0x31, 0x7E, 0x28,
++	0x0E, 0x1F, 0x12, 0x5B, 0xFE,
++	0x03, 0xCC, 0x0D, 0x63, 0x28,
++	0x0B, 0x7F, 0x6B, 0x11, 0x65,
++	0x06, 0x3C, 0xC8, 0x25, 0x06,
++	0x0A, 0xB2, 0xAE, 0x50, 0x2B,
++	0x06, 0xDD, 0x60, 0xEB, 0x09,
++	0x03, 0xAA, 0xF0, 0xC2, 0x97,
++	0x0C, 0x6F, 0x2F, 0x07, 0xF8,
++	0x0E, 0xF8, 0xBB, 0x90, 0x4A,
++	0x0D, 0x8F, 0x3E, 0x62, 0x49,
++	0x0C, 0x36, 0xAE, 0x2A, 0xE2,
++	0x08, 0x88, 0x26, 0x7E, 0x6C,
++	0x07, 0x86, 0x64, 0x50, 0xAD,
++	0x0F, 0x46, 0x96, 0xFC, 0x9A,
++	0x03, 0x87, 0xA6, 0x51, 0xA7,
++	0x04, 0x97, 0xBA, 0xC9, 0xBC,
++	0x06, 0xD0, 0x6B, 0x62, 0xD0,
++	0x02, 0xE8, 0x84, 0x52, 0x4D,
++	0x01, 0x86, 0xAC, 0x93, 0xDF,
++	0x09, 0xA1, 0x3C, 0x23, 0x2C,
++	0x09, 0xED, 0x2B, 0xF8, 0xCC,
++	0x0B, 0x74, 0x43, 0x14, 0xEF,
++	0x06, 0xFC, 0x78, 0xA5, 0x5C,
++	0x05, 0xDE, 0x68, 0x48, 0x42,
++	0x08, 0x84, 0x21, 0x58, 0xAF,
++	0x0F, 0xC8, 0xA5, 0x5E, 0x3E,
++	0x09, 0x2D, 0xF9, 0x35, 0xEA,
++	0x00, 0xA5, 0x63, 0x4B, 0xFA,
++	0x06, 0x72, 0xF1, 0x78, 0xF3,
++	0x09, 0xD6, 0x1D, 0x82, 0xD7,
++	0x0E, 0x40, 0xA5, 0x79, 0x77,
++	0x09, 0x5D, 0x26, 0x20, 0x71,
++	0x03, 0x38, 0x5E, 0xF9, 0x22,
++	0x0E, 0x1F, 0xF0, 0x5B, 0xA0,
++	0x06, 0x41, 0x29, 0xDA, 0x3C,
++	0x09, 0xB1, 0x52, 0x38, 0xDA,
++	0x03, 0x98, 0x88, 0x04, 0x23,
++	0x0B, 0xCA, 0xB0, 0xD8, 0xDB,
++	0x09, 0xC2, 0x14, 0xFD, 0x12,
++	0x0B, 0x73, 0xCA, 0x62, 0xDE,
++	0x03, 0x41, 0xB9, 0xF4, 0x59
++};
++
++static unsigned char ak77dspPRAM[] = {
++	0x0C, 0x94, 0xED, 0x1E, 0x74,
++	0x04, 0xA8, 0x9C, 0x6D, 0x55,
++	0x00, 0x44, 0x02, 0x11, 0x99,
++	0x09, 0x58, 0x6F, 0x4D, 0xD0,
++	0x01, 0x5A, 0x7C, 0xC9, 0x27,
++	0x09, 0x35, 0x31, 0x01, 0x86,
++	0x03, 0x4B, 0xFA, 0x2C, 0x75,
++	0x06, 0x78, 0xFB, 0xA8, 0xF4,
++	0x0D, 0x82, 0xD7, 0xDD, 0xE0,
++	0x05, 0x79, 0x77, 0x0B, 0x3C,
++	0x08, 0xAE, 0xA2, 0x43, 0x38
++};
++
++u8 cram_data[] = {
++	0x7F, 0xFF, 0xF0,
++	0x7F, 0xFD, 0x90,
++	0x7F, 0xF6, 0x20,
++	0x7F, 0xE9, 0xD0,
++	0x7F, 0xD8, 0x80,
++	0x7F, 0xC2, 0x50,
++	0x7F, 0xA7, 0x30,
++	0x7F, 0x87, 0x30,
++	0x7F, 0x62, 0x30,
++	0x7F, 0x38, 0x50,
++	0x7F, 0x09, 0x90,
++	0x7E, 0xD5, 0xE0,
++	0x7E, 0x9D, 0x50,
++	0x7E, 0x5F, 0xE0,
++	0x7E, 0x1D, 0x90,
++	0x7D, 0xD6, 0x60,
++	0x7D, 0x8A, 0x60,
++	0x7D, 0x39, 0x80,
++	0x7C, 0xE3, 0xD0,
++	0x7C, 0x89, 0x50,
++	0x7C, 0x2A, 0x00,
++	0x7B, 0xC5, 0xE0,
++	0x7B, 0x5D, 0x00,
++	0x7A, 0xEF, 0x60,
++	0x7A, 0x7D, 0x00,
++	0x7A, 0x05, 0xF0,
++	0x79, 0x8A, 0x20,
++	0x79, 0x09, 0xB0,
++	0x78, 0x84, 0x80,
++	0x77, 0xFA, 0xC0,
++	0x77, 0x6C, 0x50,
++	0x76, 0xD9, 0x50,
++	0x76, 0x41, 0xB0,
++	0x75, 0xA5, 0x80,
++	0x75, 0x04, 0xD0,
++	0x74, 0x5F, 0xA0,
++	0x73, 0xB5, 0xF0,
++	0x73, 0x07, 0xC0,
++	0x72, 0x55, 0x30,
++	0x71, 0x9E, 0x30,
++	0x70, 0xE2, 0xD0,
++	0x70, 0x23, 0x10,
++	0x6F, 0x5F, 0x00,
++	0x6E, 0x96, 0xB0,
++	0x6D, 0xCA, 0x10,
++	0x6C, 0xF9, 0x30,
++	0x6C, 0x24, 0x30,
++	0x6B, 0x4A, 0xF0,
++	0x6A, 0x6D, 0xA0,
++	0x69, 0x8C, 0x20,
++	0x68, 0xA6, 0xA0,
++	0x67, 0xBD, 0x10,
++	0x66, 0xCF, 0x80,
++	0x65, 0xDE, 0x00,
++	0x64, 0xE8, 0x90,
++	0x63, 0xEF, 0x30,
++	0x62, 0xF2, 0x00,
++	0x61, 0xF1, 0x00,
++	0x60, 0xEC, 0x40,
++	0x5F, 0xE3, 0xB0,
++	0x5E, 0xD7, 0x80,
++	0x5D, 0xC7, 0xA0,
++	0x5C, 0xB4, 0x20,
++	0x5B, 0x9D, 0x10,
++	0x5A, 0x82, 0x80,
++	0x59, 0x64, 0x60,
++	0x58, 0x42, 0xE0,
++	0x57, 0x1D, 0xF0,
++	0x55, 0xF5, 0xA0,
++	0x54, 0xCA, 0x10,
++	0x53, 0x9B, 0x30,
++	0x52, 0x69, 0x10,
++	0x51, 0x33, 0xD0,
++	0x4F, 0xFB, 0x60,
++	0x4E, 0xBF, 0xF0,
++	0x4D, 0x81, 0x60,
++	0x4C, 0x3F, 0xE0,
++	0x4A, 0xFB, 0x70,
++	0x49, 0xB4, 0x10,
++	0x48, 0x69, 0xE0,
++	0x47, 0x1C, 0xF0,
++	0x45, 0xCD, 0x30,
++	0x44, 0x7A, 0xD0,
++	0x43, 0x25, 0xC0,
++	0x41, 0xCE, 0x20,
++	0x40, 0x73, 0xF0,
++	0x3F, 0x17, 0x50,
++	0x3D, 0xB8, 0x30,
++	0x3C, 0x56, 0xC0,
++	0x3A, 0xF2, 0xF0,
++	0x39, 0x8C, 0xE0,
++	0x38, 0x24, 0x90,
++	0x36, 0xBA, 0x20,
++	0x35, 0x4D, 0x90,
++	0x33, 0xDE, 0xF0,
++	0x32, 0x6E, 0x50,
++	0x30, 0xFB, 0xC0,
++	0x2F, 0x87, 0x50,
++	0x2E, 0x11, 0x10,
++	0x2C, 0x99, 0x00,
++	0x2B, 0x1F, 0x30,
++	0x29, 0xA3, 0xC0,
++	0x28, 0x26, 0xC0,
++	0x26, 0xA8, 0x20,
++	0x25, 0x28, 0x10,
++	0x23, 0xA6, 0x90,
++	0x22, 0x23, 0xA0,
++	0x20, 0x9F, 0x70,
++	0x1F, 0x1A, 0x00,
++	0x1D, 0x93, 0x50,
++	0x1C, 0x0B, 0x80,
++	0x1A, 0x82, 0xA0,
++	0x18, 0xF8, 0xC0,
++	0x17, 0x6D, 0xE0,
++	0x15, 0xE2, 0x10,
++	0x14, 0x55, 0x70,
++	0x12, 0xC8, 0x10,
++	0x11, 0x39, 0xF0,
++	0x0F, 0xAB, 0x20,
++	0x0E, 0x1B, 0xC0,
++	0x0C, 0x8B, 0xD0,
++	0x0A, 0xFB, 0x70,
++	0x09, 0x6A, 0x90,
++	0x07, 0xD9, 0x60,
++	0x06, 0x47, 0xE0,
++	0x04, 0xB6, 0x20,
++	0x03, 0x24, 0x30,
++	0x01, 0x92, 0x20,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x40, 0x00, 0x00,
++	0x6C, 0xCC, 0xD0,
++	0x04, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x60,
++	0x40, 0x00, 0x00,
++	0x3C, 0x00, 0x00,
++	0x03, 0x33, 0x30,
++	0x14, 0x7A, 0xE0,
++	0x00, 0x09, 0x00,
++	0x68, 0x00, 0x00,
++	0x18, 0x00, 0x00,
++	0x00, 0x06, 0x00,
++	0x41, 0xE3, 0x50,
++	0x40, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x7E, 0x14, 0x80,
++	0x0E, 0xB8, 0x50,
++	0x08, 0x29, 0x60,
++	0x08, 0x29, 0x60,
++	0x00, 0x06, 0x00,
++	0x43, 0xC8, 0x50,
++	0x40, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x7D, 0xF3, 0xB0,
++	0x10, 0x00, 0x00,
++	0x09, 0xDA, 0xF0,
++	0x09, 0xDA, 0xF0,
++	0x00, 0x07, 0x00,
++	0x43, 0xC8, 0x50,
++	0x40, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x7D, 0xF3, 0xB0,
++	0x11, 0x68, 0x70,
++	0x0A, 0xB9, 0xA0,
++	0x0A, 0xB9, 0xA0,
++	0x00, 0x13, 0x00,
++	0x43, 0xC8, 0x50,
++	0x40, 0x00, 0x00,
++	0x0A, 0xCC, 0xD0,
++	0x7D, 0xD2, 0xF0,
++	0x0D, 0x70, 0xA0,
++	0x08, 0x46, 0xF0,
++	0x08, 0x46, 0xF0,
++	0x00, 0x13, 0x00,
++	0x43, 0xC8, 0x50,
++	0x40, 0x00, 0x00,
++	0x0E, 0x66, 0x60,
++	0x7D, 0xB2, 0x30,
++	0x0C, 0x49, 0xC0,
++	0x07, 0xF8, 0x00,
++	0x07, 0xF8, 0x00,
++	0x00, 0x13, 0x00,
++	0x43, 0xC8, 0x50,
++	0x40, 0x00, 0x00,
++	0x12, 0x00, 0x00,
++	0x7B, 0xE7, 0x70,
++	0x0B, 0x43, 0x90,
++	0x07, 0x7F, 0xC0,
++	0x07, 0x7F, 0xC0,
++	0x00, 0x33, 0x00,
++	0x49, 0x75, 0x90,
++	0x40, 0x00, 0x00,
++	0x15, 0x99, 0xA0,
++	0x76, 0x66, 0x60,
++	0x0A, 0x5E, 0x30,
++	0x07, 0x55, 0x70,
++	0x07, 0x55, 0x70,
++	0x00, 0x51, 0x00,
++	0x49, 0x75, 0x90,
++	0x40, 0x00, 0x00,
++	0x19, 0x33, 0x30,
++	0x76, 0x66, 0x60,
++	0x0A, 0x5E, 0x30,
++	0x07, 0x55, 0x70,
++	0x07, 0x55, 0x70,
++	0x00, 0x2F, 0x00,
++	0x49, 0x75, 0x90,
++	0x40, 0x00, 0x00,
++	0x1C, 0xCC, 0xD0,
++	0x76, 0x66, 0x60,
++	0x09, 0x16, 0x80,
++	0x06, 0x6D, 0xB0,
++	0x06, 0x6D, 0xB0,
++	0x7F, 0xFF, 0xF0,
++	0x01, 0x66, 0x60,
++	0x09, 0x99, 0xA0,
++	0x30, 0x00, 0x00,
++	0x19, 0x99, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x03, 0x00,
++	0xC8, 0x00, 0x00,
++	0x39, 0x99, 0xA0,
++	0x2C, 0xCC, 0xD0,
++	0x7F, 0xBE, 0x70,
++	0x7F, 0x5C, 0x30,
++	0x00, 0x00, 0x00,
++	0x00, 0x32, 0x00,
++	0x00, 0x14, 0x00,
++	0x06, 0x66, 0x60,
++	0x00, 0x03, 0x00,
++	0x08, 0x00, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x1D, 0xB0,
++	0x40, 0x26, 0xE0,
++	0x00, 0x00, 0x00,
++	0x40, 0x26, 0xE0,
++	0x00, 0x05, 0x00,
++	0xF4, 0x00, 0x00,
++	0xFF, 0x00, 0x00,
++	0x00, 0x05, 0x00,
++	0x00, 0x30, 0x00,
++	0xFA, 0x2E, 0x90,
++	0xFE, 0x8B, 0xA0,
++	0x00, 0x20, 0xC0,
++	0x00, 0x00, 0x60,
++	0x00, 0x2D, 0x00,
++	0x28, 0x61, 0xA0,
++	0x65, 0x6E, 0xE0,
++	0x00, 0x0B, 0x00,
++	0x00, 0x03, 0x00,
++	0x00, 0x09, 0x00,
++	0x00, 0x04, 0x00,
++	0x00, 0x0A, 0x00,
++	0x00, 0x06, 0x00,
++	0x00, 0x08, 0x00,
++	0x00, 0x06, 0x00,
++	0x00, 0x0A, 0x00,
++	0x00, 0x08, 0x00,
++	0x00, 0x19, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x4C, 0xCC, 0xD0,
++	0x00, 0xC0, 0x00,
++	0x00, 0x60, 0x00,
++	0x00, 0x2D, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x4C, 0xCC, 0xD0,
++	0x00, 0xC0, 0x00,
++	0x00, 0x60, 0x00,
++	0x00, 0x3B, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x4C, 0xCC, 0xD0,
++	0x00, 0xC0, 0x00,
++	0x00, 0x60, 0x00,
++	0x00, 0x50, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x4C, 0xCC, 0xD0,
++	0x00, 0xC0, 0x00,
++	0x00, 0x60, 0x00,
++	0x00, 0x30, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x4C, 0xCC, 0xD0,
++	0x00, 0xC0, 0x00,
++	0x00, 0x60, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x05, 0x00,
++	0x1C, 0xF6, 0x90,
++	0x00, 0x00, 0x00,
++	0xF4, 0x00, 0x00,
++	0x00, 0x04, 0x00,
++	0x0E, 0x38, 0xE0,
++	0x00, 0x03, 0xB0,
++	0x07, 0x08, 0x00,
++	0x19, 0x00, 0x00,
++	0x70, 0x00, 0x00,
++	0x70, 0x00, 0x00,
++	0x07, 0x00, 0x00,
++	0x00, 0x10, 0x00,
++	0x03, 0x20, 0x00,
++	0x03, 0xE8, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x6E, 0x14, 0x80,
++	0x00, 0x20, 0x00,
++	0x03, 0xA9, 0x80,
++	0x04, 0x4C, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x6F, 0x5C, 0x30,
++	0x00, 0x51, 0x00,
++	0x03, 0xF4, 0x80,
++	0x04, 0xB0, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x70, 0xA3, 0xD0,
++	0x00, 0x50, 0x00,
++	0x04, 0x3F, 0x80,
++	0x05, 0x91, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x73, 0x33, 0x30,
++	0x00, 0x30, 0x00,
++	0x04, 0x8A, 0x80,
++	0x05, 0xF5, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x75, 0xC2, 0x90,
++	0x00, 0x00, 0x00,
++	0x00, 0x80, 0x00,
++	0x01, 0x00, 0x00,
++	0x18, 0x00, 0x00,
++	0x18, 0x00, 0x00,
++	0x03, 0x00, 0x00,
++	0x01, 0xEB, 0x80,
++	0x01, 0xEB, 0x80,
++	0x02, 0x8F, 0x60,
++	0x73, 0x33, 0x30,
++	0x02, 0x8F, 0x60,
++	0x01, 0xEB, 0x80,
++	0x01, 0xEB, 0x80,
++	0x10, 0x00, 0x00,
++	0x03, 0x00, 0x00,
++	0x08, 0xF5, 0xC0,
++	0x0C, 0xCC, 0xD0,
++	0x14, 0x7A, 0xE0,
++	0x2B, 0x85, 0x20,
++	0x14, 0x7A, 0xE0,
++	0x0C, 0xCC, 0xD0,
++	0x08, 0xF5, 0xC0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x60,
++	0x07, 0x5C, 0x30,
++	0x32, 0x00, 0x00,
++	0x7E, 0x14, 0x80,
++	0x06, 0xF5, 0xB0,
++	0xD0, 0x00, 0x00,
++	0x00, 0x00, 0x30,
++	0x00, 0x10, 0x00,
++	0x12, 0x66, 0x60,
++	0x00, 0x08, 0x00,
++	0x00, 0x18, 0x00,
++	0x00, 0xE1, 0x00,
++	0x05, 0x55, 0x50,
++	0x00, 0x83, 0xA0,
++	0x00, 0x28, 0x00,
++	0x01, 0x99, 0xA0,
++	0x0C, 0xCC, 0xD0,
++	0x07, 0x33, 0x30,
++	0x03, 0x99, 0xA0,
++	0x04, 0x66, 0x60,
++	0x40, 0x00, 0x00,
++	0x49, 0x99, 0xA0,
++	0xF6, 0x66, 0x60,
++	0x73, 0x33, 0x30,
++	0x19, 0x99, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x04, 0x00,
++	0x00, 0x08, 0x00,
++	0x06, 0x66, 0x60,
++	0x00, 0x51, 0xF0,
++	0x05, 0x33, 0x30,
++	0xFD, 0x99, 0xA0,
++	0x02, 0xCC, 0xD0,
++	0x7D, 0x70, 0xA0,
++	0x02, 0xB0, 0x20,
++	0x00, 0x80, 0x00,
++	0x04, 0x00, 0x00,
++	0x10, 0xA3, 0xD0,
++	0x01, 0xBA, 0x60,
++	0x00, 0x11, 0x00,
++	0x07, 0x87, 0x80,
++	0x29, 0x99, 0xA0,
++	0x00, 0x2D, 0x00,
++	0x02, 0xD8, 0x30,
++	0x0E, 0x66, 0x60,
++	0x00, 0x3A, 0x00,
++	0x02, 0x34, 0xF0,
++	0x10, 0x00, 0x00,
++	0x00, 0x51, 0x00,
++	0x01, 0x94, 0x90,
++	0x08, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x08, 0x00,
++	0x10, 0x00, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x00, 0x04, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x18, 0x00,
++	0x10, 0x00, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x00, 0x04, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x30, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x06, 0x66, 0x60,
++	0x00, 0x04, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0x15, 0xC0,
++	0x00, 0xF5, 0xC0,
++	0xFE, 0xFD, 0xA0,
++	0x01, 0x10, 0x70,
++	0xFE, 0xDF, 0xF0,
++	0x01, 0x31, 0xA0,
++	0xFE, 0xBA, 0x80,
++	0x01, 0x5C, 0x10,
++	0xFE, 0x8A, 0x00,
++	0x01, 0x94, 0x20,
++	0xFE, 0x48, 0x70,
++	0x01, 0xE1, 0xC0,
++	0xFD, 0xEB, 0x10,
++	0x02, 0x54, 0x50,
++	0xFD, 0x5B, 0x40,
++	0x03, 0x0E, 0x50,
++	0xFC, 0x61, 0x20,
++	0x04, 0x71, 0x00,
++	0xFA, 0x41, 0xC0,
++	0x08, 0x1F, 0xE0,
++	0xF2, 0x1E, 0xF0,
++	0x2F, 0x95, 0xF0,
++	0x21, 0x4F, 0x60,
++	0xF3, 0xA9, 0xB0,
++	0x07, 0x92, 0x10,
++	0xFA, 0x8A, 0x10,
++	0x04, 0x45, 0x40,
++	0xFC, 0x7E, 0x60,
++	0x02, 0xF9, 0x60,
++	0xFD, 0x6A, 0xF0,
++	0x02, 0x48, 0x10,
++	0xFD, 0xF4, 0xE0,
++	0x01, 0xD9, 0xC0,
++	0xFE, 0x4F, 0x20,
++	0x01, 0x8E, 0x80,
++	0xFE, 0x8E, 0xE0,
++	0x01, 0x57, 0xE0,
++	0xFE, 0xBE, 0x30,
++	0x01, 0x2E, 0x60,
++	0xFE, 0xE2, 0xD0,
++	0x01, 0x0D, 0xE0,
++	0xFE, 0xFF, 0xF0,
++	0x00, 0xF3, 0xA0,
++	0xFF, 0x17, 0xA0,
++	0x00, 0xDE, 0x10,
++	0xFF, 0x2B, 0x60,
++	0x00, 0xCC, 0x00,
++	0xFF, 0x3B, 0xF0,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x70, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x00, 0x33, 0x30,
++	0xFF, 0xCC, 0xD0,
++	0x00, 0x00, 0x00,
++	0x03, 0x92, 0xD0,
++	0x08, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x16, 0xCC, 0xD0,
++	0x18, 0x00, 0x00,
++	0x16, 0x66, 0x60,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x80, 0x00, 0x00,
++	0xF9, 0x09, 0x90,
++	0x1B, 0xB7, 0x80,
++	0xC4, 0x74, 0xF0,
++	0x7F, 0x83, 0x00,
++	0x58, 0xB9, 0x10,
++	0x08, 0x00, 0x00,
++	0xC8, 0x00, 0x00,
++	0xEB, 0xD8, 0x60,
++	0x42, 0xCD, 0xA0,
++	0xA2, 0x68, 0x10,
++	0x62, 0xB9, 0xF0,
++	0x0C, 0x35, 0x90,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x2F, 0x4D, 0xF0,
++	0x18, 0xAD, 0xE0,
++	0x02, 0x35, 0xE0,
++	0x9D, 0x9A, 0x10,
++	0x04, 0x5B, 0x30,
++	0x9F, 0x16, 0x10,
++	0x06, 0x62, 0x10,
++	0xA1, 0x68, 0xD0,
++	0x08, 0x40, 0xC0,
++	0xA4, 0x62, 0x10,
++	0x09, 0xF2, 0x40,
++	0xA7, 0xCD, 0x20,
++	0x0B, 0x75, 0xD0,
++	0xAB, 0x78, 0x90,
++	0x0C, 0xCD, 0xC0,
++	0xAF, 0x3B, 0x30,
++	0x0D, 0xFE, 0x40,
++	0xB2, 0xF5, 0xA0,
++	0x0F, 0x0C, 0x60,
++	0xB6, 0x91, 0xE0,
++	0x0F, 0xFD, 0x60,
++	0xBA, 0x01, 0xF0,
++	0x10, 0xD6, 0x40,
++	0xBD, 0x3D, 0xE0,
++	0x11, 0x9B, 0x90,
++	0xC0, 0x42, 0x10,
++	0x12, 0x51, 0x60,
++	0xC3, 0x0E, 0x00,
++	0x12, 0xFB, 0x20,
++	0xC5, 0xA3, 0x00,
++	0x13, 0x9B, 0xE0,
++	0xC8, 0x03, 0x80,
++	0x14, 0x36, 0x20,
++	0xCA, 0x32, 0xB0,
++	0x14, 0xCC, 0x20,
++	0xCC, 0x33, 0xE0,
++	0x15, 0x5F, 0xD0,
++	0xCE, 0x0A, 0x80,
++	0x15, 0xF2, 0xE0,
++	0xCF, 0xB9, 0xD0,
++	0x16, 0x86, 0xD0,
++	0xD1, 0x45, 0x10,
++	0x17, 0x1D, 0x00,
++	0xD2, 0xAF, 0x00,
++	0x17, 0xB6, 0xA0,
++	0xD3, 0xFA, 0x70,
++	0x18, 0x55, 0x00,
++	0xD5, 0x29, 0xB0,
++	0x18, 0xF9, 0x30,
++	0xD6, 0x3E, 0xF0,
++	0x19, 0xA4, 0x60,
++	0xD7, 0x3C, 0x20,
++	0x1A, 0x57, 0xA0,
++	0xD8, 0x23, 0x20,
++	0x1B, 0x14, 0x10,
++	0xD8, 0xF5, 0x60,
++	0x1B, 0xDB, 0x00,
++	0xD9, 0xB4, 0x50,
++	0x1C, 0xAD, 0x80,
++	0xDA, 0x61, 0x30,
++	0x1D, 0x8D, 0x10,
++	0xDA, 0xFD, 0x20,
++	0x1E, 0x7A, 0xF0,
++	0xDB, 0x89, 0x00,
++	0x1F, 0x78, 0xD0,
++	0xDC, 0x05, 0xD0,
++	0x20, 0x88, 0x40,
++	0xDC, 0x74, 0x40,
++	0x21, 0xAB, 0x30,
++	0xDC, 0xD5, 0x00,
++	0x22, 0xE3, 0x80,
++	0xDD, 0x28, 0xB0,
++	0x24, 0x33, 0x70,
++	0xDD, 0x6F, 0xE0,
++	0x25, 0x9D, 0x70,
++	0xDD, 0xAB, 0x10,
++	0x27, 0x24, 0x20,
++	0xDD, 0xDA, 0xC0,
++	0x28, 0xCA, 0x80,
++	0xDD, 0xFF, 0x70,
++	0x2A, 0x93, 0xA0,
++	0xDE, 0x19, 0xC0,
++	0x2C, 0x83, 0x00,
++	0xDE, 0x2A, 0x30,
++	0x2E, 0x9C, 0x30,
++	0xDE, 0x31, 0xA0,
++	0x30, 0xE3, 0x20,
++	0xDE, 0x31, 0x00,
++	0x33, 0x5B, 0x90,
++	0xDE, 0x29, 0x80,
++	0x36, 0x09, 0x30,
++	0xDE, 0x1C, 0xF0,
++	0x38, 0xEF, 0x30,
++	0xDE, 0x0D, 0x70,
++	0x3C, 0x0F, 0xA0,
++	0xDD, 0xFE, 0x30,
++	0x3F, 0x6A, 0xF0,
++	0xDD, 0xF3, 0x30,
++	0x42, 0xFE, 0xA0,
++	0xDD, 0xF1, 0xF0,
++	0x46, 0xC4, 0x30,
++	0xDE, 0x01, 0x70,
++	0x4A, 0xAF, 0x00,
++	0xDE, 0x2A, 0xA0,
++	0x4E, 0xAA, 0xB0,
++	0xDE, 0x78, 0x70,
++	0x52, 0x99, 0xA0,
++	0xDE, 0xF7, 0x30,
++	0x56, 0x54, 0x10,
++	0xDF, 0xB4, 0x30,
++	0x59, 0xA9, 0xC0,
++	0xE0, 0xBB, 0xC0,
++	0x5C, 0x66, 0x80,
++	0xE2, 0x16, 0xB0,
++	0x5E, 0x59, 0xA0,
++	0xE3, 0xC8, 0x40,
++	0x5F, 0x5F, 0x60,
++	0xE5, 0xCB, 0x70,
++	0x5F, 0x68, 0xC0,
++	0xE8, 0x13, 0x60,
++	0x5E, 0x7E, 0xC0,
++	0xEA, 0x8C, 0x60,
++	0x5C, 0xBF, 0xF0,
++	0xED, 0x1F, 0xD0,
++	0x5A, 0x58, 0xD0,
++	0xEF, 0xB7, 0x90,
++	0x57, 0x7B, 0x00,
++	0xF2, 0x41, 0x20,
++	0x54, 0x55, 0x90,
++	0xF4, 0xAE, 0xE0,
++	0x51, 0x10, 0x40,
++	0xF6, 0xF8, 0x60,
++	0x4D, 0xCA, 0x00,
++	0xF9, 0x19, 0x80,
++	0x4A, 0x98, 0xD0,
++	0xFB, 0x11, 0x80,
++	0x47, 0x8B, 0x20,
++	0xFC, 0xE1, 0xC0,
++	0x44, 0xA9, 0xA0,
++	0xFE, 0x8D, 0x20,
++	0xBE, 0x07, 0x20,
++	0xFF, 0xE9, 0x00,
++	0xC0, 0x85, 0xD0,
++	0xFE, 0x7C, 0xD0,
++	0xC2, 0xD2, 0xC0,
++	0xFD, 0x2A, 0xA0,
++	0xC4, 0xEF, 0xB0,
++	0xFB, 0xEE, 0xF0,
++	0xC6, 0xDE, 0xE0,
++	0xFA, 0xC6, 0x70,
++	0xC8, 0xA3, 0x10,
++	0xF9, 0xAE, 0x20,
++	0xCA, 0x3F, 0x10,
++	0xF8, 0xA3, 0x30,
++	0xCB, 0xB5, 0x80,
++	0xF7, 0xA3, 0x30,
++	0xCD, 0x09, 0x00,
++	0xF6, 0xAB, 0xD0,
++	0xCE, 0x3C, 0x00,
++	0xF5, 0xBB, 0x10,
++	0xCF, 0x50, 0xC0,
++	0xF4, 0xCE, 0xF0,
++	0xD0, 0x49, 0x40,
++	0xF3, 0xE5, 0xA0,
++	0xD1, 0x27, 0x30,
++	0xF2, 0xFD, 0x90,
++	0xD1, 0xEC, 0x40,
++	0xF2, 0x15, 0x20,
++	0xD2, 0x99, 0xC0,
++	0xF1, 0x2A, 0xB0,
++	0xD3, 0x30, 0xF0,
++	0xF0, 0x3C, 0xC0,
++	0xD3, 0xB2, 0xD0,
++	0xEF, 0x49, 0xE0,
++	0xD4, 0x20, 0x30,
++	0xEE, 0x50, 0x80,
++	0xD4, 0x79, 0xC0,
++	0xED, 0x4F, 0x00,
++	0xD4, 0xC0, 0x20,
++	0xEC, 0x43, 0xC0,
++	0xD4, 0xF3, 0xB0,
++	0xEB, 0x2D, 0x10,
++	0xD5, 0x14, 0xC0,
++	0xEA, 0x09, 0x30,
++	0xD5, 0x23, 0x70,
++	0xE8, 0xD6, 0x10,
++	0xD5, 0x1F, 0xE0,
++	0xE7, 0x91, 0xA0,
++	0xD5, 0x09, 0xE0,
++	0xE6, 0x39, 0x90,
++	0xD4, 0xE1, 0x70,
++	0xE4, 0xCB, 0x80,
++	0xD4, 0xA6, 0x40,
++	0xE3, 0x44, 0xA0,
++	0xD4, 0x58, 0x00,
++	0xE1, 0xA2, 0x00,
++	0xD3, 0xF6, 0x80,
++	0xDF, 0xE0, 0x60,
++	0xD3, 0x81, 0x40,
++	0xDD, 0xFC, 0x50,
++	0xD2, 0xF8, 0x30,
++	0xDB, 0xF2, 0x10,
++	0xD2, 0x5B, 0x20,
++	0xD9, 0xBD, 0xB0,
++	0xD1, 0xAA, 0x60,
++	0xD7, 0x5B, 0x30,
++	0xD0, 0xE6, 0x90,
++	0xD4, 0xC6, 0x90,
++	0xD0, 0x11, 0x10,
++	0xD1, 0xFC, 0x20,
++	0xCF, 0x2C, 0x70,
++	0xCE, 0xF9, 0x30,
++	0xCE, 0x3C, 0x80,
++	0xCB, 0xBC, 0x50,
++	0xCD, 0x47, 0x60,
++	0xC8, 0x46, 0xA0,
++	0xCC, 0x55, 0xC0,
++	0xC4, 0x9C, 0xF0,
++	0xCB, 0x73, 0xE0,
++	0xC0, 0xC9, 0x30,
++	0xCA, 0xB1, 0xC0,
++	0xBC, 0xDC, 0xC0,
++	0xCA, 0x23, 0xA0,
++	0xB8, 0xF1, 0x60,
++	0xC9, 0xE1, 0x00,
++	0xB5, 0x2A, 0x70,
++	0xCA, 0x02, 0x60,
++	0xB1, 0xB3, 0x90,
++	0xCA, 0x9E, 0x30,
++	0xAE, 0xBC, 0xE0,
++	0xCB, 0xC3, 0xC0,
++	0xAC, 0x73, 0xF0,
++	0xCD, 0x77, 0x20,
++	0xAA, 0xFB, 0xC0,
++	0xCF, 0xAE, 0xF0,
++	0xAA, 0x64, 0xF0,
++	0xD2, 0x55, 0x40,
++	0xAA, 0xAA, 0xC0,
++	0xD5, 0x4B, 0xC0,
++	0xAB, 0xB4, 0xC0,
++	0xD8, 0x71, 0x50,
++	0xAD, 0x5D, 0x50,
++	0xDB, 0xA7, 0x00,
++	0xAF, 0x79, 0x70,
++	0xDE, 0xD3, 0xA0,
++	0xB1, 0xDF, 0xB0,
++	0xE1, 0xE4, 0xD0,
++	0xB4, 0x6C, 0x40,
++	0xE4, 0xCE, 0xE0,
++	0xB7, 0x03, 0x10,
++	0xE7, 0x8B, 0x70,
++	0xB9, 0x8F, 0x90,
++	0xEA, 0x18, 0x30,
++	0xBC, 0x03, 0xA0,
++	0xEC, 0x75, 0xA0,
++	0xBE, 0x56, 0x80,
++	0x08, 0x00, 0x00,
++	0x08, 0x33, 0x40,
++	0x0A, 0x6A, 0x40,
++	0x0B, 0x65, 0x90,
++	0x0C, 0x27, 0xE0,
++	0x0C, 0xE2, 0xD0,
++	0x0D, 0xA4, 0xC0,
++	0x0E, 0x72, 0x50,
++	0x0D, 0x4D, 0xB0,
++	0x0C, 0x76, 0x10,
++	0x0B, 0xD2, 0xF0,
++	0x0B, 0x54, 0xE0,
++	0x0A, 0xF1, 0xD0,
++	0x0A, 0xA2, 0xE0,
++	0x0A, 0x63, 0x50,
++	0x0A, 0x2F, 0xA0,
++	0x0A, 0x05, 0x60,
++	0x09, 0xE2, 0xB0,
++	0x09, 0xC6, 0x30,
++	0x09, 0xAE, 0xE0,
++	0x09, 0x9B, 0xE0,
++	0x09, 0x8C, 0x90,
++	0x09, 0x80, 0x80,
++	0x09, 0x77, 0x60,
++	0x09, 0x70, 0xE0,
++	0x09, 0x6C, 0xD0,
++	0x09, 0x6B, 0x10,
++	0x09, 0x6B, 0xA0,
++	0x09, 0x6E, 0x70,
++	0x09, 0x73, 0x80,
++	0x09, 0x7B, 0x10,
++	0x09, 0x85, 0x30,
++	0x09, 0x92, 0x20,
++	0x09, 0xA2, 0x40,
++	0x09, 0xB6, 0x00,
++	0x09, 0xCE, 0x00,
++	0x09, 0xEA, 0xF0,
++	0x0A, 0x0D, 0xF0,
++	0x0A, 0x38, 0x40,
++	0x0A, 0x6B, 0xD0,
++	0x0A, 0xAB, 0x30,
++	0x0A, 0xFA, 0x10,
++	0x0B, 0x5D, 0xE0,
++	0x0B, 0xDE, 0xE0,
++	0x0C, 0x8A, 0xE0,
++	0x0D, 0x79, 0xC0,
++	0x0E, 0xDA, 0xD0,
++	0x11, 0x1B, 0xD0,
++	0x15, 0x96, 0x30,
++	0x25, 0x8B, 0x20,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x7F, 0x54, 0xB0,
++	0x1F, 0x6B, 0x10,
++	0x17, 0x41, 0x50,
++	0x13, 0xB0, 0x40,
++	0x11, 0xA3, 0x10,
++	0x10, 0x4C, 0xF0,
++	0x0F, 0x5E, 0x20,
++	0x0E, 0xB0, 0x60,
++	0x0E, 0x2E, 0xF0,
++	0x0D, 0xCD, 0x90,
++	0x0D, 0x84, 0xA0,
++	0x0D, 0x4F, 0x20,
++	0x0D, 0x29, 0xD0,
++	0x0D, 0x12, 0xA0,
++	0x0D, 0x08, 0x50,
++	0x0D, 0x0A, 0x50,
++	0x0D, 0x18, 0xA0,
++	0x0D, 0x33, 0xF0,
++	0x0D, 0x5D, 0x90,
++	0x0D, 0x97, 0xC0,
++	0x0D, 0xE5, 0xD0,
++	0x0E, 0x4D, 0x10,
++	0x0E, 0xD5, 0xA0,
++	0x0F, 0x8C, 0x70,
++	0x10, 0x87, 0xE0,
++	0x11, 0xF1, 0xE0,
++	0x14, 0x24, 0x10,
++	0x18, 0x0F, 0x60,
++	0x21, 0xB8, 0x80,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x00, 0x64, 0x80,
++	0x01, 0x2D, 0x90,
++	0x01, 0xF6, 0xA0,
++	0x02, 0xBF, 0xB0,
++	0x03, 0x88, 0xB0,
++	0x04, 0x51, 0xA0,
++	0x05, 0x1A, 0x90,
++	0x05, 0xE3, 0x70,
++	0x06, 0xAC, 0x40,
++	0x07, 0x75, 0x00,
++	0x08, 0x3D, 0xB0,
++	0x09, 0x06, 0x50,
++	0x09, 0xCE, 0xD0,
++	0x0A, 0x97, 0x40,
++	0x0B, 0x5F, 0x90,
++	0x0C, 0x27, 0xC0,
++	0x0C, 0xEF, 0xE0,
++	0x0D, 0xB7, 0xD0,
++	0x0E, 0x7F, 0xB0,
++	0x0F, 0x47, 0x60,
++	0x10, 0x0E, 0xF0,
++	0x10, 0xD6, 0x50,
++	0x11, 0x9D, 0x90,
++	0x12, 0x64, 0xA0,
++	0x13, 0x2B, 0x80,
++	0x13, 0xF2, 0x30,
++	0x14, 0xB8, 0xB0,
++	0x15, 0x7F, 0x00,
++	0x16, 0x45, 0x20,
++	0x17, 0x0B, 0x00,
++	0x17, 0xD0, 0xA0,
++	0x18, 0x96, 0x10,
++	0x19, 0x5B, 0x50,
++	0x1A, 0x20, 0x40,
++	0x1A, 0xE4, 0xF0,
++	0x1B, 0xA9, 0x60,
++	0x1C, 0x6D, 0x90,
++	0x1D, 0x31, 0x70,
++	0x1D, 0xF5, 0x10,
++	0x1E, 0xB8, 0x70,
++	0x1F, 0x7B, 0x70,
++	0x20, 0x3E, 0x30,
++	0x21, 0x00, 0xA0,
++	0x21, 0xC2, 0xB0,
++	0x22, 0x84, 0x80,
++	0x23, 0x45, 0xF0,
++	0x24, 0x07, 0x10,
++	0x24, 0xC7, 0xD0,
++	0x25, 0x88, 0x30,
++	0x26, 0x48, 0x40,
++	0x27, 0x07, 0xF0,
++	0x27, 0xC7, 0x30,
++	0x28, 0x86, 0x20,
++	0x29, 0x44, 0xA0,
++	0x2A, 0x02, 0xC0,
++	0x2A, 0xC0, 0x80,
++	0x2B, 0x7D, 0xD0,
++	0x2C, 0x3A, 0xB0,
++	0x2C, 0xF7, 0x30,
++	0x2D, 0xB3, 0x30,
++	0x2E, 0x6E, 0xC0,
++	0x2F, 0x29, 0xF0,
++	0x2F, 0xE4, 0xA0,
++	0x30, 0x9E, 0xD0,
++	0x31, 0x58, 0x90,
++	0x32, 0x11, 0xE0,
++	0x32, 0xCA, 0xB0,
++	0x33, 0x83, 0x00,
++	0x34, 0x3A, 0xD0,
++	0x34, 0xF2, 0x20,
++	0x35, 0xA8, 0xE0,
++	0x36, 0x5F, 0x30,
++	0x37, 0x14, 0xF0,
++	0x37, 0xCA, 0x30,
++	0x38, 0x7E, 0xE0,
++	0x39, 0x33, 0x00,
++	0x39, 0xE6, 0x90,
++	0x3A, 0x99, 0xA0,
++	0x3B, 0x4C, 0x20,
++	0x3B, 0xFE, 0x00,
++	0x3C, 0xAF, 0x50,
++	0x3D, 0x60, 0x10,
++	0x3E, 0x10, 0x30,
++	0x3E, 0xBF, 0xC0,
++	0x3F, 0x6E, 0xB0,
++	0x40, 0x1D, 0x00,
++	0x40, 0xCA, 0xC0,
++	0x41, 0x77, 0xD0,
++	0x42, 0x24, 0x40,
++	0x42, 0xD0, 0x10,
++	0x43, 0x7B, 0x40,
++	0x44, 0x25, 0xD0,
++	0x44, 0xCF, 0xA0,
++	0x45, 0x78, 0xE0,
++	0x46, 0x21, 0x60,
++	0x46, 0xC9, 0x40,
++	0x47, 0x70, 0x70,
++	0x48, 0x16, 0xF0,
++	0x48, 0xBC, 0xB0,
++	0x49, 0x61, 0xD0,
++	0x4A, 0x06, 0x30,
++	0x4A, 0xA9, 0xE0,
++	0x4B, 0x4C, 0xD0,
++	0x4B, 0xEF, 0x10,
++	0x4C, 0x90, 0x80,
++	0x4D, 0x31, 0x50,
++	0x4D, 0xD1, 0x50,
++	0x4E, 0x70, 0x90,
++	0x4F, 0x0F, 0x10,
++	0x4F, 0xAC, 0xD0,
++	0x50, 0x49, 0xD0,
++	0x50, 0xE6, 0x00,
++	0x51, 0x81, 0x70,
++	0x52, 0x1C, 0x10,
++	0x52, 0xB5, 0xE0,
++	0x53, 0x4E, 0xF0,
++	0x53, 0xE7, 0x30,
++	0x54, 0x7E, 0xA0,
++	0x55, 0x15, 0x40,
++	0x55, 0xAB, 0x10,
++	0x56, 0x40, 0x00,
++	0x56, 0xD4, 0x30,
++	0x57, 0x67, 0x80,
++	0x57, 0xF9, 0xF0,
++	0x58, 0x8B, 0x90,
++	0x59, 0x1C, 0x50,
++	0x59, 0xAC, 0x40,
++	0x5A, 0x3B, 0x40,
++	0x5A, 0xC9, 0x70,
++	0x5B, 0x56, 0xC0,
++	0x5B, 0xE3, 0x30,
++	0x5C, 0x6E, 0xB0,
++	0x5C, 0xF9, 0x50,
++	0x5D, 0x83, 0x10,
++	0x5E, 0x0B, 0xF0,
++	0x5E, 0x93, 0xE0,
++	0x5F, 0x1A, 0xE0,
++	0x5F, 0xA1, 0x00,
++	0x60, 0x26, 0x30,
++	0x60, 0xAA, 0x70,
++	0x61, 0x2D, 0xC0,
++	0x61, 0xB0, 0x30,
++	0x62, 0x31, 0xA0,
++	0x62, 0xB2, 0x20,
++	0x63, 0x31, 0xB0,
++	0x63, 0xB0, 0x40,
++	0x64, 0x2D, 0xE0,
++	0x64, 0xAA, 0x90,
++	0x65, 0x26, 0x40,
++	0x65, 0xA1, 0x00,
++	0x66, 0x1A, 0xC0,
++	0x66, 0x93, 0x80,
++	0x67, 0x0B, 0x40,
++	0x67, 0x82, 0x10,
++	0x67, 0xF7, 0xD0,
++	0x68, 0x6C, 0xA0,
++	0x68, 0xE0, 0x60,
++	0x69, 0x53, 0x20,
++	0x69, 0xC4, 0xE0,
++	0x6A, 0x35, 0xA0,
++	0x6A, 0xA5, 0x50,
++	0x6B, 0x14, 0x00,
++	0x6B, 0x81, 0xA0,
++	0x6B, 0xEE, 0x40,
++	0x6C, 0x59, 0xD0,
++	0x6C, 0xC4, 0x50,
++	0x6D, 0x2D, 0xD0,
++	0x6D, 0x96, 0x40,
++	0x6D, 0xFD, 0xA0,
++	0x6E, 0x63, 0xF0,
++	0x6E, 0xC9, 0x20,
++	0x6F, 0x2D, 0x50,
++	0x6F, 0x90, 0x70,
++	0x6F, 0xF2, 0x70,
++	0x70, 0x53, 0x60,
++	0x70, 0xB3, 0x40,
++	0x71, 0x12, 0x10,
++	0x71, 0x6F, 0xC0,
++	0x71, 0xCC, 0x50,
++	0x72, 0x27, 0xD0,
++	0x72, 0x82, 0x40,
++	0x72, 0xDB, 0x90,
++	0x73, 0x33, 0xC0,
++	0x73, 0x8A, 0xD0,
++	0x73, 0xE0, 0xC0,
++	0x74, 0x35, 0xA0,
++	0x74, 0x89, 0x50,
++	0x74, 0xDB, 0xF0,
++	0x75, 0x2D, 0x70,
++	0x75, 0x7D, 0xC0,
++	0x75, 0xCD, 0x00,
++	0x76, 0x1B, 0x10,
++	0x76, 0x68, 0x00,
++	0x76, 0xB3, 0xD0,
++	0x76, 0xFE, 0x80,
++	0x77, 0x48, 0x00,
++	0x77, 0x90, 0x60,
++	0x77, 0xD7, 0x90,
++	0x78, 0x1D, 0xA0,
++	0x78, 0x62, 0x80,
++	0x78, 0xA6, 0x40,
++	0x78, 0xE8, 0xD0,
++	0x79, 0x2A, 0x30,
++	0x79, 0x6A, 0x70,
++	0x79, 0xA9, 0x80,
++	0x79, 0xE7, 0x70,
++	0x7A, 0x24, 0x20,
++	0x7A, 0x5F, 0xB0,
++	0x7A, 0x9A, 0x10,
++	0x7A, 0xD3, 0x40,
++	0x7B, 0x0B, 0x40,
++	0x7B, 0x42, 0x10,
++	0x7B, 0x77, 0xB0,
++	0x7B, 0xAC, 0x20,
++	0x7B, 0xDF, 0x60,
++	0x7C, 0x11, 0x70,
++	0x7C, 0x42, 0x40,
++	0x7C, 0x71, 0xF0,
++	0x7C, 0xA0, 0x60,
++	0x7C, 0xCD, 0xA0,
++	0x7C, 0xF9, 0xB0,
++	0x7D, 0x24, 0x90,
++	0x7D, 0x4E, 0x30,
++	0x7D, 0x76, 0xA0,
++	0x7D, 0x9D, 0xD0,
++	0x7D, 0xC3, 0xE0,
++	0x7D, 0xE8, 0xA0,
++	0x7E, 0x0C, 0x40,
++	0x7E, 0x2E, 0xA0,
++	0x7E, 0x4F, 0xC0,
++	0x7E, 0x6F, 0xB0,
++	0x7E, 0x8E, 0x70,
++	0x7E, 0xAB, 0xF0,
++	0x7E, 0xC8, 0x30,
++	0x7E, 0xE3, 0x40,
++	0x7E, 0xFD, 0x20,
++	0x7F, 0x15, 0xC0,
++	0x7F, 0x2D, 0x20,
++	0x7F, 0x43, 0x40,
++	0x7F, 0x58, 0x30,
++	0x7F, 0x6B, 0xF0,
++	0x7F, 0x7E, 0x60,
++	0x7F, 0x8F, 0xA0,
++	0x7F, 0x9F, 0xB0,
++	0x7F, 0xAE, 0x70,
++	0x7F, 0xBC, 0x00,
++	0x7F, 0xC8, 0x60,
++	0x7F, 0xD3, 0x70,
++	0x7F, 0xDD, 0x50,
++	0x7F, 0xE5, 0xF0,
++	0x7F, 0xED, 0x50,
++	0x7F, 0xF3, 0x80,
++	0x7F, 0xF8, 0x70,
++	0x7F, 0xFC, 0x20,
++	0x7F, 0xFE, 0xA0,
++	0x7F, 0xFF, 0xE0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0x87, 0x50,
++	0xFE, 0x8C, 0x50,
++	0xFD, 0xE9, 0x70,
++	0x00, 0x00, 0x00,
++	0x06, 0xD8, 0xD0,
++	0x11, 0x8D, 0x30,
++	0x1B, 0xAE, 0x90,
++	0x1F, 0xDC, 0xD0,
++	0x1B, 0xAE, 0x90,
++	0x11, 0x8D, 0x30,
++	0x06, 0xD8, 0xD0,
++	0x00, 0x00, 0x00,
++	0xFD, 0xE9, 0x70,
++	0xFE, 0x8C, 0x50,
++	0xFF, 0x87, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x08, 0x00,
++	0x07, 0x87, 0x80,
++	0x78, 0x78, 0x80,
++	0x00, 0x09, 0x00,
++	0x2D, 0x38, 0x80,
++	0x52, 0xC7, 0x80,
++	0x00, 0x0B, 0x00,
++	0x24, 0x73, 0x10,
++	0x5B, 0x8C, 0xF0,
++	0x00, 0x0F, 0x00,
++	0x7F, 0x42, 0x50,
++	0x00, 0xBD, 0xB0,
++	0x00, 0x13, 0x00,
++	0x5A, 0x5A, 0x60,
++	0x25, 0xA5, 0xA0,
++	0x00, 0x18, 0x00,
++	0x5B, 0x23, 0x60,
++	0x24, 0xDC, 0xA0,
++	0x00, 0x1D, 0x00,
++	0x2D, 0x2D, 0x30,
++	0x52, 0xD2, 0xD0,
++	0x00, 0x23, 0x00,
++	0x7F, 0x36, 0xF0,
++	0x00, 0xC9, 0x10,
++	0x00, 0x24, 0x00,
++	0x22, 0xB3, 0xD0,
++	0x5D, 0x4C, 0x30,
++	0x00, 0x2A, 0x00,
++	0x05, 0x90, 0x00,
++	0x7A, 0x70, 0x00,
++	0x00, 0x2E, 0x00,
++	0x32, 0x22, 0x70,
++	0x4D, 0xDD, 0x90,
++	0x00, 0x31, 0x00,
++	0x72, 0xA8, 0xD0,
++	0x0D, 0x57, 0x30,
++	0x00, 0x32, 0x00,
++	0x5C, 0xE8, 0xB0,
++	0x23, 0x17, 0x50,
++	0x2C, 0xCC, 0xD0,
++	0x00, 0x04, 0x00,
++	0x20, 0x00, 0x00,
++	0x00, 0x03, 0x00,
++	0x2A, 0xAA, 0xB0,
++	0x40, 0x00, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x18, 0x00, 0x00,
++	0x00, 0x41, 0x90,
++	0xFF, 0x33, 0x30,
++	0x03, 0xEE, 0xA0,
++	0x08, 0x00, 0x00,
++	0x18, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x03, 0x33, 0x30,
++	0x20, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x20, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x06, 0x00,
++	0xFE, 0x80, 0x00,
++	0x0A, 0x80, 0x00,
++	0xDD, 0x00, 0x00,
++	0x68, 0xFF, 0x80,
++	0x34, 0x7F, 0x00,
++	0xFC, 0x80, 0x80,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x3F, 0xF0,
++	0x08, 0x5F, 0xB0,
++	0xEA, 0x91, 0x40,
++	0xF7, 0xA0, 0x50,
++	0x55, 0x2E, 0xD0,
++	0x00, 0x00, 0x00,
++	0x00, 0x51, 0x20,
++	0xF8, 0x3B, 0xA0,
++	0x19, 0x90, 0xF0,
++	0x5C, 0x00, 0x00,
++	0x19, 0x90, 0xF0,
++	0xF8, 0x3B, 0xA0,
++	0x00, 0x51, 0x20,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0xFE, 0x40,
++	0x00, 0x00, 0x00,
++	0x00, 0x0A, 0x30,
++	0x00, 0x00, 0x00,
++	0xFF, 0xE5, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x34, 0x70,
++	0x00, 0x00, 0x00,
++	0xFF, 0xA6, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x8A, 0x40,
++	0x00, 0x00, 0x00,
++	0xFF, 0x35, 0xA0,
++	0x00, 0x00, 0x00,
++	0x01, 0x1C, 0x90,
++	0x00, 0x00, 0x00,
++	0xFE, 0x7A, 0x70,
++	0x00, 0x00, 0x00,
++	0x02, 0x0D, 0x20,
++	0x00, 0x00, 0x00,
++	0xFD, 0x3F, 0x80,
++	0x00, 0x00, 0x00,
++	0x03, 0xB9, 0x20,
++	0x00, 0x00, 0x00,
++	0xFA, 0xD2, 0x20,
++	0x00, 0x00, 0x00,
++	0x07, 0xAE, 0xA0,
++	0x00, 0x00, 0x00,
++	0xF2, 0xB3, 0xD0,
++	0x00, 0x00, 0x00,
++	0x28, 0xA6, 0x10,
++	0x40, 0x00, 0x00,
++	0x28, 0xA6, 0x10,
++	0x00, 0x00, 0x00,
++	0xF2, 0xB3, 0xD0,
++	0x00, 0x00, 0x00,
++	0x07, 0xAE, 0xA0,
++	0x00, 0x00, 0x00,
++	0xFA, 0xD2, 0x20,
++	0x00, 0x00, 0x00,
++	0x03, 0xB9, 0x20,
++	0x00, 0x00, 0x00,
++	0xFD, 0x3F, 0x80,
++	0x00, 0x00, 0x00,
++	0x02, 0x0D, 0x20,
++	0x00, 0x00, 0x00,
++	0xFE, 0x7A, 0x70,
++	0x00, 0x00, 0x00,
++	0x01, 0x1C, 0x90,
++	0x00, 0x00, 0x00,
++	0xFF, 0x35, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x8A, 0x40,
++	0x00, 0x00, 0x00,
++	0xFF, 0xA6, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x34, 0x70,
++	0x00, 0x00, 0x00,
++	0xFF, 0xE5, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x0A, 0x30,
++	0x00, 0x00, 0x00,
++	0xFF, 0xFE, 0x40,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x12, 0x00,
++	0x00, 0x11, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x07, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x5B, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0x65, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0x80, 0x00,
++	0x02, 0x00, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0xB0, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0xB1, 0x00,
++	0x02, 0x58, 0x00,
++	0x02, 0x58, 0x00,
++	0x03, 0xFF, 0x00,
++	0x09, 0x7F, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x51, 0x00,
++	0x03, 0xFF, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0xF0, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x7E, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x01, 0x4A, 0xA0,
++	0x06, 0x57, 0xF0,
++	0x06, 0x57, 0xF0,
++	0x00, 0x04, 0x00,
++	0x7F, 0xF0, 0x00,
++	0x00, 0x10, 0x00,
++	0x1D, 0x9A, 0x50,
++	0xF9, 0xA8, 0x10,
++	0x00, 0x56, 0x00,
++	0x01, 0x00, 0x00,
++	0x20, 0x00, 0x00,
++	0xF0, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x7E, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x01, 0x4A, 0xA0,
++	0x06, 0x57, 0xF0,
++	0x06, 0x57, 0xF0,
++	0x00, 0x04, 0x00,
++	0x7F, 0xF0, 0x00,
++	0x00, 0x10, 0x00,
++	0x32, 0xBF, 0x60,
++	0xF9, 0xA8, 0x10,
++	0x40, 0x3B, 0x00,
++	0x3F, 0xFC, 0x30,
++	0x10, 0x00, 0x00,
++	0x40, 0x26, 0xE0,
++	0x01, 0x00, 0x00,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x7F, 0xC0, 0x00,
++	0x00, 0x40, 0x00,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x40, 0x00, 0x60,
++	0x20, 0x00, 0x00,
++	0x7F, 0xC0, 0x00,
++	0x00, 0x40, 0x00,
++	0x00, 0x0D, 0x30,
++	0x78, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x3F, 0xFF, 0xF0,
++	0x40, 0x00, 0x10,
++	0x03, 0x2B, 0x70,
++	0x00, 0xA5, 0xB0,
++	0x0E, 0x7D, 0xA0,
++	0x3F, 0x15, 0xE0,
++	0x40, 0x01, 0xE0,
++	0x00, 0x20, 0x50,
++	0x0F, 0xE2, 0xF0,
++	0x3F, 0xFE, 0x20,
++	0x40, 0x5E, 0x90,
++	0x03, 0x2B, 0x70,
++	0x00, 0xA5, 0xB0,
++	0x50, 0xC3, 0x30,
++	0x01, 0x00, 0x00,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x7F, 0xC0, 0x00,
++	0x00, 0x40, 0x00,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x40, 0x00, 0x60,
++	0x20, 0x00, 0x00,
++	0x7F, 0xC0, 0x00,
++	0x00, 0x40, 0x00,
++	0x00, 0x0D, 0x30,
++	0x78, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x3F, 0xFF, 0xF0,
++	0x40, 0x00, 0x10,
++	0x03, 0x2B, 0x70,
++	0x00, 0xA5, 0xB0,
++	0x0E, 0x7D, 0xA0,
++	0x3F, 0x15, 0xE0,
++	0x40, 0x01, 0xE0,
++	0x01, 0x00, 0xA0,
++	0x0F, 0xE2, 0xF0,
++	0x3F, 0xFE, 0x20,
++	0x40, 0x5E, 0x90,
++	0x03, 0x2B, 0x70,
++	0x00, 0xA5, 0xB0,
++	0x50, 0xC3, 0x30,
++	0x37, 0x00, 0x80,
++	0x91, 0xFF, 0x10,
++	0xD1, 0x50, 0xA0,
++	0x6D, 0x52, 0x80,
++	0x37, 0x00, 0x80,
++	0x10, 0xAC, 0x30,
++	0x21, 0x58, 0x60,
++	0xED, 0x25, 0x50,
++	0x10, 0x2A, 0x00,
++	0x10, 0xAC, 0x30,
++	0x3D, 0x8F, 0x00,
++	0x84, 0xE2, 0x00,
++	0xC4, 0xD5, 0xE0,
++	0x7B, 0x11, 0xD0,
++	0x3D, 0x8F, 0x00,
++	0x23, 0xF1, 0xA0,
++	0x47, 0xE3, 0x50,
++	0xD8, 0x04, 0x50,
++	0xD8, 0x35, 0x20,
++	0x23, 0xF1, 0xA0,
++	0x33, 0x2B, 0xA0,
++	0x99, 0xA8, 0xC0,
++	0xD8, 0x39, 0xC0,
++	0x64, 0xE8, 0x30,
++	0x33, 0x2B, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x11, 0x48, 0x30,
++	0x22, 0x90, 0x70,
++	0xEA, 0x1D, 0xE0,
++	0x10, 0xC1, 0x50,
++	0x11, 0x48, 0x30,
++	0x39, 0xC0, 0x70,
++	0x8C, 0x7F, 0x20,
++	0xCB, 0x60, 0x40,
++	0x72, 0x62, 0x10,
++	0x39, 0xC0, 0x70,
++	0x39, 0x12, 0x00,
++	0x8D, 0xDC, 0x00,
++	0xCD, 0x76, 0x60,
++	0x71, 0xBE, 0x60,
++	0x39, 0x12, 0x00,
++	0x15, 0x55, 0x50,
++	0x2A, 0xAA, 0xB0,
++	0xEA, 0xAA, 0xB0,
++	0x00, 0x00, 0x00,
++	0x15, 0x55, 0x50,
++	0x1E, 0x12, 0x40,
++	0x3C, 0x24, 0x80,
++	0xE9, 0x01, 0x90,
++	0xDE, 0xB5, 0x80,
++	0x1E, 0x12, 0x40,
++	0x0E, 0x26, 0x00,
++	0x1F, 0xA7, 0xF0,
++	0xEB, 0x0E, 0x10,
++	0x09, 0xB7, 0x50,
++	0x1D, 0x6C, 0xC0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x40, 0x00,
++	0x05, 0x80, 0x00,
++	0x20, 0xC0, 0x00,
++	0x02, 0x00, 0x00,
++	0x03, 0x90, 0x00,
++	0x00, 0x40, 0x00,
++	0x28, 0xF5, 0x00,
++	0x0A, 0x3D, 0x00,
++	0x08, 0x55, 0x60,
++	0x33, 0x33, 0x30,
++	0x14, 0x00, 0x00,
++	0xB8, 0x00, 0x00,
++	0x10, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x19, 0x99, 0x90,
++	0x00, 0x00, 0x00,
++	0x74, 0x7A, 0xE0,
++	0x40, 0x00, 0x00,
++	0x01, 0x47, 0xA0,
++	0x05, 0x1E, 0xB0,
++	0x02, 0x8F, 0x50,
++	0x05, 0x1E, 0xB0,
++	0x02, 0x8F, 0x50,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x00, 0x10, 0x00,
++	0x00, 0x20, 0x00,
++	0x00, 0x50, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0xB0, 0x00,
++	0x00, 0xFF, 0x00,
++	0x23, 0x00, 0x00,
++	0x05, 0x80, 0x00,
++	0x26, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x03, 0x98, 0x00,
++	0x00, 0x40, 0x00,
++	0x28, 0xF5, 0x00,
++	0x0A, 0x3D, 0x00,
++	0x08, 0x55, 0x60,
++	0x33, 0x33, 0x30,
++	0x14, 0x00, 0x00,
++	0xB8, 0x00, 0x00,
++	0x10, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x19, 0x99, 0x90,
++	0x00, 0x00, 0x00,
++	0x74, 0x7A, 0xE0,
++	0x40, 0x00, 0x00,
++	0x01, 0x47, 0xA0,
++	0x05, 0x1E, 0xB0,
++	0x02, 0x8F, 0x50,
++	0x05, 0x1E, 0xB0,
++	0x02, 0x8F, 0x50,
++	0x2D, 0x6A, 0x80,
++	0x2D, 0x6A, 0x80,
++	0x2D, 0x6A, 0x80,
++	0x2D, 0x6A, 0x80,
++	0x2D, 0x6A, 0x80,
++	0x2D, 0x6A, 0x80,
++	0x00, 0x10, 0x00,
++	0x00, 0x20, 0x00,
++	0x00, 0x50, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0xB0, 0x00,
++	0x00, 0xFF, 0x00,
++	0x00, 0x03, 0x00,
++	0x00, 0x60, 0x00,
++	0x02, 0x0C, 0x50,
++	0x20, 0x00, 0x00,
++	0x14, 0x00, 0x00,
++	0x00, 0x06, 0x00,
++	0x01, 0x00, 0x00,
++	0x19, 0x99, 0xA0,
++	0x01, 0x47, 0xB0,
++	0x0C, 0xCC, 0xD0,
++	0x20, 0x00, 0x00,
++	0x04, 0x80, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x28, 0xF0,
++	0x01, 0x47, 0xB0,
++	0x05, 0x1E, 0xC0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x2B, 0x85, 0x20,
++	0x14, 0x7A, 0xE0,
++	0x0C, 0xCC, 0xD0,
++	0x08, 0xF5, 0xC0,
++	0x10, 0x00, 0x00,
++	0x70, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0xA3, 0x00,
++	0x00, 0x00, 0x00,
++	0xC0, 0x00, 0x00,
++	0x40, 0x26, 0xE0,
++	0x2C, 0xCC, 0xD0,
++	0x7F, 0xFF, 0xF0,
++	0x7F, 0xFF, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x02, 0x02, 0x70,
++	0x02, 0xD6, 0xB0,
++	0x04, 0x02, 0x70,
++	0x05, 0xA9, 0xE0,
++	0x08, 0x00, 0x00,
++	0x0B, 0x4C, 0xE0,
++	0x0F, 0xF6, 0x50,
++	0x16, 0x8C, 0x10,
++	0x1F, 0xD9, 0x40,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x23, 0x64, 0x00,
++	0x00, 0x00, 0x00,
++	0x23, 0x64, 0x00,
++	0x40, 0x00, 0x00,
++	0x7F, 0x8A, 0xD0,
++	0xAA, 0xD1, 0xB0,
++	0xD5, 0xA3, 0x70,
++	0x65, 0xD8, 0x00,
++	0xF8, 0x00, 0x00,
++	0x60, 0x00, 0x00,
++	0x6E, 0xD9, 0xF0,
++	0x49, 0xE6, 0xA0,
++	0xE7, 0x5D, 0xD0,
++	0x10, 0x6C, 0x20,
++	0xF2, 0x50, 0x90,
++	0x0C, 0xC5, 0xE0,
++	0xF3, 0x3A, 0x20,
++	0x08, 0x00, 0x00,
++	0x5A, 0x82, 0x80,
++	0x00, 0x00, 0x00,
++	0x05, 0x05, 0x00,
++	0x07, 0x1B, 0x00,
++	0x08, 0xB5, 0x00,
++	0x0A, 0x11, 0x00,
++	0x0B, 0x44, 0x00,
++	0x0C, 0x5A, 0x00,
++	0x0D, 0x5B, 0x00,
++	0x0E, 0x4A, 0x00,
++	0x0F, 0x2C, 0x00,
++	0x10, 0x02, 0x00,
++	0x10, 0xCE, 0x00,
++	0x11, 0x91, 0x00,
++	0x12, 0x4E, 0x00,
++	0x13, 0x03, 0x00,
++	0x13, 0xB3, 0x00,
++	0x14, 0x5D, 0x00,
++	0x15, 0x02, 0x00,
++	0x15, 0xA3, 0x00,
++	0x16, 0x41, 0x00,
++	0x16, 0xDA, 0x00,
++	0x17, 0x70, 0x00,
++	0x18, 0x03, 0x00,
++	0x18, 0x93, 0x00,
++	0x19, 0x20, 0x00,
++	0x19, 0xAB, 0x00,
++	0x1A, 0x33, 0x00,
++	0x1A, 0xB9, 0x00,
++	0x1B, 0x3D, 0x00,
++	0x1B, 0xBF, 0x00,
++	0x1C, 0x3F, 0x00,
++	0x1C, 0xBD, 0x00,
++	0x1D, 0x39, 0x00,
++	0x1D, 0xB4, 0x00,
++	0x1E, 0x2E, 0x00,
++	0x1E, 0xA5, 0x00,
++	0x1F, 0x1C, 0x00,
++	0x1F, 0x91, 0x00,
++	0x20, 0x05, 0x00,
++	0x20, 0x77, 0x00,
++	0x20, 0xE8, 0x00,
++	0x21, 0x59, 0x00,
++	0x21, 0xC8, 0x00,
++	0x22, 0x36, 0x00,
++	0x22, 0xA3, 0x00,
++	0x23, 0x0F, 0x00,
++	0x23, 0x7A, 0x00,
++	0x23, 0xE4, 0x00,
++	0x24, 0x4D, 0x00,
++	0x24, 0xB6, 0x00,
++	0x25, 0x1D, 0x00,
++	0x25, 0x84, 0x00,
++	0x25, 0xEA, 0x00,
++	0x26, 0x50, 0x00,
++	0x26, 0xB4, 0x00,
++	0x27, 0x18, 0x00,
++	0x27, 0x7B, 0x00,
++	0x27, 0xDE, 0x00,
++	0x28, 0x3F, 0x00,
++	0x28, 0xA1, 0x00,
++	0x29, 0x01, 0x00,
++	0x29, 0x61, 0x00,
++	0x29, 0xC1, 0x00,
++	0x2A, 0x1F, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00
++};
++
++u8 pram_data_bak[] = {
++	0x0C, 0xB4, 0xED, 0x1E, 0x42,
++	0x04, 0xA9, 0x1C, 0x6D, 0x49,
++	0x04, 0x44, 0x82, 0x1A, 0x44,
++	0x0F, 0x58, 0x7E, 0x4D, 0x88,
++	0x0D, 0x5A, 0x7E, 0x89, 0x1D,
++	0x03, 0x35, 0x1C, 0x03, 0x8C,
++	0x0F, 0x4A, 0x05, 0x6C, 0x68,
++	0x0A, 0x70, 0xFF, 0x60, 0xE7,
++	0x01, 0x83, 0x9B, 0x95, 0x72,
++	0x09, 0x79, 0x72, 0x83, 0xAE,
++	0x07, 0xAE, 0xA6, 0x4F, 0x67,
++	0x0E, 0xD9, 0xA5, 0xD2, 0x80,
++	0x00, 0x7B, 0xE2, 0xEA, 0x9E,
++	0x05, 0xDB, 0xB3, 0xF9, 0xAC,
++	0x0E, 0x38, 0x0C, 0xB8, 0x91,
++	0x03, 0x81, 0xB6, 0x89, 0xCA,
++	0x0C, 0xDF, 0x09, 0xD1, 0x5F,
++	0x0F, 0x78, 0x28, 0xDB, 0xF2,
++	0x06, 0x67, 0x95, 0x59, 0x5B,
++	0x0B, 0xF4, 0x98, 0x6B, 0x25,
++	0x0A, 0x72, 0xD4, 0x2D, 0xBB,
++	0x09, 0xAE, 0x33, 0x01, 0x57,
++	0x09, 0x6B, 0xBD, 0xBA, 0x4F,
++	0x01, 0x54, 0x86, 0x70, 0xBB,
++	0x0F, 0x53, 0xBC, 0x3F, 0xE7,
++	0x0B, 0xC4, 0x7B, 0x42, 0x4E,
++	0x08, 0x79, 0x17, 0x62, 0xAD,
++	0x0A, 0x33, 0xE5, 0x31, 0x10,
++	0x04, 0x47, 0xD3, 0x15, 0x7C,
++	0x01, 0x37, 0xC4, 0x85, 0x60,
++	0x00, 0xA2, 0x23, 0xE4, 0xD4,
++	0x07, 0x81, 0x74, 0x8D, 0x2F,
++	0x03, 0x31, 0xCD, 0x59, 0xE3,
++	0x02, 0x83, 0x5B, 0x76, 0x35,
++	0x00, 0xD5, 0x02, 0x95, 0xE5,
++	0x00, 0x0E, 0x1C, 0xDE, 0xA7,
++	0x03, 0xCC, 0xE5, 0x7B, 0x43,
++	0x07, 0x78, 0x7B, 0xC1, 0xF0,
++	0x07, 0x99, 0x68, 0x27, 0x75,
++	0x09, 0x26, 0xC9, 0x48, 0xCB,
++	0x0A, 0xE2, 0x66, 0x20, 0x0F,
++	0x00, 0x27, 0x5E, 0x03, 0x67,
++	0x04, 0x85, 0x12, 0xD3, 0xDD,
++	0x09, 0x6F, 0xCD, 0xA9, 0x87,
++	0x0C, 0x65, 0x18, 0x5F, 0xD1,
++	0x0F, 0xAC, 0xB4, 0x47, 0xD4,
++	0x0C, 0x76, 0x67, 0x16, 0x91,
++	0x0A, 0x05, 0x2B, 0x4B, 0xB2,
++	0x0C, 0xE9, 0x3F, 0x75, 0x12,
++	0x05, 0xC6, 0x96, 0xCD, 0x0A,
++	0x0A, 0x3C, 0x32, 0xDF, 0x24,
++	0x02, 0x09, 0x4E, 0xC1, 0xE5,
++	0x07, 0x49, 0x92, 0xC6, 0xE0,
++	0x04, 0xC4, 0x40, 0x31, 0x1A,
++	0x02, 0x55, 0x86, 0x34, 0xDF,
++	0x06, 0x15, 0xA2, 0xAC, 0x9B,
++	0x0F, 0x93, 0x51, 0x30, 0x18,
++	0x0A, 0x34, 0xBD, 0xA2, 0x8D,
++	0x05, 0x67, 0xD6, 0xFA, 0x10,
++	0x06, 0x58, 0x09, 0x7D, 0x54,
++	0x06, 0x51, 0x2E, 0x70, 0x0F,
++	0x0E, 0x7A, 0xAA, 0x64, 0x04,
++	0x09, 0xED, 0xDD, 0xDD, 0xD9,
++	0x03, 0x07, 0xB2, 0x2E, 0x5D,
++	0x09, 0x1D, 0x88, 0xCF, 0x9B,
++	0x09, 0x3C, 0x72, 0x57, 0xB8,
++	0x04, 0x80, 0xCF, 0x70, 0x95,
++	0x0B, 0x0D, 0xEB, 0xB9, 0x14,
++	0x0B, 0x4F, 0xD9, 0x29, 0xF5,
++	0x0A, 0xA6, 0xEE, 0xB1, 0x9D,
++	0x09, 0x7F, 0x47, 0x8E, 0xB8,
++	0x04, 0x1F, 0x74, 0x1A, 0xDB,
++	0x0C, 0x5A, 0xF9, 0x28, 0x1A,
++	0x07, 0x2E, 0x76, 0x7F, 0xA4,
++	0x09, 0xEA, 0x48, 0x67, 0x3A,
++	0x03, 0x35, 0xBB, 0xC3, 0x3E,
++	0x03, 0x7F, 0x5C, 0xC8, 0x17,
++	0x0B, 0x47, 0x9F, 0xB2, 0x20,
++	0x07, 0x1B, 0x57, 0x9F, 0x5B,
++	0x00, 0x84, 0x61, 0xB5, 0x1C,
++	0x0B, 0xD3, 0x72, 0xA4, 0x1C,
++	0x0F, 0xB2, 0x4B, 0xF2, 0x07,
++	0x0C, 0xC0, 0x63, 0xA4, 0x58,
++	0x0E, 0x8B, 0x1D, 0xE9, 0x14,
++	0x0E, 0xE8, 0x37, 0xBB, 0x2A,
++	0x0E, 0xF5, 0x50, 0x29, 0x5E,
++	0x0D, 0xC0, 0xE7, 0x47, 0xF6,
++	0x08, 0x90, 0xCA, 0x1A, 0x32,
++	0x08, 0x77, 0x85, 0xF2, 0x57,
++	0x00, 0x81, 0x10, 0x4A, 0xB6,
++	0x0F, 0x3E, 0x6E, 0x54, 0x84,
++	0x0C, 0x4E, 0x3D, 0xA2, 0x5D,
++	0x08, 0xC2, 0x72, 0xBA, 0x35,
++	0x0D, 0xE4, 0x50, 0xAD, 0x3F,
++	0x08, 0x96, 0xFC, 0x9A, 0x9F,
++	0x0C, 0xC6, 0x51, 0xA5, 0xFA,
++	0x0A, 0x25, 0x34, 0xC0, 0x4E,
++	0x08, 0x6B, 0xEE, 0xC8, 0x6B,
++	0x06, 0xA1, 0xD0, 0x3C, 0xA6,
++	0x08, 0x06, 0x73, 0xDB, 0x51,
++	0x08, 0x1A, 0xCB, 0x6C, 0x10,
++	0x05, 0x0F, 0xB8, 0xBD, 0xB1,
++	0x01, 0x20, 0x94, 0xE5, 0x1E,
++	0x00, 0xD8, 0x69, 0x1C, 0x64,
++	0x0C, 0x3C, 0xC4, 0x02, 0x11,
++	0x08, 0xE4, 0x87, 0xAF, 0x49,
++	0x04, 0xA0, 0xBA, 0x7E, 0xCD,
++	0x0D, 0xF9, 0x37, 0x35, 0x03,
++	0x0C, 0xA3, 0x49, 0xFE, 0x26,
++	0x09, 0x97, 0xF8, 0x3B, 0xBD,
++	0x0F, 0x5D, 0x62, 0xDB, 0xD5,
++	0x09, 0x03, 0x9B, 0x77, 0xC3,
++	0x05, 0x27, 0x2C, 0xA2, 0xC9,
++	0x04, 0x5F, 0x4F, 0xE1, 0xC3,
++	0x04, 0x75, 0x05, 0x66, 0x17,
++	0x0D, 0x28, 0x43, 0xBC, 0xE4,
++	0x0D, 0x51, 0x57, 0x1A, 0xBC,
++	0x04, 0x8B, 0x4C, 0x23, 0x0C,
++	0x01, 0x35, 0x47, 0x9B, 0x91,
++	0x02, 0xB4, 0xFF, 0x92, 0x5B,
++	0x02, 0x6A, 0x66, 0x07, 0x13,
++	0x0A, 0x97, 0x3D, 0x18, 0xE2,
++	0x00, 0xF1, 0x1D, 0x81, 0xA4,
++	0x0B, 0x05, 0xAF, 0xA8, 0x33,
++	0x0A, 0xF2, 0xEC, 0x05, 0x8E,
++	0x03, 0x5D, 0x87, 0x06, 0x79,
++	0x01, 0xB2, 0xC3, 0xBC, 0x22,
++	0x0C, 0xF6, 0x4B, 0xCC, 0x9F,
++	0x08, 0x31, 0xC6, 0x73, 0x93,
++	0x08, 0x70, 0x37, 0x31, 0x2C,
++	0x0C, 0x09, 0xA3, 0xD3, 0x96,
++	0x08, 0x3D, 0xD7, 0x22, 0x45,
++	0x00, 0x7A, 0xC4, 0xB7, 0xA4,
++	0x08, 0xCC, 0xC2, 0x32, 0x84,
++	0x0F, 0xE8, 0xBB, 0xD2, 0x87,
++	0x03, 0xEE, 0x81, 0x5F, 0x7C,
++	0x09, 0x5F, 0x5D, 0x0E, 0x55,
++	0x07, 0xDC, 0x0E, 0x72, 0xAD,
++	0x0A, 0x09, 0xAC, 0xE1, 0x7B,
++	0x06, 0xE7, 0xFA, 0x7F, 0xC1,
++	0x03, 0x8B, 0x53, 0x44, 0xAE,
++	0x08, 0xF3, 0xE6, 0xC3, 0x02,
++	0x0F, 0x6A, 0x33, 0xA2, 0x29,
++	0x00, 0x8C, 0x25, 0x2C, 0x89,
++	0x03, 0xBE, 0xA5, 0x06, 0xD3,
++	0x0F, 0xCF, 0x8F, 0xC9, 0x69,
++	0x02, 0x0C, 0x2F, 0x1A, 0x1F,
++	0x01, 0x63, 0xAC, 0xB5, 0xF4,
++	0x04, 0xDE, 0x52, 0xE0, 0x16,
++	0x07, 0x2C, 0xE1, 0x2B, 0x08,
++	0x02, 0x1C, 0xA4, 0x3D, 0x55,
++	0x0A, 0x19, 0x42, 0xFF, 0x4D,
++	0x0E, 0xF0, 0xFF, 0x83, 0xDF,
++	0x07, 0x32, 0x09, 0x4E, 0xD1,
++	0x05, 0xCD, 0x8A, 0x97, 0xC6,
++	0x09, 0xC5, 0x66, 0xC0, 0x3C,
++	0x08, 0x3E, 0xD7, 0x86, 0xF4,
++	0x00, 0x8A, 0xD1, 0xE7, 0xE5,
++	0x02, 0xDF, 0x91, 0x57, 0x3A,
++	0x03, 0x4F, 0x7B, 0x3F, 0xA2,
++	0x0C, 0xDC, 0x28, 0x0F, 0xBA,
++	0x01, 0x6D, 0x4A, 0x6D, 0x60,
++	0x08, 0x0A, 0x44, 0x57, 0x78,
++	0x02, 0x50, 0x3F, 0x6A, 0x24,
++	0x0F, 0x84, 0x68, 0x9A, 0x00,
++	0x0D, 0xFF, 0xDE, 0xBE, 0x27,
++	0x04, 0x12, 0x9D, 0xA3, 0x07,
++	0x0B, 0x15, 0x23, 0x89, 0xA1,
++	0x00, 0x68, 0x60, 0x4E, 0x30,
++	0x05, 0x2D, 0xEF, 0xE9, 0xF9,
++	0x0E, 0x2B, 0x19, 0x59, 0x05,
++	0x07, 0x26, 0x24, 0x62, 0xB1,
++	0x0E, 0x69, 0x17, 0xC5, 0x8F,
++	0x0A, 0xCF, 0x9D, 0x78, 0xDA,
++	0x07, 0xB1, 0xFD, 0x7A, 0xB5,
++	0x0F, 0x2A, 0x61, 0x60, 0x73,
++	0x0F, 0x70, 0x9B, 0xC8, 0x67,
++	0x07, 0xDA, 0xB7, 0x7B, 0xDE,
++	0x02, 0x0E, 0xFE, 0x5C, 0xD5,
++	0x07, 0x3B, 0x47, 0x99, 0x36,
++	0x06, 0x47, 0x04, 0x17, 0x21,
++	0x01, 0x70, 0x04, 0x61, 0x39,
++	0x06, 0x1B, 0xD1, 0x72, 0x28,
++	0x06, 0x9F, 0xB0, 0x4F, 0x74,
++	0x04, 0xCC, 0x2C, 0x63, 0xE8,
++	0x08, 0xFE, 0xE3, 0x9D, 0x45,
++	0x07, 0xBE, 0x08, 0x35, 0x77,
++	0x0A, 0xB5, 0x90, 0xD0, 0x09,
++	0x02, 0x5C, 0xA0, 0xE7, 0x54,
++	0x00, 0x2D, 0xF6, 0x42, 0x9F,
++	0x0A, 0x69, 0x13, 0xC7, 0xE1,
++	0x05, 0x7D, 0xD5, 0x96, 0x38,
++	0x0A, 0x8E, 0xD6, 0xEC, 0x50,
++	0x02, 0x37, 0x47, 0xA6, 0x27,
++	0x0A, 0x8D, 0xB0, 0xF4, 0x9E,
++	0x07, 0xA6, 0xE4, 0x54, 0x8F
++};
++
++static int ak7719_read_reg(struct ak7719_data *ak7719, u8 reg)
++{
++	int ret = i2c_smbus_read_byte_data(ak7719->client, reg);
++	if (ret > 0)
++		ret &= 0xff;
++
++	return ret;
++}
++
++static int ak7719_write_reg(struct ak7719_data *ak7719,
++		u8 reg, u8 value)
++{
++	return i2c_smbus_write_byte_data(ak7719->client, reg, value);
++}
++
++/*used to calculate the crc value for PRAM or CRAM binary*/
++unsigned short calc_crc(const char *str, unsigned short length)
++{
++	unsigned short crc = 0x0000;
++	int i, j;
++	for(i = 0; i < length; i++){
++		crc ^= *str++ << 8;
++		for(j = 0; j < 8; j++){
++			if(crc & 0x8000){
++				crc <<= 1;
++				crc ^= CRC16_CCITT;
++			} else {
++				crc <<= 1;
++			}
++		}
++	}
++
++	return crc;
++}
++
++static int ak7719_write_command(struct ak7719_data *ak7719, u8 cmdvalue,
++		u32 subaddr, u8 *pbuf, unsigned int length, u16 *crc_val)
++{
++	int ret;
++	u8 *bufcmd = NULL;
++	struct i2c_msg msg[1];
++	struct i2c_client *client;
++	client = ak7719->client;
++
++	bufcmd = kmalloc(length+3, GFP_KERNEL);
++	if (!bufcmd) {
++		return -ENOMEM;
++	}
++	bufcmd[0] = cmdvalue;
++	bufcmd[1] = (subaddr & 0xff00) >> 8;
++	bufcmd[2] = subaddr & 0xff;
++	memcpy(bufcmd + 3, pbuf, length);
++
++	/*calculate the crc value for the writing data*/
++	if(*crc_val == 0)
++		*crc_val = calc_crc(bufcmd, length+3);
++
++	/*begin to encapsulate the message for i2c*/
++	msg[0].addr = client->addr;
++	msg[0].len = length +3;
++	msg[0].flags = 0;
++	msg[0].buf = bufcmd;
++
++	ret = i2c_transfer(client->adapter, msg, 1);
++	udelay(100);
++
++	kfree(bufcmd);
++	if (ret < 0) {
++		dev_err(&client->dev, "Failed writing cmd 0x%02x!\n", cmdvalue);
++		return ret;
++	}
++	return 0;
++}
++
++unsigned short ak7719_ram_read(struct ak7719_data *ak7719, char *sbuf, u8 slen, char *rbuf, u8 rlen){
++	int ret;
++
++	ret = i2c_smbus_read_i2c_block_data(ak7719->client, sbuf[0], rlen, rbuf);
++
++	return 0;
++}
++
++static int ak7719_ram_download_crc(struct ak7719_data *ak7719, u8 cmd, u8 *data, int len ,u16 crc_value)
++{
++	u16 crc_val = crc_value;
++	u16 crc_flag = 1;
++	char crc_tx[1] = { 0x72 };
++	char crc_rx[2];
++	int ret, ret1, timeout = crc_timeout; //timeout = 3; chane 3 times to 10 times
++
++	do {	/*write PRAM or CRAM and get crc value*/
++		ret1 = ak7719_write_command(ak7719, cmd, 0, data, len, &crc_val);
++		if (ret1 != 0) {
++			pr_err(" write ram error in function  %s\n ",__FUNCTION__);
++			continue;
++		}
++
++		/*get the crc value by command 0x72*/
++		 do {
++			ret = ak7719_ram_read(ak7719, crc_tx, 1, crc_rx, 2);
++			if(ret != 0)
++				pr_err("%s:  read crc err\n",__FUNCTION__);
++		 } while (ret != 0);
++
++		ret  =  (crc_rx[0] << 8) + crc_rx[1];
++		akdbgprt("pram : crc flag ret=%x \n" ,ret);
++		crc_flag  =  (crc_val == ret);
++		timeout--;
++		udelay(10);
++	} while (crc_flag == 0 && timeout > 0);
++
++	akdbgprt("crc_flag = %d timeout = %d\n", crc_flag, timeout);
++	if(timeout == 0)
++		return -1;
++	return 0;
++}
++
++static void ak7719_download_dsp_pro(struct ak7719_data *ak7719)
++{
++	int ret;
++
++	if(aec == 1) {
++		/* pram data is ak7719 dsp binary */
++		ret = ak7719_ram_download_crc(ak7719, 0xB8, pram_data, ARRAY_SIZE(pram_data), 0xc4a9);
++		if(ret < 0) {
++			printk("ak7719:write dsp binary failed!!!\n");
++		}
++	} else if(aec == 0) {
++		/* ak77dspPRAM is ak7719 bypass dsp binary */
++		ak7719_ram_download_crc(ak7719, 0xB8, ak77dspPRAM, ARRAY_SIZE(ak77dspPRAM), 0x5bf4);
++	}
++
++	ret = ak7719_ram_download_crc(ak7719, 0xB4, cram_data, ARRAY_SIZE(cram_data), 0x50df);
++	if(ret < 0)
++		printk("ak7719:write cram data failed\n");
++
++	ak7719_write_reg(ak7719, 0xc6, 0x0);
++	ak7719_write_reg(ak7719, 0xc6, 0x4);
++
++}
++
++static void ak7719_download_work(struct work_struct *work){
++	struct ak7719_workqueue *ak7719_work = container_of(work,struct ak7719_workqueue, download_binary);
++	ak7719_download_dsp_pro(ak7719_work->data);
++}
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static int ak7719_i2c_probe(struct i2c_client *i2c,
++			    const struct i2c_device_id *id)
++{
++	int rval = 0;
++	enum of_gpio_flags flags;
++	struct device_node *np = i2c->dev.of_node;
++	struct ak7719_data *ak7719 = NULL;
++	int rst_pin;
++
++	ak7719 = devm_kzalloc(&i2c->dev, sizeof(struct ak7719_data), GFP_KERNEL);
++	if (ak7719 == NULL) {
++		printk("kzalloc for ak7719 is failed\n");
++		return -ENOMEM;
++	}
++
++	rst_pin = of_get_gpio_flags(np, 0, &flags);
++	if (rst_pin < 0 || !gpio_is_valid(rst_pin)) {
++		printk("ak7719 rst pin is not working");
++		rval = -ENXIO;
++		goto out;
++	}
++
++	ak7719->rst_pin = rst_pin;
++	ak7719->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	ak7719->client = i2c;
++	i2c_set_clientdata(i2c, ak7719);
++#if 1
++	rval = devm_gpio_request(&i2c->dev, ak7719->rst_pin, "ak7719 reset");
++	if (rval < 0){
++		dev_err(&i2c->dev, "Failed to request rst_pin: %d\n", rval);
++		goto out;
++	}
++
++	/* Reset AK7719 dsp */
++	gpio_direction_output(ak7719->rst_pin, ak7719->rst_active);
++	msleep(10);
++	gpio_direction_output(ak7719->rst_pin, !ak7719->rst_active);
++	msleep(10);
++#endif
++	ak7719_read_reg(ak7719, 0x50);
++	ak7719_read_reg(ak7719, 0x51);
++	ak7719_write_reg(ak7719, 0xd0, 0x1);
++	ak7719_write_reg(ak7719, 0xd1, 0x1);
++	ak7719_write_reg(ak7719, 0xc0, 0x20);
++	ak7719_write_reg(ak7719, 0xc1, 0x30);
++	ak7719_write_reg(ak7719, 0xc2, 0x64);
++	ak7719_write_reg(ak7719, 0xc3, 0xb2);
++	ak7719_write_reg(ak7719, 0xc4, 0xf0);
++	ak7719_write_reg(ak7719, 0xc5, 0x0);
++	ak7719_write_reg(ak7719, 0xc6, 0x0);
++	//ak7719_write_reg(ak7719, 0xc7, 0x0);
++	ak7719_write_reg(ak7719, 0xc8, 0x80);
++//	ak7719_read_reg(ak7719, 0x50);
++//	ak7719_read_reg(ak7719, 0x51);
++//	ak7719_read_reg(ak7719, 0x47);
++
++	ak7719_write_reg(ak7719, 0xc6, 0x20);
++	msleep(1);
++
++	ak7719_wq = create_workqueue("ak7719_workqueue");
++	ak7719_work.data = ak7719;
++ 	INIT_WORK(&(ak7719_work.download_binary), ak7719_download_work);
++	queue_work(ak7719_wq, &(ak7719_work.download_binary));
++
++	return 0;
++out:
++	devm_kfree(&i2c->dev, ak7719);
++	return rval;
++}
++
++static int ak7719_i2c_remove(struct i2c_client *client)
++{	struct ak7719_data *ak7719 = NULL;
++
++	destroy_workqueue(ak7719_wq);
++	ak7719_wq = NULL;
++	ak7719_work.data = NULL;
++	ak7719 = i2c_get_clientdata(client);
++	devm_gpio_free(&client->dev, ak7719->rst_pin);
++	devm_kfree(&client->dev, ak7719);
++
++	return 0;
++}
++
++static const struct of_device_id ak7719_dt_ids[] = {
++	{ .compatible = "ambarella,ak7719",},
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ak7719_dt_ids);
++
++static const struct i2c_device_id ak7719_i2c_id[] = {
++	{ "ak7719", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, ak7719_i2c_id);
++
++static struct i2c_driver ak7719_i2c_driver = {
++	.driver = {
++		.name = "DRIVER_NAME",
++		.owner = THIS_MODULE,
++		.of_match_table = ak7719_dt_ids,
++	},
++	.probe		=	ak7719_i2c_probe,
++	.remove		=	ak7719_i2c_remove,
++	.id_table	=	ak7719_i2c_id,
++};
++#endif
++
++static int __init ak7719_modinit(void)
++{
++	int ret;
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&ak7719_i2c_driver);
++	if (ret != 0)
++		pr_err("Failed to register AK7719 I2C driver: %d\n", ret);
++#endif
++	return ret;
++}
++module_init(ak7719_modinit);
++static void __exit ak7719_exit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	i2c_del_driver(&ak7719_i2c_driver);
++#endif
++}
++module_exit(ak7719_exit);
++
++MODULE_DESCRIPTION("Amabrella Board AK7719 DSP for Audio Codec");
++MODULE_AUTHOR("Ken He <jianhe@ambarella.com>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:"DRIVER_NAME);
+diff --git a/sound/soc/codecs/ak7755.c b/sound/soc/codecs/ak7755.c
+new file mode 100644
+index 00000000..d74d5fc0
+--- /dev/null
++++ b/sound/soc/codecs/ak7755.c
+@@ -0,0 +1,2720 @@
++/*
++ * ak7755.c  --  audio driver for AK7755
++ *
++ * Copyright (C) 2014 Asahi Kasei Microdevices Corporation
++ *  Author                Date        Revision
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *                      14/04/22	    1.0
++ *                      15/06/15	    1.1
++ *                      16/01/13	    2.01  kernel 3.10.94
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/gpio.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++#include <sound/pcm_params.h>
++#include <linux/ioctl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/spi/spi.h>
++#include <plat/spi.h>
++
++
++#include <linux/of_gpio.h> // '16/01/13
++
++#include <linux/mutex.h>
++#include <linux/firmware.h>
++#include <linux/vmalloc.h>
++
++#include <sound/ak7755_pdata.h>    // '15/06/15
++#include "ak7755.h"
++#include "ak7755_dsp_code.h"
++#include <linux/types.h>
++
++//#define AK7755_PD_SUSPEND     // '15/06/15
++
++//#define AK7755_DEBUG			//used at debug mode
++#define AK7755_CONTIF_DEBUG	//used at debug mode
++
++#ifdef AK7755_DEBUG
++#define akdbgprt printk
++#else
++#define akdbgprt(format, arg...) do {} while (0)
++#endif
++static int fast_boot = 0;
++module_param(fast_boot, uint, 0664);
++static int aec = 1;
++module_param(aec, uint, 0664);
++static int RAM_FLAG = 1;
++
++/* AK7755 Codec Private Data */
++struct ak7755_priv {
++	enum snd_soc_control_type control_type;
++	struct snd_soc_codec *codec;
++	struct spi_device *spi;
++	struct i2c_client *i2c;
++	int fs;
++	int rclk;			//Master Clock
++	int lign;			//LIGN3-0(LineIn Volume)
++	int selmix;			//SELMIX2-0
++	int status;
++	int MIRNo;
++	int bickfs;         // '15/06/15  0:64fs, 1:48fs, 2:32fs, 3:256fs
++	int pdn_gpio;       // '15/06/15
++	unsigned int pdn_active;
++	int power_gpio;
++	unsigned int power_active;
++	int amp_gpio;
++	unsigned int amp_active;
++	unsigned int fmt;
++	u8 reg_cache[AK7755_MAX_REGNUM];
++
++	u16  DSPPramMode;
++	u16  DSPCramMode;
++	u16  DSPOfregMode;
++	u16  DSPAcramMode;
++	int  EQLevel[5];
++	int  HPFfc[2];
++	int  LimRel;
++	int  LimVol;
++};
++
++struct _ak7755_pd_handler {
++	int ref_count;
++	struct mutex lock;
++	struct ak7755_priv *data;
++} ak7755_pd_handler = {
++	.ref_count = -1,
++	.data = NULL,
++};
++
++
++static int ak7755_reads(u8 *, size_t, u8 *, size_t);
++static int ak7755_writes(const u8 *tx, size_t wlen);
++static unsigned int ak7755_i2c_read(u8 *reg,int reglen,u8 *data,int datalen);
++
++
++static struct ak7755_priv *ak7755_data;
++/* ak7755 register cache & default register settings */
++static u8 ak7755_reg[AK7755_MAX_REGISTERS];
++
++static const u8 ak7755_reg2[] = {
++	0x00,	/*	0xC0	AK7755_C0_CLOCK_SETTING1			*/
++	0x00,	/*	0xC1	AK7755_C1_CLOCK_SETTING2			*/
++	0x00,	/*	0xC2	AK7755_C2_SERIAL_DATA_FORMAT		*/
++	0x00,	/*	0xC3	AK7755_C3_DELAY_RAM_DSP_IO			*/
++	0x00,	/*	0xC4	AK7755_C4_DATARAM_CRAM_SETTING		*/
++	0x00,	/*	0xC5	AK7755_C5_ACCELARETOR_SETTING		*/
++	0x00,	/*	0xC6	AK7755_C6_DAC_DEM_SETTING			*/
++	0x00,	/*	0xC7	AK7755_C7_DSP_OUT_SETTING			*/
++	0x00,	/*	0xC8	AK7755_C8_DAC_IN_SETTING			*/
++	0x00,	/*	0xC9	AK7755_C9_ANALOG_IO_SETTING			*/
++	0x00,	/*	0xCA	AK7755_CA_CLK_SDOUT_SETTING			*/
++	0x00,	/*	0xCB	AK7755_CB_TEST_SETTING				*/
++	0x00,	/*	0xCC	AK7755_CC_VOLUME_TRANSITION			*/
++	0x80,	/*	0xCD	AK7755_CD_STO_DLS_SETTING			*/
++	0x00,	/*	0xCE	AK7755_CE_POWER_MANAGEMENT			*/
++	0x00,	/*	0xCF	AK7755_CF_RESET_POWER_SETTING		*/
++	0x00,	/*	0xD0	AK7755_D0_FUNCTION_SETTING			*/
++	0x00,	/*	0xD1	AK7755_D1_DSPMCLK_SETTING			*/
++	0x00,	/*	0xD2	AK7755_D2_MIC_GAIN_SETTING			*/
++	0x00,	/*	0xD3	AK7755_D3_LIN_LO3_VOLUME_SETTING	*/
++	0x00,	/*	0xD4	AK7755_D4_LO1_LO2_VOLUME_SETTING	*/
++	0x30,	/*	0xD5	AK7755_D5_ADC_DVOLUME_SETTING1		*/
++	0x30,	/*	0xD6	AK7755_D6_ADC_DVOLUME_SETTING2		*/
++	0x30,	/*	0xD7	AK7755_D7_ADC2_DVOLUME_SETTING1		*/
++	0x18,	/*	0xD8	AK7755_D8_DAC_DVOLUME_SETTING1		*/
++	0x18,	/*	0xD9	AK7755_D9_DAC_DVOLUME_SETTING2		*/
++	0x00,	/*	0xDA	AK7755_DA_MUTE_ADRC_ZEROCROSS_SET	*/
++	0x00,	/*	0xDB	AK7755_DB_ADRC_MIC_GAIN_READ		*/
++	0x00,	/*	0xDC	AK7755_DC_TEST_SETTING				*/
++	0x30,	/*	0xDD	AK7755_DD_ADC2_DVOLUME_SETTING2		*/
++	0x00,	/*	0xDE	AK7755_DE_DMIC_IF_SETTING			*/
++};
++
++static struct {
++	int readable;   /* Mask of readable bits */
++	int writable;   /* Mask of writable bits */
++} ak7755_access_masks[AK7755_MAX_REGISTERS];
++
++static const struct {
++	int readable;   /* Mask of readable bits */
++	int writable;   /* Mask of writable bits */
++} ak7755_access_masks2[] = {
++    { 0xFF, 0x7F },	//0xC0
++    { 0xFF, 0xFF },	//0xC1
++    { 0xFF, 0xFF },	//0xC2
++    { 0xFF, 0xFF },	//0xC3
++    { 0xFF, 0xFB },	//0xC4
++    { 0xFF, 0xFF },	//0xC5
++    { 0xFF, 0xF7 },	//0xC6
++    { 0xFF, 0xF7 },	//0xC7
++    { 0xFF, 0xFF },	//0xC8
++    { 0xFF, 0xFF },	//0xC9
++    { 0xFF, 0xE7 },	//0xCA
++    { 0xFF, 0x00 },	//0xCB
++    { 0xFF, 0xB7 },	//0xCC
++    { 0xFF, 0x81 },	//0xCD
++    { 0xFF, 0xFF },	//0xCE
++    { 0xFF, 0x3F },	//0xCF
++    { 0xFF, 0xF9 },	//0xD0
++    { 0xFF, 0xFF },	//0xD1
++    { 0xFF, 0xFF },	//0xD2
++    { 0xFF, 0xFF },	//0xD3
++    { 0xFF, 0xFF },	//0xD4
++    { 0xFF, 0xFF },	//0xD5
++    { 0xFF, 0xFF },	//0xD6
++    { 0xFF, 0xFF },	//0xD7
++    { 0xFF, 0xFF },	//0xD8
++    { 0xFF, 0xFF },	//0xD9
++    { 0xFF, 0xFF },	//0xDA
++    { 0xFF, 0x00 },	//0xDB
++    { 0xFF, 0x00 },	//0xDC
++    { 0xFF, 0xFF },	//0xDD
++    { 0xFF, 0xFC },	//0xDE
++};
++
++/* MIC Input Volume control:
++ * from 0 to 36 dB (quantity of each step is various) */
++static DECLARE_TLV_DB_MINMAX(mgnl_tlv, 0, 3600);
++static DECLARE_TLV_DB_MINMAX(mgnr_tlv, 0, 3600);
++
++/* Line-out Volume control:
++ * from -30 to 0 dB in 2 dB steps (mute instead of -30 dB) */
++static DECLARE_TLV_DB_SCALE(lovol1_tlv, -3000, 200, 0);
++static DECLARE_TLV_DB_SCALE(lovol2_tlv, -3000, 200, 0);
++static DECLARE_TLV_DB_SCALE(lovol3_tlv, -3000, 200, 0);
++
++static const char *line_in_texts[]  =
++{
++	"-21dB","-18dB","-15dB","-12dB","-9dB","-6dB","-3dB",
++	"0dB","+3dB","+6dB","+9dB","+12dB","+15dB","+18dB","+21dB",
++};
++
++static const struct soc_enum ak7755_linein_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(line_in_texts), line_in_texts),
++};
++
++/* ADC, ADC2 Digital Volume control:
++ * from -103.5 to 24 dB in 0.5 dB steps (mute instead of -103.5 dB) */
++static DECLARE_TLV_DB_SCALE(voladl_tlv, -10350, 50, 0);
++static DECLARE_TLV_DB_SCALE(voladr_tlv, -10350, 50, 0);
++static DECLARE_TLV_DB_SCALE(volad2l_tlv, -10350, 50, 0);
++static DECLARE_TLV_DB_SCALE(volad2r_tlv, -10350, 50, 0);
++
++/* DAC Digital Volume control:
++ * from -115.5 to 12 dB in 0.5 dB steps (mute instead of -115.5 dB) */
++static DECLARE_TLV_DB_SCALE(voldal_tlv, -11550, 50, 0);
++static DECLARE_TLV_DB_SCALE(voldar_tlv, -11550, 50, 0);
++
++
++static const char *ak7755_bank_select_texts[] =
++		{"0:8192", "1024:7168","2048:6144","3072:5120","4096:4096",
++			"5120:3072","6144:2048","7168:1024","8192:0"};
++static const char *ak7755_drms_select_texts[] =
++		{"512:1536", "1024:1024", "1536:512"};
++static const char *ak7755_dram_select_texts[] =
++		{"Ring:Ring", "Ring:Linear", "Linear:Ring", "Linear:Linear"};
++static const char *ak7755_pomode_select_texts[] = {"DBUS Immediate", "OFREG"};
++static const char *ak7755_wavp_select_texts[] =
++		{"33 word", "65 word", "129 word", "257 word"};
++static const char *ak7755_filmode1_select_texts[] = {"Adaptive Filter", "FIR Filter"};
++static const char *ak7755_filmode2_select_texts[] = {"Adaptive Filter", "FIR Filter"};
++static const char *ak7755_submode1_select_texts[] = {"Fullband", "Subband"};
++static const char *ak7755_submode2_select_texts[] = {"Fullband", "Subband"};
++static const char *ak7755_memdiv_select_texts[] =
++		{"2048:-", "1792:256", "1536:512", "1024:1024"};
++static const char *ak7755_dem_select_texts[] = {"Off", "48kHz", "44.1kHz", "32kHz"};
++static const char *ak7755_clkoe_select_texts[] = {"CLKO=L", "CLKO Out Enable"};
++static const char *ak7755_clks_select_texts[] =
++		{"12.288MHz", "6.144MHz", "3.072MHz", "8.192MHz",
++			"4.096MHz", "2.048MHz", "256fs", "XTI or BICK"};
++
++static const struct soc_enum ak7755_set_enum[] = {
++	SOC_ENUM_SINGLE(AK7755_C3_DELAY_RAM_DSP_IO, 0,
++			ARRAY_SIZE(ak7755_bank_select_texts), ak7755_bank_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 6,
++			ARRAY_SIZE(ak7755_drms_select_texts), ak7755_drms_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 4,
++			ARRAY_SIZE(ak7755_dram_select_texts), ak7755_dram_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 3,
++			ARRAY_SIZE(ak7755_pomode_select_texts), ak7755_pomode_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 0,
++			ARRAY_SIZE(ak7755_wavp_select_texts), ak7755_wavp_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 5,
++			ARRAY_SIZE(ak7755_filmode1_select_texts), ak7755_filmode1_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 4,
++			ARRAY_SIZE(ak7755_filmode2_select_texts), ak7755_filmode2_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 3,
++			ARRAY_SIZE(ak7755_submode1_select_texts), ak7755_submode1_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 2,
++			ARRAY_SIZE(ak7755_submode2_select_texts), ak7755_submode2_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 0,
++			ARRAY_SIZE(ak7755_memdiv_select_texts), ak7755_memdiv_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C6_DAC_DEM_SETTING, 6,
++			ARRAY_SIZE(ak7755_dem_select_texts), ak7755_dem_select_texts),
++	SOC_ENUM_SINGLE(AK7755_CA_CLK_SDOUT_SETTING, 7,
++			ARRAY_SIZE(ak7755_clkoe_select_texts), ak7755_clkoe_select_texts),
++	SOC_ENUM_SINGLE(AK7755_C1_CLOCK_SETTING2, 1,
++			ARRAY_SIZE(ak7755_clks_select_texts), ak7755_clks_select_texts),
++};
++
++// '15/06/15
++static const char *ak7755_bick_select_texts[] =
++		{"64fs", "48fs", "32fs", "TDM" };
++
++static const struct soc_enum ak7755_bick_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_bick_select_texts), ak7755_bick_select_texts)
++};
++
++static int get_bickfs(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak7755->bickfs;
++
++    return 0;
++}
++
++static int set_bickfs(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++	ak7755->bickfs = ucontrol->value.enumerated.item[0];
++    return 0;
++}
++// '15/06/15
++
++static const char *selmix_set_texts[]  =
++{
++	"SDOUTAD", "ADL_AD2L/ADR", "ADL/ADR_AD2R", "SDOUTAD2",
++	"DSPL/AD2R", "AD2L/DSPR", "DSPL/ADR", "ADL/DSPR",
++};
++
++static const struct soc_enum ak7755_selmix_enum[] = {
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(selmix_set_texts), selmix_set_texts),
++};
++
++// Added for AK7755
++static const struct soc_enum ak7755_firmware_enum[] =
++{
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_pram), ak7755_firmware_pram),
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_cram), ak7755_firmware_cram),
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_ofreg), ak7755_firmware_ofreg),
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_acram), ak7755_firmware_acram),
++};
++
++static inline u32 ak7755_read_reg_cache(struct snd_soc_codec *, u16);
++static int ak7755_firmware_write_ram(u16 mode, u16 cmd);
++static int ak7755_set_status(enum ak7755_status status);
++static int ak7755_write_cram(int addr, int len, unsigned char *cram_data);
++
++static int get_linein(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak7755->lign;
++
++    return 0;
++}
++
++static int set_linein(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++	ak7755->lign = ucontrol->value.enumerated.item[0];
++
++	if ( ak7755->lign <= 7) {
++		snd_soc_update_bits(codec, AK7755_D3_LIN_LO3_VOLUME_SETTING, 0xF0, ((7 - ak7755->lign) << 4) );
++	}
++	else {
++		snd_soc_update_bits(codec, AK7755_D3_LIN_LO3_VOLUME_SETTING, 0xF0, ((ak7755->lign + 1) << 4) );
++	}
++
++    return 0;
++}
++
++static int get_selmix(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++    ucontrol->value.enumerated.item[0] = ak7755->selmix;
++
++    return 0;
++}
++
++static int set_selmix(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++	ak7755->selmix = ucontrol->value.enumerated.item[0];
++
++	if ( ak7755->selmix < 4) {	//SELMIX2=0, SELMIX1-0=selmix
++		snd_soc_update_bits(codec, AK7755_C9_ANALOG_IO_SETTING, 0x01, 0x00);
++		snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0x03, ak7755->selmix);
++	}
++	else {						//SELMIX2=1, SELMIX1-0=(selmix & 0x03)
++		snd_soc_update_bits(codec, AK7755_C9_ANALOG_IO_SETTING, 0x01, 0x01);
++		snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0x03, (ak7755->selmix & 0x03));
++	}
++
++    return 0;
++}
++
++static int get_DSP_write_pram(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = ak7755_data->DSPPramMode;
++
++    return 0;
++
++}
++
++static int set_DSP_write_pram(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    ret;
++	akdbgprt("set_DSP_write_pram start ...\n");
++
++/*
++	if ( currMode == ak7755_data->DSPPramMode ) {
++		akdbgprt("\t%s Same PRAM mode =%d\n",__FUNCTION__, currMode);
++		return(0);
++	}
++*/
++	if (RAM_FLAG ==1 ){
++		akdbgprt("\t%s PRAM mode =%d\n",__FUNCTION__, currMode);
++
++		ret = ak7755_firmware_write_ram(RAMTYPE_PRAM, currMode);
++		if ( ret != 0 ) return(-1);
++
++		ak7755_data->DSPPramMode = currMode;
++	}
++	akdbgprt("set_DSP_write_pram done ...\n");
++	return(0);
++}
++
++static int get_DSP_write_cram(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = ak7755_data->DSPCramMode;
++
++    return 0;
++
++}
++
++static int set_DSP_write_cram(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    ret;
++	akdbgprt("set_DSP_write_cram start ...\n");
++
++/*
++	if ( currMode == ak7755_data->DSPCramMode ) {
++		akdbgprt("\t%s Same CRAM mode =%d\n",__FUNCTION__, currMode);
++		return(0);
++	}
++*/
++	if (RAM_FLAG ==1){
++		RAM_FLAG = 0 ;
++		akdbgprt("\t%s CRAM mode =%d\n",__FUNCTION__, currMode);
++
++		ret = ak7755_firmware_write_ram(RAMTYPE_CRAM, currMode);
++		if ( ret != 0 ) return(-1);
++
++		ak7755_data->DSPCramMode =currMode;
++	}
++	akdbgprt("set_DSP_write_cram done ...\n");
++	return(0);
++}
++
++static int get_DSP_write_ofreg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = ak7755_data->DSPOfregMode;
++
++    return 0;
++
++}
++
++static int set_DSP_write_ofreg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    ret;
++
++/*
++	if ( currMode == ak7755_data->DSPOfregMode ) {
++		akdbgprt("\t%s Same CRAM mode =%d\n",__FUNCTION__, currMode);
++		return(0);
++	}
++	akdbgprt("\t%s OFREG mode =%d\n",__FUNCTION__, currMode);
++*/
++	ret = ak7755_firmware_write_ram(RAMTYPE_OFREG, currMode);
++	if ( ret != 0 ) return(-1);
++
++	ak7755_data->DSPOfregMode =currMode;
++
++	return(0);
++}
++
++static int get_DSP_write_acram(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = ak7755_data->DSPAcramMode;
++
++    return 0;
++
++}
++
++static int set_DSP_write_acram(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    ret;
++
++/*
++	if ( currMode == ak7755_data->DSPAcramMode ) {
++		akdbgprt("\t%s Same CRAM mode =%d\n",__FUNCTION__, currMode);
++		return(0);
++	}
++*/
++	akdbgprt("\t%s ACRAM mode =%d\n",__FUNCTION__, currMode);
++
++	ret = ak7755_firmware_write_ram(RAMTYPE_ACRAM, currMode);
++	if ( ret != 0 ) return(-1);
++
++	ak7755_data->DSPAcramMode =currMode;
++
++	return(0);
++}
++
++#ifdef AK7755_DEBUG
++
++static int test_read_ram(int mode)
++{
++	u8	tx[3], rx[512];
++	int i, n, plen, clen;
++
++	akdbgprt("*****[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x1, 0x1);  // DLRDY bit = 1
++	mdelay(1);
++	if ( mode == 1 ) {
++		plen = 10;
++		for ( n = 0 ; n < (5 * plen) ; n++ ) rx[n] = 0;
++		tx[0] = 0x38;
++		tx[1] = 0x0;
++		tx[2] = 0x0;
++		ak7755_reads(tx, 3, rx, 5 * plen);
++		printk("*****%s PRAM LEN = %d *******\n", __func__, plen);
++		n = 0;
++		for ( i = 0 ; i < plen ; i ++ ) {
++			printk("PAddr=%x %x %x %x %x %x\n", i,(int)rx[n], (int)rx[n+1], (int)rx[n+2], (int)rx[n+3], (int)rx[n+4]);
++			n += 5;
++		}
++	}
++	else if ( mode < 5 ) {
++		clen = 80;
++		for ( n = 0 ; n < (3 * clen) ; n++ ) rx[n] = 0;
++		if ( mode == 2 ) tx[0] = 0x34;
++		else if ( mode == 3 ) {
++			tx[0] = 0x32;
++			clen = 16;
++		}
++		else  tx[0] = 0x3B;
++		tx[1] = 0x0;
++		tx[2] = 0x0;
++		ak7755_reads(tx, 3, rx, 3 * clen);
++		printk("*****%s RAM CMD=%d,  LEN = %d*******\n", __func__, (int)tx[0], clen);
++		n = 0;
++		for ( i = 0 ; i < clen ; i ++ ) {
++			printk("CAddr=%x %x %x %x\n", i,(int)rx[n], (int)rx[n+1], (int)rx[n+2]);
++			n += 3;
++		}
++	}
++	mdelay(1);
++	snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x1, 0x0);  // DLRDY bit = 0
++
++	return(0);
++
++}
++
++static const char *test_reg_select[]   =
++{
++    "read AK7755 Reg 00:24",
++	"read PRAM",
++	"read CRAM",
++	"read OFREG",
++	"read ACRAM",
++};
++
++static const struct soc_enum ak7755_enum[] =
++{
++    SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
++};
++
++static int nTestRegNo = 0;
++
++
++static int get_test_reg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    /* Get the current output routing */
++    ucontrol->value.enumerated.item[0] = nTestRegNo;
++
++    return 0;
++}
++
++static int set_test_reg(
++struct snd_kcontrol       *kcontrol,
++struct snd_ctl_elem_value  *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++    u32    currMode = ucontrol->value.enumerated.item[0];
++	int    i, value;
++	int	   regs, rege;
++
++	nTestRegNo = currMode;
++
++	if ( currMode == 0 ) {
++		regs = 0xC0;
++		rege = 0xDE;
++
++		for ( i = regs ; i <= rege ; i++ ){
++			value = snd_soc_read(codec, i);
++			printk("***AK7755 Addr,Reg=(%x, %x)\n", i, value);
++		}
++	}
++	else if ( currMode < 5 ) {
++		test_read_ram(currMode);
++	}
++
++	return 0;
++
++}
++#endif
++
++static const struct snd_kcontrol_new ak7755_snd_controls[] = {
++	SOC_SINGLE_TLV("MIC Input Volume L",
++			AK7755_D2_MIC_GAIN_SETTING, 0, 0x0F, 0, mgnl_tlv),
++	SOC_SINGLE_TLV("MIC Input Volume R",
++			AK7755_D2_MIC_GAIN_SETTING, 4, 0x0F, 0, mgnr_tlv),
++	SOC_SINGLE_TLV("Line Out Volume 1",
++			AK7755_D4_LO1_LO2_VOLUME_SETTING, 0, 0x0F, 0, lovol1_tlv),
++	SOC_SINGLE_TLV("Line Out Volume 2",
++			AK7755_D4_LO1_LO2_VOLUME_SETTING, 4, 0x0F, 0, lovol2_tlv),
++	SOC_SINGLE_TLV("Line Out Volume 3",
++			AK7755_D3_LIN_LO3_VOLUME_SETTING, 0, 0x0F, 0, lovol3_tlv),
++	SOC_ENUM_EXT("Line Input Volume", ak7755_linein_enum[0], get_linein, set_linein),
++	SOC_SINGLE_TLV("ADC Digital Volume L",
++			AK7755_D5_ADC_DVOLUME_SETTING1, 0, 0xFF, 1, voladl_tlv),
++	SOC_SINGLE_TLV("ADC Digital Volume R",
++			AK7755_D6_ADC_DVOLUME_SETTING2, 0, 0xFF, 1, voladr_tlv),
++	SOC_SINGLE_TLV("ADC2 Digital Volume L",
++			AK7755_D7_ADC2_DVOLUME_SETTING1, 0, 0xFF, 1, volad2l_tlv),
++	SOC_SINGLE_TLV("ADC2 Digital Volume R",
++			AK7755_DD_ADC2_DVOLUME_SETTING2, 0, 0xFF, 1, volad2r_tlv),
++	SOC_SINGLE_TLV("DAC Digital Volume L",
++			AK7755_D8_DAC_DVOLUME_SETTING1, 0, 0xFF, 1, voldal_tlv),
++	SOC_SINGLE_TLV("DAC Digital Volume R",
++			AK7755_D9_DAC_DVOLUME_SETTING2, 0, 0xFF, 1, voldar_tlv),
++
++	SOC_SINGLE("ADC Mute", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 7, 1, 0),
++	SOC_SINGLE("ADC2 Mute", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 6, 1, 0),
++	SOC_SINGLE("DAC Mute", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 5, 1, 0),
++	SOC_SINGLE("Analog DRC Lch", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 2, 1, 0),
++	SOC_SINGLE("Analog DRC Rch", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 3, 1, 0),
++	SOC_SINGLE("MICGAIN Lch Zero-cross", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 0, 1, 0),
++	SOC_SINGLE("MICGAIN Rch Zero-cross", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 1, 1, 0),
++
++	SOC_ENUM("DAC De-emphasis", ak7755_set_enum[10]),
++
++	SOC_SINGLE("JX0 Enable", AK7755_C2_SERIAL_DATA_FORMAT, 0, 1, 0),
++	SOC_SINGLE("JX1 Enable", AK7755_C2_SERIAL_DATA_FORMAT, 1, 1, 0),
++	SOC_SINGLE("JX2 Enable", AK7755_C1_CLOCK_SETTING2, 7, 1, 0),
++	SOC_SINGLE("JX3 Enable", AK7755_C5_ACCELARETOR_SETTING, 6, 1, 0),
++
++	SOC_ENUM("DLRAM Mode(Bank1:Bank0)", ak7755_set_enum[0]),
++	SOC_ENUM("DRAM Size(Bank1:Bank0)", ak7755_set_enum[1]),
++	SOC_ENUM("DRAM Addressing Mode(Bank1:Bank0)", ak7755_set_enum[2]),
++	SOC_ENUM("POMODE DLRAM Pointer 0", ak7755_set_enum[3]),
++	SOC_ENUM("CRAM Memory Assignment", ak7755_set_enum[4]),
++	SOC_ENUM("FIRMODE1 Accelerator Ch1", ak7755_set_enum[5]),
++	SOC_ENUM("FIRMODE2 Accelerator Ch2", ak7755_set_enum[6]),
++	SOC_ENUM("SUBMODE1 Accelerator Ch1", ak7755_set_enum[7]),
++	SOC_ENUM("SUBMODE2 Accelerator Ch2", ak7755_set_enum[8]),
++	SOC_ENUM("Accelerator Memory(ch1:ch2)", ak7755_set_enum[9]),
++	SOC_ENUM("CLKO pin", ak7755_set_enum[11]),
++	SOC_ENUM("CLKO Output Clock", ak7755_set_enum[12]),
++
++	SOC_ENUM_EXT("BICK fs", ak7755_bick_enum[0], get_bickfs, set_bickfs),     // '15/06/15
++
++// Added for AK7755
++	SOC_ENUM_EXT("DSP Firmware PRAM", ak7755_firmware_enum[0], get_DSP_write_pram, set_DSP_write_pram),
++	SOC_ENUM_EXT("DSP Firmware CRAM", ak7755_firmware_enum[1], get_DSP_write_cram, set_DSP_write_cram),
++	SOC_ENUM_EXT("DSP Firmware OFREG", ak7755_firmware_enum[2], get_DSP_write_ofreg, set_DSP_write_ofreg),
++	SOC_ENUM_EXT("DSP Firmware ACRAM", ak7755_firmware_enum[3], get_DSP_write_acram, set_DSP_write_acram),
++#if 0
++#ifdef AK7755_CRAM_BASIC_COTROL
++	SOC_ENUM_EXT("CRAM EQ1 Level", ak7755_cram_write_enum[0], get_cram_write_eq1, set_cram_write_eq1),
++	SOC_ENUM_EXT("CRAM EQ2 Level", ak7755_cram_write_enum[0], get_cram_write_eq2, set_cram_write_eq2),
++	SOC_ENUM_EXT("CRAM EQ3 Level", ak7755_cram_write_enum[0], get_cram_write_eq3, set_cram_write_eq3),
++	SOC_ENUM_EXT("CRAM EQ4 Level", ak7755_cram_write_enum[0], get_cram_write_eq4, set_cram_write_eq4),
++	SOC_ENUM_EXT("CRAM EQ5 Level", ak7755_cram_write_enum[0], get_cram_write_eq5, set_cram_write_eq5),
++	SOC_ENUM_EXT("CRAM HPF1 fc", ak7755_cram_write_enum[1], get_cram_write_hpf1fc, set_cram_write_hpf1fc),
++	SOC_ENUM_EXT("CRAM HPF2 fc", ak7755_cram_write_enum[1], get_cram_write_hpf2fc, set_cram_write_hpf2fc),
++	SOC_ENUM_EXT("CRAM Limiter Release Time", ak7755_cram_write_enum[2], get_cram_write_limrel, set_cram_write_limrel),
++	SOC_ENUM_EXT("CRAM Limiter Volume", ak7755_cram_write_enum[3], get_cram_write_limvol, set_cram_write_limvol),
++#endif
++#endif
++#ifdef AK7755_DEBUG
++	SOC_ENUM_EXT("Reg Read", ak7755_enum[0], get_test_reg, set_test_reg),
++#endif
++
++	SOC_ENUM_EXT("SELMIX2-0", ak7755_selmix_enum[0], get_selmix, set_selmix),	//SELMIX2-0 bit setting
++
++};
++
++
++/* Clock Event for DAC, ADC */
++static int ak7755_clkset_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:	/* after widget power up */
++		snd_soc_update_bits(codec, AK7755_CF_RESET_POWER_SETTING, 0x08,0x08);	//CRESETN(CODEC ResetN)=1
++		break;
++	}
++
++	return 0;
++}
++
++/* Clock Event */
++static int ak7755_clock_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event) //CONFIG_LINF
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	switch (event) {
++		case SND_SOC_DAPM_POST_PMU:	/* after widget power up */
++			akdbgprt("\t[AK7755] %s wait=10msec\n",__FUNCTION__);
++			mdelay(10);
++			break;
++		case SND_SOC_DAPM_PRE_PMD:	/* before widget power down */
++			snd_soc_update_bits(codec, AK7755_CF_RESET_POWER_SETTING, 0x08,0x00);	//CODEC Reset
++			break;
++	}
++
++	return 0;
++}
++
++/* SDOUT 1 switch */
++static const struct snd_kcontrol_new ak7755_out1e_control =
++	SOC_DAPM_SINGLE("Switch", AK7755_CA_CLK_SDOUT_SETTING, 0, 1, 0);
++
++/* SDOUT 2 switch */
++static const struct snd_kcontrol_new ak7755_out2e_control =
++	SOC_DAPM_SINGLE("Switch", AK7755_CA_CLK_SDOUT_SETTING, 1, 1, 0);
++
++/* SDOUT 3 switch */
++static const struct snd_kcontrol_new ak7755_out3e_control =
++	SOC_DAPM_SINGLE("Switch", AK7755_CA_CLK_SDOUT_SETTING, 2, 1, 0);
++
++/* LineOut1 Switch */
++static const char *ak7755_pmlo1_select_texts[] =
++		{"Off", "On"};
++
++static const struct soc_enum ak7755_pmlo1_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_CE_POWER_MANAGEMENT, 2,
++			ARRAY_SIZE(ak7755_pmlo1_select_texts), ak7755_pmlo1_select_texts);
++//	SOC_ENUM_SINGLE(0, 0,
++//			ARRAY_SIZE(ak7755_pmlo1_select_texts), ak7755_pmlo1_select_texts);
++
++static const struct snd_kcontrol_new ak7755_pmlo1_mux_control =
++	SOC_DAPM_ENUM("OUT1 SW", ak7755_pmlo1_mux_enum);
++	//SOC_DAPM_ENUM_VIRT("OUT1 SW", ak7755_pmlo1_mux_enum);
++
++/* LineOut2 Switch */
++static const char *ak7755_pmlo2_select_texts[] =
++		{"Off", "On"};
++
++static const struct soc_enum ak7755_pmlo2_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_CE_POWER_MANAGEMENT, 3,
++			ARRAY_SIZE(ak7755_pmlo2_select_texts), ak7755_pmlo2_select_texts);
++//	SOC_ENUM_SINGLE(0, 0,
++//			ARRAY_SIZE(ak7755_pmlo2_select_texts), ak7755_pmlo2_select_texts);
++
++static const struct snd_kcontrol_new ak7755_pmlo2_mux_control =
++	SOC_DAPM_ENUM("OUT2 SW", ak7755_pmlo2_mux_enum);
++//	SOC_DAPM_ENUM_VIRT("OUT2 SW", ak7755_pmlo2_mux_enum);
++
++/* LineOut3 Mixer */
++static const struct snd_kcontrol_new ak7755_lo3sw_mixer_controls[] = {
++	SOC_DAPM_SINGLE("LOSW1", AK7755_C9_ANALOG_IO_SETTING, 1, 1, 0),
++	SOC_DAPM_SINGLE("LOSW2", AK7755_C9_ANALOG_IO_SETTING, 2, 1, 0),
++#ifndef DIGITAL_MIC		//LOSW3 used only Analog MIC
++	SOC_DAPM_SINGLE("LOSW3", AK7755_C9_ANALOG_IO_SETTING, 3, 1, 0),
++#endif
++};
++
++/* DSPIn Virt SWITCH */
++static const char *ak7755_dspinad_texts[] =
++		{"Off", "On"};
++
++static const struct soc_enum ak7755_dspinad_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak7755_dspinad_texts), ak7755_dspinad_texts);
++
++static const struct soc_enum ak7755_dspinad2_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak7755_dspinad_texts), ak7755_dspinad_texts);
++
++static const struct snd_kcontrol_new ak7755_dspinad_control =
++	SOC_DAPM_ENUM_VIRT("DSPINAD Switch", ak7755_dspinad_enum);
++
++static const struct snd_kcontrol_new ak7755_dspinad2_control =
++	SOC_DAPM_ENUM_VIRT("DSPINAD2 Switch", ak7755_dspinad2_enum);
++
++/* LIN MUX */
++static const char *ak7755_lin_select_texts[] =
++		{"IN1", "IN2", "INPN1"};
++
++static const struct soc_enum ak7755_lin_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_C9_ANALOG_IO_SETTING, 4,
++			ARRAY_SIZE(ak7755_lin_select_texts), ak7755_lin_select_texts);
++
++static const struct snd_kcontrol_new ak7755_lin_mux_control =
++	SOC_DAPM_ENUM("LIN Select", ak7755_lin_mux_enum);
++
++/* RIN MUX */
++static const char *ak7755_rin_select_texts[] =
++		{"IN3", "IN4", "INPN2"};
++
++static const struct soc_enum ak7755_rin_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_C9_ANALOG_IO_SETTING, 6,
++			ARRAY_SIZE(ak7755_rin_select_texts), ak7755_rin_select_texts);
++
++static const struct snd_kcontrol_new ak7755_rin_mux_control =
++	SOC_DAPM_ENUM("RIN Select", ak7755_rin_mux_enum);
++
++/* DAC MUX */
++static const char *ak7755_seldai_select_texts[] =
++		{"DSP", "MIXOUT", "SDIN2", "SDIN1"};
++
++static const struct soc_enum ak7755_seldai_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_C8_DAC_IN_SETTING, 6,
++			ARRAY_SIZE(ak7755_seldai_select_texts), ak7755_seldai_select_texts);
++
++static const struct snd_kcontrol_new ak7755_seldai_mux_control =
++	SOC_DAPM_ENUM("SELDAI Select", ak7755_seldai_mux_enum);
++
++/* SDOUT1 MUX */
++static const char *ak7755_seldo1_select_texts[] =
++		{"DSP", "DSP GP0", "SDIN1", "SDOUTAD", "EEST", "SDOUTAD2"};
++
++static const struct soc_enum ak7755_seldo1_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_CC_VOLUME_TRANSITION, 0,
++			ARRAY_SIZE(ak7755_seldo1_select_texts), ak7755_seldo1_select_texts);
++
++static const struct snd_kcontrol_new ak7755_seldo1_mux_control =
++	SOC_DAPM_ENUM("SELDO1 Select", ak7755_seldo1_mux_enum);
++
++/* SDOUT2 MUX */
++static const char *ak7755_seldo2_select_texts[] =
++		{"DSP", "DSP GP1", "SDIN2", "SDOUTAD2"};
++
++static const struct soc_enum ak7755_seldo2_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_C8_DAC_IN_SETTING, 2,
++			ARRAY_SIZE(ak7755_seldo2_select_texts), ak7755_seldo2_select_texts);
++
++static const struct snd_kcontrol_new ak7755_seldo2_mux_control =
++	SOC_DAPM_ENUM("SELDO2 Select", ak7755_seldo2_mux_enum);
++
++/* SDOUT3 MUX */
++static const char *ak7755_seldo3_select_texts[] =
++		{"DSP DOUT3", "MIXOUT", "DSP DOUT4", "SDOUTAD2"};
++
++static const struct soc_enum ak7755_seldo3_mux_enum =
++	SOC_ENUM_SINGLE(AK7755_C8_DAC_IN_SETTING, 4,
++			ARRAY_SIZE(ak7755_seldo3_select_texts), ak7755_seldo3_select_texts);
++
++static const struct snd_kcontrol_new ak7755_seldo3_mux_control =
++	SOC_DAPM_ENUM("SELDO3 Select", ak7755_seldo3_mux_enum);
++
++/* SELMIX Virt SWITCH */
++static const char *ak7755_selmix_select_texts[] =
++		{"Off", "On"};
++
++static const struct soc_enum ak7755_sdoutad_selmix_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak7755_selmix_select_texts), ak7755_selmix_select_texts);
++
++static const struct soc_enum ak7755_sdoutad2_selmix_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak7755_selmix_select_texts), ak7755_selmix_select_texts);
++
++static const struct soc_enum ak7755_dsp_selmix_enum =
++	SOC_ENUM_SINGLE(0, 0,
++			ARRAY_SIZE(ak7755_selmix_select_texts), ak7755_selmix_select_texts);
++
++static const struct snd_kcontrol_new ak7755_sdoutad_selmix_control =
++	SOC_DAPM_ENUM_VIRT("SELMIX Switch", ak7755_sdoutad_selmix_enum);
++
++static const struct snd_kcontrol_new ak7755_sdoutad2_selmix_control =
++	SOC_DAPM_ENUM_VIRT("SELMIX Switch", ak7755_sdoutad2_selmix_enum);
++
++static const struct snd_kcontrol_new ak7755_dsp_selmix_control =
++	SOC_DAPM_ENUM_VIRT("SELMIX Switch", ak7755_dsp_selmix_enum);
++
++
++
++/* ak7755 dapm widgets */
++static const struct snd_soc_dapm_widget ak7755_dapm_widgets[] = {
++
++// ADC, DAC
++#ifdef DIGITAL_MIC
++	SND_SOC_DAPM_INPUT("DMICIN1"),
++	SND_SOC_DAPM_INPUT("DMICIN2"),
++	SND_SOC_DAPM_ADC_E("DMIC1 Left",  "NULL", AK7755_CE_POWER_MANAGEMENT, 6, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_ADC_E("DMIC1 Right", "NULL", AK7755_CE_POWER_MANAGEMENT, 7, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_ADC_E("DMIC2 Left",  "NULL", AK7755_CE_POWER_MANAGEMENT, 5, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_ADC_E("DMIC2 Right", "NULL", AK7755_CF_RESET_POWER_SETTING, 1, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_SUPPLY("DMIC1 CLK", AK7755_DE_DMIC_IF_SETTING, 5, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("DMIC2 CLK", AK7755_DE_DMIC_IF_SETTING, 2, 0, NULL, 0),
++#else
++	SND_SOC_DAPM_ADC_E("ADC Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 6, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_ADC_E("ADC Right", "NULL", AK7755_CE_POWER_MANAGEMENT, 7, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_ADC_E("ADC2 Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 5, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++#endif
++	SND_SOC_DAPM_DAC_E("DAC Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 0, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_DAC_E("DAC Right", "NULL", AK7755_CE_POWER_MANAGEMENT, 1, 0,
++		ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
++	SND_SOC_DAPM_SUPPLY("CLOCK", AK7755_C1_CLOCK_SETTING2, 0, 0,
++		ak7755_clock_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
++
++// Analog Output
++	SND_SOC_DAPM_OUTPUT("Line Out1"),
++	SND_SOC_DAPM_OUTPUT("Line Out2"),
++	SND_SOC_DAPM_OUTPUT("Line Out3"),
++
++	SND_SOC_DAPM_MIXER("LineOut Amp3 Mixer", AK7755_CE_POWER_MANAGEMENT, 4, 0,
++			&ak7755_lo3sw_mixer_controls[0], ARRAY_SIZE(ak7755_lo3sw_mixer_controls)),
++//	SND_SOC_DAPM_MUX("LineOut Amp2", AK7755_CE_POWER_MANAGEMENT, 3, 0, &ak7755_pmlo2_mux_control),
++//	SND_SOC_DAPM_MUX("LineOut Amp1", AK7755_CE_POWER_MANAGEMENT, 2, 0, &ak7755_pmlo1_mux_control),
++
++	SND_SOC_DAPM_MUX("LineOut Amp1", SND_SOC_NOPM, 0, 0,	&ak7755_pmlo1_mux_control),
++	SND_SOC_DAPM_MUX("LineOut Amp2", SND_SOC_NOPM, 0, 0,	&ak7755_pmlo2_mux_control),
++
++// Analog Input
++	SND_SOC_DAPM_INPUT("LIN"),
++	SND_SOC_DAPM_INPUT("IN1"),
++	SND_SOC_DAPM_INPUT("IN2"),
++	SND_SOC_DAPM_INPUT("IN3"),
++	SND_SOC_DAPM_INPUT("IN4"),
++	SND_SOC_DAPM_INPUT("INPN1"),
++	SND_SOC_DAPM_INPUT("INPN2"),
++
++	SND_SOC_DAPM_PGA("LineIn Amp", AK7755_CF_RESET_POWER_SETTING, 5, 0, NULL, 0),
++	SND_SOC_DAPM_MUX("RIN MUX", SND_SOC_NOPM, 0, 0,	&ak7755_rin_mux_control),
++	SND_SOC_DAPM_MUX("LIN MUX", SND_SOC_NOPM, 0, 0,	&ak7755_lin_mux_control),
++	SND_SOC_DAPM_VIRT_MUX("DSPIN SDOUTAD2", SND_SOC_NOPM, 0, 0, &ak7755_dspinad2_control),
++	SND_SOC_DAPM_VIRT_MUX("DSPIN SDOUTAD", SND_SOC_NOPM, 0, 0, &ak7755_dspinad_control),
++
++// Digital Input/Output
++	SND_SOC_DAPM_AIF_IN("SDIN1", "Playback", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_IN("SDIN2", "Playback", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_OUT("SDOUT1", "Capture", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_OUT("SDOUT2", "Capture", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_OUT("SDOUT3", "Capture", 0, SND_SOC_NOPM, 0, 0),
++
++	SND_SOC_DAPM_SWITCH("SDOUT3 Enable", SND_SOC_NOPM, 0, 0,
++		&ak7755_out3e_control),
++	SND_SOC_DAPM_SWITCH("SDOUT2 Enable", SND_SOC_NOPM, 0, 0,
++		&ak7755_out2e_control),
++	SND_SOC_DAPM_SWITCH("SDOUT1 Enable", SND_SOC_NOPM, 0, 0,
++		&ak7755_out1e_control),
++
++	SND_SOC_DAPM_PGA("SDOUTAD", SND_SOC_NOPM, 0, 0, NULL, 0),		//ADC's Output
++	SND_SOC_DAPM_PGA("SDOUTAD2", SND_SOC_NOPM, 0, 0, NULL, 0),		//ADC2's Output
++	SND_SOC_DAPM_PGA("DSP", AK7755_CF_RESET_POWER_SETTING, 2, 0, NULL, 0),
++
++	SND_SOC_DAPM_AIF_IN("DSP GP0", NULL, 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_IN("DSP GP1", NULL, 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_IN("EEST", NULL, 0, SND_SOC_NOPM, 0, 0),
++
++// Multiplexer (selects 1 analog signal from many inputs) & Mixer
++	SND_SOC_DAPM_MUX("SDOUT3 MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldo3_mux_control),
++	SND_SOC_DAPM_MUX("SDOUT2 MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldo2_mux_control),
++	SND_SOC_DAPM_MUX("SDOUT1 MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldo1_mux_control),
++	SND_SOC_DAPM_MUX("DAC MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldai_mux_control),
++	SND_SOC_DAPM_VIRT_MUX("SELMIX DSP", SND_SOC_NOPM, 0, 0, &ak7755_dsp_selmix_control),
++	SND_SOC_DAPM_VIRT_MUX("SELMIX AD2", SND_SOC_NOPM, 0, 0, &ak7755_sdoutad2_selmix_control),
++	SND_SOC_DAPM_VIRT_MUX("SELMIX AD", SND_SOC_NOPM, 0, 0, &ak7755_sdoutad_selmix_control),
++	SND_SOC_DAPM_PGA("SELMIX Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++};
++
++static const struct snd_soc_dapm_route ak7755_intercon[] =
++{
++
++#ifdef DIGITAL_MIC
++	{"DMIC1 Left", "NULL", "CLOCK"},
++	{"DMIC1 Right", "NULL", "CLOCK"},
++	{"DMIC2 Left", "NULL", "CLOCK"},
++	{"DMIC2 Right", "NULL", "CLOCK"},
++
++	{"DMICIN1", "NULL", "DMIC1 CLK"},
++	{"DMICIN2", "NULL", "DMIC2 CLK"},
++	{"DMIC1 Left", "NULL", "DMICIN1"},
++	{"DMIC1 Right", "NULL", "DMICIN1"},
++	{"DMIC2 Left", "NULL", "DMICIN2"},
++	{"DMIC2 Right", "NULL", "DMICIN2"},
++	{"SDOUTAD", "NULL", "DMIC1 Left"},
++	{"SDOUTAD", "NULL", "DMIC1 Right"},
++	{"SDOUTAD2", "NULL", "DMIC2 Left"},
++	{"SDOUTAD2", "NULL", "DMIC2 Right"},
++#else
++	{"ADC Left", "NULL", "CLOCK"},
++	{"ADC Right", "NULL", "CLOCK"},
++	{"ADC2 Left", "NULL", "CLOCK"},
++
++	{"LineIn Amp", "NULL", "LIN"},
++	{"ADC2 Left", "NULL", "LineIn Amp"},
++	{"SDOUTAD2", "NULL", "ADC2 Left"},
++
++	{"LIN MUX", "IN1", "IN1"},
++	{"LIN MUX", "IN2", "IN2"},
++	{"LIN MUX", "INPN1", "INPN1"},
++	{"RIN MUX", "IN3", "IN3"},
++	{"RIN MUX", "IN4", "IN4"},
++	{"RIN MUX", "INPN2", "INPN2"},
++	{"ADC Left", "NULL", "LIN MUX"},
++	{"ADC Right", "NULL", "RIN MUX"},
++	{"SDOUTAD", "NULL", "ADC Left"},
++	{"SDOUTAD", "NULL", "ADC Right"},
++#endif
++
++	{"DAC Left", "NULL", "CLOCK"},
++	{"DAC Right", "NULL", "CLOCK"},
++	{"DSP", "NULL", "CLOCK"},
++
++	{"DSP", "NULL", "SDIN1"},
++	{"DSP", "NULL", "SDIN2"},
++
++	{"DSPIN SDOUTAD", "On", "SDOUTAD"},
++	{"DSPIN SDOUTAD2", "On", "SDOUTAD2"},
++	{"DSP", "NULL", "DSPIN SDOUTAD"},
++	{"DSP", "NULL", "DSPIN SDOUTAD2"},
++
++	{"SELMIX AD", "On", "SDOUTAD"},
++	{"SELMIX AD2", "On", "SDOUTAD2"},
++	{"SELMIX DSP", "On", "DSP"},
++	{"SELMIX Mixer", "NULL", "SELMIX AD"},
++	{"SELMIX Mixer", "NULL", "SELMIX AD2"},
++	{"SELMIX Mixer", "NULL", "SELMIX DSP"},
++	{"DAC MUX", "MIXOUT", "SELMIX Mixer"},
++	{"DAC MUX", "DSP", "DSP"},
++	{"DAC MUX", "SDIN2", "SDIN2"},
++	{"DAC MUX", "SDIN1", "SDIN1"},
++
++	{"DAC Left", "NULL", "DAC MUX"},
++	{"DAC Right", "NULL", "DAC MUX"},
++
++	{"LineOut Amp1", "On", "DAC Left"},
++	{"LineOut Amp2", "On", "DAC Right"},
++	{"Line Out1", "NULL", "LineOut Amp1"},
++	{"Line Out2", "NULL", "LineOut Amp2"},
++	{"LineOut Amp3 Mixer", "LOSW1", "DAC Left"},
++	{"LineOut Amp3 Mixer", "LOSW2", "DAC Right"},
++#ifndef DIGITAL_MIC		//LOSW3 used only Analog MIC
++	{"LineOut Amp3 Mixer", "LOSW3", "LineIn Amp"},
++#endif
++	{"Line Out3", "NULL", "LineOut Amp3 Mixer"},
++
++	{"SDOUT1 MUX", "DSP", "DSP"},
++	{"SDOUT1 MUX", "DSP GP0", "DSP GP0"},
++	{"SDOUT1 MUX", "SDIN1", "SDIN1"},
++	{"SDOUT1 MUX", "SDOUTAD", "SDOUTAD"},
++	{"SDOUT1 MUX", "EEST", "EEST"},
++	{"SDOUT1 MUX", "SDOUTAD2", "SDOUTAD2"},
++
++	{"SDOUT2 MUX", "DSP", "DSP"},
++	{"SDOUT2 MUX", "DSP GP1", "DSP GP1"},
++	{"SDOUT2 MUX", "SDIN2", "SDIN2"},
++	{"SDOUT2 MUX", "SDOUTAD2", "SDOUTAD2"},
++
++	{"SDOUT3 MUX", "DSP DOUT3", "DSP"},
++	{"SDOUT3 MUX", "MIXOUT", "DAC MUX"},
++	{"SDOUT3 MUX", "DSP DOUT4", "DSP"},
++	{"SDOUT3 MUX", "SDOUTAD2", "SDOUTAD2"},
++
++	{"SDOUT1 Enable", "Switch", "SDOUT1 MUX"},
++	{"SDOUT2 Enable", "Switch", "SDOUT2 MUX"},
++	{"SDOUT3 Enable", "Switch", "SDOUT3 MUX"},
++
++	{"SDOUT1", "NULL", "SDOUT1 Enable"},
++	{"SDOUT2", "NULL", "SDOUT2 Enable"},
++	{"SDOUT3", "NULL", "SDOUT3 Enable"},
++
++};
++
++static int ak7755_hw_params_set(struct snd_soc_codec *codec, int nfs)
++{
++	u8 	fs;
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	fs = snd_soc_read(codec, AK7755_C0_CLOCK_SETTING1);
++	fs &= ~AK7755_FS;
++
++	switch (nfs) {
++	case 8000:
++		fs |= AK7755_FS_8KHZ;
++		break;
++	case 11025:
++		fs |= AK7755_FS_12KHZ;
++		break;
++	case 16000:
++		fs |= AK7755_FS_16KHZ;
++		break;
++	case 22050:
++		fs |= AK7755_FS_24KHZ;
++		break;
++	case 32000:
++		fs |= AK7755_FS_32KHZ;
++		break;
++	case 44100:
++	case 48000:
++		fs |= AK7755_FS_48KHZ;
++		break;
++	case 88200:
++	case 96000:
++		fs |= AK7755_FS_96KHZ;
++		break;
++	default:
++		return -EINVAL;
++	}
++	snd_soc_write(codec, AK7755_C0_CLOCK_SETTING1, fs);
++	ak7755_set_status(RUN);
++	if (aec == 1){
++		snd_soc_update_bits(codec, AK7755_CE_POWER_MANAGEMENT, 0x80, 0x0);		//If aec is enable, only CH-L enable by DSP
++	}
++
++	return 0;
++}
++
++static int ak7755_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++	u8 format;
++
++	format = snd_soc_read(codec, AK7755_C2_SERIAL_DATA_FORMAT);
++	format &= ~AK7755_LRIF;
++	if (aec ==0){
++		switch (params_format(params)) {
++			case SNDRV_PCM_FORMAT_S16_LE:
++				ak7755->bickfs = (AK7755_AIF_BICK32 >> 4);
++				break;
++			case SNDRV_PCM_FORMAT_S24_LE:
++				ak7755->bickfs = (AK7755_AIF_BICK48 >> 4);
++				break;
++			case SNDRV_PCM_FORMAT_S32_LE:
++				ak7755->bickfs = (AK7755_AIF_BICK64 >> 4);
++				break;
++			default:
++				dev_err(codec->dev, "Can not support the format");
++				return -EINVAL;
++		}
++	}else{
++		ak7755->bickfs = (AK7755_AIF_BICK64 >> 4);
++	}
++	ak7755->fs = params_rate(params);
++	ak7755_hw_params_set(codec, ak7755->fs);
++
++	snd_soc_update_bits(codec, AK7755_C1_CLOCK_SETTING2, 0x30, (ak7755->bickfs << 4));
++	if ( ak7755->bickfs < 3 ) {
++		format &= 0x7F;
++	} else {
++		format |= 0x80;
++		format &= 0xF3;
++		format |=  AK7755_TDM_INPUT_SOURCE;
++	}
++
++	switch (ak7755->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		format |= AK7755_LRIF_I2S_MODE;
++		if ( ak7755->bickfs == 2 ) {   // 32fs
++			snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0xf0); 	// DIF2, DOF2
++			snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x33);		//DIF, DIFDA
++			snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0xf3); 		//DOF
++		}else {
++			snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0x0); 	// DIF2, DOF2
++			snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x0);	//DIF, DIFDA
++			snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0x0); 	//DOF
++		}
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		format |= AK7755_LRIF_MSB_MODE;
++		if ( ak7755->bickfs == 2 ) {   // 32fs
++			snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0xF0); 	// DIF2, DOF2
++			snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x33);	//DIF, DIFDA
++			snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0xF3); 	//DOF
++		}
++		else {
++			snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0x0); 	// DIF2, DOF2
++			snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x0);	//DIF, DIFDA
++			snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0x0); 	//DOF
++		}
++		break;
++/*
++	case SND_SOC_DAIFMT_PCM_SHORT:
++		format &= 0xBF;							//BCKP Clear
++		format |= (AK7755_BCKP_BIT << 6);		//BCKP set
++		format |= AK7755_LRIF_PCM_SHORT_MODE;
++		break;
++	case SND_SOC_DAIFMT_PCM_LONG:
++		format &= 0xBF;							//BCKP lear
++		format |= (AK7755_BCKP_BIT << 6);		//BCKP set
++		format |= AK7755_LRIF_PCM_LONG_MODE;
++		break;
++*/
++	default:
++		return -EINVAL;
++	}
++
++	snd_soc_write(codec, AK7755_C2_SERIAL_DATA_FORMAT, format);
++	return 0;
++}
++
++static int ak7755_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
++		unsigned int freq, int dir)
++{
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak7755_data->rclk = freq;
++
++	return 0;
++}
++
++static int ak7755_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++
++	struct snd_soc_codec *codec = dai->codec;
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);  // '15/06/15
++	u8 mode, mode2;
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	/* set master/slave audio interface */
++	mode = snd_soc_read(codec, AK7755_C0_CLOCK_SETTING1);//CKM2-0(M/S)
++	mode &= ~AK7755_M_S;
++	mode2 = snd_soc_read(codec, AK7755_CA_CLK_SDOUT_SETTING);//BICKOE,LRCKOE
++
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++        case SND_SOC_DAIFMT_CBS_CFS:
++	#ifdef CLOCK_MODE_BICK
++	    	mode |= AK7755_M_S_3;//CKM mode = 3(Slave, BICK)
++	#else
++	    	mode |= AK7755_M_S_2;//CKM mode = 2(Slave, XTI=12.288MHz)
++	#endif
++          	mode2 &= ~AK7755_BICK_LRCK;//BICK = LRCK = 0
++            break;
++        case SND_SOC_DAIFMT_CBM_CFM:
++	#ifdef CLOCK_MODE_18_432
++	    	mode |= AK7755_M_S_1;//CKM mode = 1(Master, XTI=18.432MHz)
++	#else
++	    	mode |= AK7755_M_S_0;//CKM mode = 0(Master, XTI=12.288MHz)
++	#endif
++		mode2 |= AK7755_BICK_LRCK;//BICK = LRCK = 1
++            break;
++        case SND_SOC_DAIFMT_CBS_CFM:
++        case SND_SOC_DAIFMT_CBM_CFS:
++        default:
++            dev_err(codec->dev, "Clock mode unsupported");
++           return -EINVAL;
++	}
++
++	ak7755->fmt = fmt;
++	/* set mode */
++	snd_soc_write(codec, AK7755_C0_CLOCK_SETTING1, mode);
++	snd_soc_write(codec, AK7755_CA_CLK_SDOUT_SETTING, mode2);
++	return 0;
++}
++
++static int ak7755_volatile(struct snd_soc_codec *codec, unsigned int reg)
++{
++	int	ret;
++
++	switch (reg) {
++//		case :
++//			ret = 1;
++		default:
++			ret = 0;
++			break;
++	}
++	return ret;
++}
++
++static int ak7755_readable(struct snd_soc_codec *codec, unsigned int reg)
++{
++	return ak7755_access_masks[reg].readable != 0;
++
++}
++
++static int ak7755_reads(u8 *tx, size_t wlen, u8 *rx, size_t rlen)
++{
++	int ret;
++
++	//akdbgprt("*****[AK7755] %s tx[0]=%x, %d, %d\n",__FUNCTION__, tx[0],wlen,rlen);
++	if (ak7755_data->control_type == SND_SOC_SPI) {
++		ret = spi_write_then_read(ak7755_data->spi, tx, wlen, rx, rlen);
++	}
++	else {
++		ret = ak7755_i2c_read( tx, wlen, rx, rlen);
++	}
++
++	return ret;
++
++}
++
++static int ak7755_writes(const u8 *tx, size_t wlen)
++{
++	int rc;
++
++	akdbgprt("![AK7755W] %s tx[0]=%x tx[1]=%x, len=%d\n",__FUNCTION__, (int)tx[0], (int)tx[1], wlen);
++
++	if (ak7755_data->control_type == SND_SOC_SPI)
++		rc = spi_write_then_read(ak7755_data->spi, tx, wlen, NULL, 0);
++	else
++		rc = i2c_master_send(ak7755_data->i2c, tx, wlen);
++
++	if (rc < 0) {
++		akdbgprt("\t[AK7755] %s error rc = %d\n",__FUNCTION__, rc);
++	}
++
++	return rc;
++}
++
++#ifdef AK7755_CONTIF_DEBUG
++static inline void ak7755_write_reg_cache(struct snd_soc_codec *codec,u16 reg,u16 value)
++{
++    u8 *cache = codec->reg_cache;
++    //BUG_ON(reg_index > ARRAY_SIZE(ak7755_reg));
++
++    if (reg < ARRAY_SIZE(ak7755_reg))
++    	cache[reg] = (u8)value;
++}
++
++/*
++* Read ak7755 register cache
++ */
++static inline u32 ak7755_read_reg_cache(struct snd_soc_codec *codec, u16 reg)
++{
++    u8 *cache = codec->reg_cache;
++    BUG_ON(reg > ARRAY_SIZE(ak7755_reg));
++    return (u32)cache[reg];
++}
++
++
++static unsigned int ak7755_i2c_read(
++u8 *reg,
++int reglen,
++u8 *data,
++int datalen)
++{
++	struct i2c_msg xfer[2];
++	int ret;
++	struct i2c_client *client = ak7755_data->i2c;
++
++	/* Write register */
++	xfer[0].addr = client->addr;
++	xfer[0].flags = 0;
++	xfer[0].len = reglen;
++	xfer[0].buf = reg;
++
++	/* Read data */
++	xfer[1].addr = client->addr;
++	xfer[1].flags = I2C_M_RD;
++	xfer[1].len = datalen;
++	xfer[1].buf = data;
++
++	ret = i2c_transfer(client->adapter, xfer, 2);
++
++//	akdbgprt("*****[AK7755] %s (%x,%x)\n",__FUNCTION__, (int)reg[0], (int)data[0]);
++
++	if (ret == 2)
++		return 0;
++	else if (ret < 0)
++		return -ret;
++	else
++		return -EIO;
++}
++
++unsigned int ak7755_reg_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++	unsigned char tx[1], rx[1];
++	int	wlen, rlen;
++	int ret;
++	unsigned int rdata;
++
++	wlen = 1;
++	rlen = 1;
++	tx[0] = (unsigned char)(0x7F & reg);
++
++	//akdbgprt("*****[AK7755] %s reg = %0x, tx[0]=%0x, %d, %d\n",__FUNCTION__, reg,  tx[0],wlen,rlen);
++
++	if (ak7755_data->control_type == SND_SOC_SPI) {
++		ret = spi_write_then_read(ak7755_data->spi, tx, wlen, rx, rlen);
++	}
++	else {
++		ret = ak7755_i2c_read(tx, wlen, rx, rlen);
++	}
++
++	if (ret < 0) {
++		akdbgprt("\t[AK7755] %s error ret = %d\n",__FUNCTION__, ret);
++		rdata = -EIO;
++		return rdata;
++	}
++	else {
++		rdata = (unsigned int)rx[0];
++		if (ak7755_read_reg_cache(codec, reg) != rdata)
++			ak7755_write_reg_cache(codec, reg, rdata);
++	}
++	akdbgprt("\t[AK7755] %s addr, read data =(%x, %x)\n",__FUNCTION__, reg, (int)rdata);
++
++	return rdata;
++}
++
++
++int ak7755_reg_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
++{
++	unsigned char tx[3];
++	int	wlen;
++	int ret;
++
++	wlen = 2;
++	tx[0] = reg;
++	tx[1] = value;
++
++	ret = ak7755_writes(tx, wlen);
++
++	if (ret >=0) {
++		ak7755_write_reg_cache(codec, reg, value);
++	}
++
++	return ret;
++}
++
++
++/*
++ * Write with Mask to  AK7755 register space
++ */
++// ak7755_writeMask() => snd_soc_update_bits()  // '16/01/13
++
++#endif
++
++
++static int crc_read(void)
++{
++	int rc;
++	u8	tx[1], rx[2];
++
++	tx[0] = CRC_COMMAND_READ_RESULT;
++
++	rc =  ak7755_reads(tx, 1, rx, 2);
++
++	return (rc < 0) ? rc : ((rx[0] << 8) + rx[1]);
++}
++
++static int ak7755_set_status(enum ak7755_status status)
++{
++
++	switch (status) {
++	case RUN:
++		snd_soc_update_bits(ak7755_data->codec, AK7755_C1_CLOCK_SETTING2, 0x1, 0x1);  // CKRESETN bit = 1
++		mdelay(10);
++		snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0xd, 0xc);  // CRESETN bit = DSPRESETN = 1;
++		mdelay(10);
++		break;
++	case DOWNLOAD:
++		snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x1, 0x1);  // DLRDY bit = 1
++		mdelay(10);
++		break;
++	case STANDBY:
++		snd_soc_update_bits(ak7755_data->codec, AK7755_C1_CLOCK_SETTING2, 0x1, 0x1);  // CKRESETN bit = 1
++		mdelay(10);
++		snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0xc, 0x0);  // CRESETN bit = DSPRESETN = 0;
++		mdelay(10);
++		break;
++	case SUSPEND:
++	case POWERDOWN:
++		snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x3f, 0x0);
++		snd_soc_update_bits(ak7755_data->codec, AK7755_CE_POWER_MANAGEMENT, 0xFF, 0x0);
++		snd_soc_update_bits(ak7755_data->codec, AK7755_C1_CLOCK_SETTING2, 0x0, 0x0);
++		mdelay(10);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	ak7755_data->status = status;
++
++	return 0;
++}
++
++static int ak7755_ram_download(const u8 *tx_ram, u64 num, u16 crc)
++{
++	int rc;
++	u16	read_crc;
++	u8 tx[2];
++
++	akdbgprt("\t[AK7755] %s num=%ld\n",__FUNCTION__, (long int)num);
++	if (fast_boot == 0)
++		ak7755_set_status(DOWNLOAD);
++
++	rc = ak7755_writes(tx_ram, num);
++	if (rc < 0) {
++		printk("%s: RAM Write Error! RAM size = %lld \n", __func__, num);
++		if ( fast_boot == 1 ) {
++			tx[0] = AK7755_CF_RESET_POWER_SETTING;
++			tx[1] = 0x0c;
++			ak7755_writes(tx, 2);
++		} else {
++			snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x0d,0x0c);  // system rest release
++		}
++		return rc;
++	}
++
++	if ( ( crc != 0 ) && (rc >= 0) )  {
++		read_crc = crc_read();
++		akdbgprt("\t[AK7755] %s CRC Cal=%x Read=%x\n",__FUNCTION__, (int)crc,(int)read_crc);
++
++		if ( read_crc == crc ) rc = 0;
++		else rc = 1;
++	}
++	if ( fast_boot == 0 )
++		ak7755_set_status(STANDBY);
++
++	return rc;
++
++}
++
++static int calc_CRC(int length, u8 *data )
++{
++
++#define CRC16_CCITT (0x1021)
++
++	unsigned short crc = 0x0000;
++	int i, j;
++
++	for ( i = 0; i < length; i++ ) {
++		crc ^= *data++ << 8;
++		for ( j = 0; j < 8; j++) {
++			if ( crc & 0x8000) {
++				crc <<= 1;
++				crc ^= CRC16_CCITT;
++			}
++			else {
++				crc <<= 1;
++			}
++		}
++	}
++
++	akdbgprt("[AK7755] %s CRC=%x\n",__FUNCTION__, crc);
++
++	return crc;
++}
++
++static int ak7755_write_ram(
++int	 nPCRam,  // 0 : PRAM, 1 : CRAM, 2:  OFREG. 3: ACRAM
++u8 	*upRam,
++int	 nWSize)
++{
++	int n, ret;
++	int	wCRC;
++
++	switch(nPCRam) {
++		case RAMTYPE_PRAM:
++			if (  nWSize > TOTAL_NUM_OF_PRAM_MAX ) {
++				printk("%s: PRAM Write size is over! \n", __func__);
++				return(-1);
++			}
++			break;
++		case RAMTYPE_CRAM:
++			if (  nWSize > TOTAL_NUM_OF_CRAM_MAX ) {
++				printk("%s: CRAM Write size is over! \n", __func__);
++				return(-1);
++			}
++			break;
++		case RAMTYPE_OFREG:
++			if (  nWSize > TOTAL_NUM_OF_OFREG_MAX ) {
++				printk("%s: OFREG Write size is over! \n", __func__);
++				return(-1);
++			}
++			break;
++		case RAMTYPE_ACRAM:
++			if (  nWSize > TOTAL_NUM_OF_ACRAM_MAX ) {
++				printk("%s: ACRAM Write size is over! \n", __func__);
++				return(-1);
++			}
++			break;
++		default:
++			break;
++	}
++
++	wCRC = calc_CRC(nWSize, upRam);
++
++	n = MAX_LOOP_TIMES;
++	do {
++		ret = ak7755_ram_download(upRam, nWSize, wCRC);
++		if ( ret >= 0 ) break;
++		printk("%s: RAM Write Error! RAM No = %d \n", __func__, nPCRam);
++		n--;
++	} while ( n > 0 );
++
++	if ( ret < 0 ) {
++		printk("%s: RAM Write Error! RAM No = %d \n", __func__, nPCRam);
++		return(-1);
++	}
++
++	return(0);
++
++}
++
++static int ak7755_firmware_write_ram(u16 mode, u16 cmd)
++{
++	int ret = 0;
++	int nNumMode, nMaxLen;
++	int nRamSize;
++	u8  *ram_basic;
++	const struct firmware *fw;
++	u8  *fwdn;
++	char szFileName[32];
++
++	akdbgprt("[AK7755] %s mode=%d, cmd=%d\n",__FUNCTION__, mode, cmd);
++
++	switch(mode) {
++		case RAMTYPE_PRAM:
++			nNumMode = sizeof(ak7755_firmware_pram) / sizeof(ak7755_firmware_pram[0]);
++			break;
++		case RAMTYPE_CRAM:
++			nNumMode = sizeof(ak7755_firmware_cram) / sizeof(ak7755_firmware_cram[0]);
++			break;
++		case RAMTYPE_OFREG:
++			nNumMode = sizeof(ak7755_firmware_ofreg) / sizeof(ak7755_firmware_ofreg[0]);
++			break;
++		case RAMTYPE_ACRAM:
++			nNumMode = sizeof(ak7755_firmware_acram) / sizeof(ak7755_firmware_acram[0]);
++			break;
++		default:
++			akdbgprt("[AK7755] %s mode Error=%d\n",__FUNCTION__, mode);
++			return( -EINVAL);
++	}
++
++	if ( cmd == 0 ) return(0);
++
++	if ( cmd >= nNumMode ) {
++		pr_err("%s: invalid command %d\n", __func__, cmd);
++		return( -EINVAL);
++	}
++
++	if ( cmd == 1 ) {
++		switch(mode) {
++			case RAMTYPE_PRAM:
++				if (aec == 0){
++					ram_basic = ak7755_pram_basic;
++					nRamSize = sizeof(ak7755_pram_basic);
++				}else{
++					ram_basic = ak7755_pram_aec;
++					nRamSize = sizeof(ak7755_pram_aec);
++				}
++				break;
++			case RAMTYPE_CRAM:
++				if (aec == 0){
++					ram_basic = ak7755_cram_basic;
++					nRamSize = sizeof(ak7755_cram_basic);
++				}else{
++					ram_basic = ak7755_cram_aec;
++					nRamSize = sizeof(ak7755_cram_aec);
++				}
++				break;
++			case RAMTYPE_OFREG:
++				ram_basic = ak7755_ofreg_basic;
++				nRamSize = sizeof(ak7755_ofreg_basic);
++				break;
++			case RAMTYPE_ACRAM:
++				ram_basic = ak7755_acram_basic;
++				nRamSize = sizeof(ak7755_acram_basic);
++				break;
++			default:
++				return( -EINVAL);
++		}
++		ret = ak7755_write_ram((int)mode, ram_basic, nRamSize);
++	} else {
++		switch(mode) {
++			case RAMTYPE_PRAM:
++				sprintf(szFileName, "ak7755_pram_%s.bin", ak7755_firmware_pram[cmd]);
++				nMaxLen = TOTAL_NUM_OF_PRAM_MAX;
++				break;
++			case RAMTYPE_CRAM:
++				sprintf(szFileName, "ak7755_cram_%s.bin", ak7755_firmware_cram[cmd]);
++				nMaxLen = TOTAL_NUM_OF_CRAM_MAX;
++				break;
++			case RAMTYPE_OFREG:
++				sprintf(szFileName, "ak7755_ofreg_%s.bin", ak7755_firmware_cram[cmd]);
++				nMaxLen = TOTAL_NUM_OF_OFREG_MAX;
++				break;
++			case RAMTYPE_ACRAM:
++				sprintf(szFileName, "ak7755_acram_%s.bin", ak7755_firmware_cram[cmd]);
++				nMaxLen = TOTAL_NUM_OF_ACRAM_MAX;
++				break;
++			default:
++				return( -EINVAL);
++		}
++
++		if (ak7755_data->control_type == SND_SOC_SPI) {
++			ret = request_firmware(&fw, szFileName, &(ak7755_data->spi->dev));
++		}
++		else {
++			ret = request_firmware(&fw, szFileName, &(ak7755_data->i2c->dev));
++		}
++		if (ret) {
++			akdbgprt("[AK7755] %s could not load firmware=%d\n", szFileName, ret);
++			return -EINVAL;
++		}
++
++		//printk("[AK7755] %s name=%s size=%d\n",__FUNCTION__, szFileName, fw->size);
++		if ( fw->size > nMaxLen ) {
++			akdbgprt("[AK7755] %s RAM Size Error : %d\n",__FUNCTION__, fw->size);
++			return -ENOMEM;
++		}
++
++		fwdn = kmalloc((unsigned long)fw->size, GFP_KERNEL);
++		if (fwdn == NULL) {
++			printk(KERN_ERR "failed to buffer vmalloc: %d\n", fw->size);
++			return -ENOMEM;
++		}
++
++		memcpy((void *)fwdn, fw->data, fw->size);
++
++		ret = ak7755_write_ram((int)mode, (u8 *)fwdn, (fw->size));
++		//printk("ak7755 download ram is ok, ret = %d\n", ret);
++
++		kfree(fwdn);
++	}
++
++
++	return ret;
++}
++
++static int ak7755_write_cram(
++int addr,
++int len,
++unsigned char *cram_data)
++{
++	int i, n, ret;
++	int nDSPRun;
++	unsigned char tx[51];
++
++	akdbgprt("[AK7755] %s addr=%d, len=%d\n",__FUNCTION__, addr, len);
++
++	if ( len > 48 ) {
++		akdbgprt("[AK7755] %s Length over!\n",__FUNCTION__);
++		return(-1);
++	}
++
++	nDSPRun = snd_soc_read(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING);
++
++	if ( nDSPRun & 0x4 ) {
++		tx[0] = 0x80 + (unsigned char)((len / 3) - 1);
++		tx[1] = (unsigned char)(0xFF & (addr >> 8));
++		tx[2] = (unsigned char)(0xFF & addr);
++	}
++	else {
++		ak7755_set_status(DOWNLOAD);
++		tx[0] = 0xB4;
++		tx[1] = (unsigned char)(0xFF & (addr >> 8));
++		tx[2] = (unsigned char)(0xFF & addr);
++	}
++
++	n = 3;
++	for ( i = 0 ; i < len; i ++ ) {
++		tx[n++] = cram_data[i];
++	}
++
++	ret = ak7755_writes(tx, n);
++
++	if ( nDSPRun & 0x4 ) {
++		tx[0] = 0xA4;
++		tx[1] = 0;
++		tx[2] = 0;
++		ret = ak7755_writes(tx, 3);
++	}
++	else {
++		snd_soc_write(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, nDSPRun);
++	}
++
++
++	return ret;
++
++}
++
++static unsigned long ak7755_readMIR(
++int nMIRNo)
++{
++	unsigned char tx[1];
++	unsigned char rx[4];
++	unsigned long dwMIRData;
++
++	if ( ( nMIRNo < 1 )  ||  ( nMIRNo > 4 ) ) return(-1);
++
++	tx[0] = (unsigned char)(0x74 + (2 * nMIRNo));
++
++	ak7755_reads(tx, 1, rx, 4);
++
++	dwMIRData = ((0xFF & (unsigned long)rx[0]) << 20) + ((0xFF & (unsigned long)rx[1]) << 12) +
++                       ((0xFF & (unsigned long)rx[2]) << 4) + ((0xFF & (unsigned long)rx[3]) >> 4);
++
++
++	return(dwMIRData);
++
++}
++
++static int ak7755_reg_cmd(REG_CMD *reg_param, int len)
++{
++	int i;
++	int rc;
++	int  addr, value;
++
++	akdbgprt("*****[AK7755] %s len = %d\n",__FUNCTION__, len);
++
++	rc = 0;
++	for (i = 0; i < len; i++) {
++		addr = (int)(reg_param[i].addr);
++		value = (int)(reg_param[i].data);
++
++		if ( addr != 0xFF ) {
++			rc = snd_soc_write(ak7755_data->codec, addr, value);
++			if (rc < 0) {
++				break;
++			}
++		}
++		else {
++			mdelay(value);
++		}
++	}
++
++	if (rc != 0 ) rc = 0;
++
++	return(rc);
++
++}
++
++#ifdef AK7755_IO_CONTROL
++static long ak7755_ioctl(struct file *file, unsigned int cmd, unsigned long args)
++{
++	struct ak7755_priv *ak7755 = (struct ak7755_priv*)file->private_data;
++	struct ak7755_wreg_handle ak7755_wreg;
++	struct ak7755_wcram_handle  ak7755_wcram;
++	struct ak7755_loadram_handle  ak7755_ram;
++	void __user *data = (void __user *)args;
++	int *val = (int *)args;
++	int i;
++	unsigned long dwMIRData;
++	int ret = 0;
++	REG_CMD      regcmd[MAX_WREG];
++	unsigned char cram_data[MAX_WCRAM];
++
++	akdbgprt("*****[AK7755] %s cmd, val=%x, %x\n",__FUNCTION__, cmd, val[0]);
++
++	switch(cmd) {
++	case AK7755_IOCTL_WRITECRAM:
++		if (copy_from_user(&ak7755_wcram, data, sizeof(struct ak7755_wcram_handle)))
++			return -EFAULT;
++		if ( (  ak7755_wcram.len % 3 ) != 0 ) {
++			printk(KERN_ERR "[AK7755] %s CRAM len error\n",__FUNCTION__);
++			return -EFAULT;
++		}
++		if ( ( ak7755_wcram.len < 3 ) || ( ak7755_wcram.len > MAX_WCRAM ) ) {
++			printk(KERN_ERR "[AK7755] %s CRAM len error2\n",__FUNCTION__);
++			return -EFAULT;
++		}
++		for ( i = 0 ; i < ak7755_wcram.len ; i ++ ) {
++			cram_data[i] = ak7755_wcram.cram[i];
++		}
++		ret = ak7755_write_cram(ak7755_wcram.addr, ak7755_wcram.len, cram_data);
++		break;
++	case AK7755_IOCTL_WRITEREG:
++		if (copy_from_user(&ak7755_wreg, data, sizeof(struct ak7755_wreg_handle)))
++			return -EFAULT;
++		if ( ( ak7755_wreg.len < 1 ) || ( ak7755_wreg.len > MAX_WREG ) ) {
++			printk(KERN_ERR "MAXREG ERROR %d\n", ak7755_wreg.len );
++			return -EFAULT;
++		}
++		for ( i = 0 ; i < ak7755_wreg.len; i ++ ) {
++			regcmd[i].addr = ak7755_wreg.regcmd[i].addr;
++			regcmd[i].data = ak7755_wreg.regcmd[i].data;
++		}
++		ak7755_reg_cmd(regcmd, ak7755_wreg.len);
++		break;
++	case AK7755_IOCTL_LOADRAM:
++		if (copy_from_user(&ak7755_ram, data, sizeof(struct ak7755_loadram_handle)))
++			return -EFAULT;
++		ak7755_firmware_write_ram(ak7755_ram.ramtype, ak7755_ram.mode);
++		break;
++	case AK7755_IOCTL_SETSTATUS:
++		ret = ak7755_set_status(val[0]);
++		if (ret < 0) {
++			printk(KERN_ERR "ak7755: set_status error: \n");
++			return ret;
++		}
++		break;
++	case AK7755_IOCTL_GETSTATUS:
++		ret = copy_to_user(data, (const void*)&ak7755->status,
++							(unsigned long)sizeof(unsigned int));
++		if (ret < 0) {
++			printk(KERN_ERR "ak7755: get status error\n");
++			return -EFAULT;
++		}
++		break;
++	case AK7755_IOCTL_SETMIR:
++		ak7755->MIRNo = val[0];
++		if (ret < 0) {
++			printk(KERN_ERR "ak7755: set MIR error\n");
++			return -EFAULT;
++		}
++		break;
++	case AK7755_IOCTL_GETMIR:
++		dwMIRData = ak7755_readMIR(ak7755->MIRNo);
++		ret = copy_to_user(data, (const void*)&dwMIRData,
++							(unsigned long)sizeof(unsigned int));
++		if (ret < 0) {
++			printk(KERN_ERR "ak7755: get status error\n");
++			return -EFAULT;
++		}
++		break;
++
++	default:
++		printk(KERN_ERR "Unknown command required: %d\n", cmd);
++		return -EINVAL;
++	}
++
++	return ret;
++}
++
++static int init_ak7755_pd(struct ak7755_priv *data)
++{
++	struct _ak7755_pd_handler *ak7755 = &ak7755_pd_handler;
++
++	if (data == NULL)
++		return -EFAULT;
++
++	mutex_init(&ak7755->lock);
++
++	mutex_lock(&ak7755->lock);
++	ak7755->data = data;
++	mutex_unlock(&ak7755->lock);
++
++	printk("data:%p, ak7755->data:%p\n", data, ak7755->data);
++
++	return 0;
++}
++
++static struct ak7755_priv* get_ak7755_pd(void)
++{
++	struct _ak7755_pd_handler *ak7755 = &ak7755_pd_handler;
++
++	if (ak7755->data == NULL)
++		return NULL;
++
++	mutex_lock(&ak7755->lock);
++	ak7755->ref_count++;
++	mutex_unlock(&ak7755->lock);
++
++	return ak7755->data;
++}
++
++static int rel_ak7755_pd(struct ak7755_priv *data)
++{
++	struct _ak7755_pd_handler *ak7755 = &ak7755_pd_handler;
++
++	if (ak7755->data == NULL)
++		return -EFAULT;
++
++	mutex_lock(&ak7755->lock);
++	ak7755->ref_count--;
++	mutex_unlock(&ak7755->lock);
++
++	data = NULL;
++
++	return 0;
++}
++
++/* AK7755 Misc driver interfaces */
++static int ak7755_open(struct inode *inode, struct file *file)
++{
++	struct ak7755_priv *ak7755;
++
++	ak7755 = get_ak7755_pd();
++	file->private_data = ak7755;
++
++	return 0;
++}
++
++static int ak7755_close(struct inode *inode, struct file *file)
++{
++	struct ak7755_priv *ak7755 = (struct ak7755_priv*)file->private_data;
++
++	rel_ak7755_pd(ak7755);
++
++	return 0;
++}
++
++static const struct file_operations ak7755_fops = {
++	.owner = THIS_MODULE,
++	.open = ak7755_open,
++	.release = ak7755_close,
++	.unlocked_ioctl = ak7755_ioctl,
++};
++
++static struct miscdevice ak7755_misc = {
++	.minor = MISC_DYNAMIC_MINOR,
++	.name = "ak7755-dsp",
++	.fops = &ak7755_fops,
++};
++
++#endif
++
++/*********************************/
++
++// * for AK7755
++static int ak7755_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *codec_dai)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++	int 	ret = 0;
++
++	if(ak7755->amp_gpio > 0) {
++		switch (cmd) {
++		case SNDRV_PCM_TRIGGER_START:
++		case SNDRV_PCM_TRIGGER_RESUME:
++		case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++				gpio_direction_output(ak7755->amp_gpio, ak7755->amp_active);
++			}
++			break;
++		case SNDRV_PCM_TRIGGER_STOP:
++		case SNDRV_PCM_TRIGGER_SUSPEND:
++		case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
++				gpio_direction_output(ak7755->amp_gpio, !ak7755->amp_active);
++			}
++			break;
++		default:
++			break;
++		}
++
++	}
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	return ret;
++}
++
++static int ak7755_set_bias_level(struct snd_soc_codec *codec,
++		enum snd_soc_bias_level level)
++{
++	akdbgprt("\t[AK7755] %s(%d) level : %d\n",__FUNCTION__,__LINE__, level);
++
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++	case SND_SOC_BIAS_PREPARE:
++		ak7755_set_status(RUN);
++		break;
++	case SND_SOC_BIAS_STANDBY:
++		ak7755_set_status(STANDBY);
++		break;
++	case SND_SOC_BIAS_OFF:
++		ak7755_set_status(POWERDOWN);
++		break;
++	}
++	codec->dapm.bias_level = level;
++
++	return 0;
++}
++
++static int ak7755_set_dai_mute2(struct snd_soc_codec *codec, int mute)
++{
++	int ret = 0;
++	//int ndt;
++
++	//akdbgprt("\t[AK7755] %s mute[%s]\n",__FUNCTION__, mute ? "ON":"OFF");
++
++#if 0
++	if (mute) {	//SMUTE: 1 , MUTE
++		ret = snd_soc_update_bits(codec, AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 0xE0, 0xE0);
++	}
++	else {
++		ak7755_set_status(RUN);
++		// SMUTE: 0 ,NORMAL operation
++		ret = snd_soc_update_bits(codec, AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 0xE0, 0x00);
++	}
++
++	ndt = 1021000 / ak7755_data->fs;
++	mdelay(ndt);
++#endif
++	return ret;
++}
++
++static int ak7755_set_dai_mute(struct snd_soc_dai *dai, int mute)
++{
++    struct snd_soc_codec *codec = dai->codec;
++
++	ak7755_set_dai_mute2(codec, mute);
++
++	return 0;
++}
++
++#define AK7755_RATES		(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++				SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
++				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
++				SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
++			    SNDRV_PCM_RATE_96000)
++
++#define AK7755_FORMATS		(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_ops ak7755_dai_ops = {
++	.hw_params	= ak7755_hw_params,
++	.set_sysclk	= ak7755_set_dai_sysclk,
++	.set_fmt	= ak7755_set_dai_fmt,
++	.trigger = ak7755_trigger,
++	.digital_mute = ak7755_set_dai_mute,
++};
++
++struct snd_soc_dai_driver ak7755_dai[] = {
++	{
++		.name = "ak7755-AIF1",
++		.playback = {
++		       .stream_name = "Playback",
++		       .channels_min = 1,
++		       .channels_max = 2,
++		       .rates = AK7755_RATES,
++		       .formats = AK7755_FORMATS,
++		},
++		.capture = {
++		       .stream_name = "Capture",
++		       .channels_min = 1,
++		       .channels_max = 4,
++		       .rates = AK7755_RATES,
++		       .formats = AK7755_FORMATS,
++		},
++		.ops = &ak7755_dai_ops,
++	},
++};
++
++static int ak7755_init_reg(struct snd_soc_codec *codec)
++{
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);   // '15/06/15
++
++	akdbgprt("\t[AK7755 bias] %s(%d)\n",__FUNCTION__,__LINE__);
++
++
++	if ( ak7755->power_gpio > 0 ) {
++		gpio_direction_output(ak7755->power_gpio, ak7755->power_active);
++	}
++
++	if ( ak7755->pdn_gpio > 0 ) {
++		gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
++		msleep(10);
++		gpio_direction_output(ak7755->pdn_gpio, !ak7755->pdn_active);
++	}
++
++
++	ak7755_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	snd_soc_update_bits(codec, AK7755_D4_LO1_LO2_VOLUME_SETTING, 0xFF, 0xFF);			//LOVOL1,2=F(0dB)
++	snd_soc_update_bits(codec, AK7755_D3_LIN_LO3_VOLUME_SETTING, 0x0F, 0x0F);			//LOVOL3=F(0dB)
++	snd_soc_update_bits(codec, AK7755_D2_MIC_GAIN_SETTING, 0xFF, 0xCC);
++	snd_soc_update_bits(codec, AK7755_D0_FUNCTION_SETTING, 0x40, 0x40);				//CRCE=1(CRC Enable)
++	snd_soc_update_bits(codec, AK7755_C2_SERIAL_DATA_FORMAT, 0x40, AK7755_BCKP_BIT);	//BCKP bit
++	snd_soc_update_bits(codec, AK7755_D0_FUNCTION_SETTING, 0x10, AK7755_SOCFG_BIT);	//SOFG bit
++#ifdef DIGITAL_MIC		//Analog MIC Use
++	snd_soc_update_bits(codec, AK7755_DE_DMIC_IF_SETTING, 0x90, 0x90);					//DMIC1=DMIC2=1(Digital MIC Use)
++	snd_soc_update_bits(codec, AK7755_DE_DMIC_IF_SETTING, 0x40, AK7755_DMCLKP1_BIT);	//DMCLKP1 bit
++	snd_soc_update_bits(codec, AK7755_DE_DMIC_IF_SETTING, 0x08, AK7755_DMCLKP2_BIT);	//DMCLKP2 bit
++	snd_soc_update_bits(codec, AK7755_C0_CLOCK_SETTING1, 0x08, 0x00);
++#else
++	snd_soc_update_bits(codec, AK7755_C0_CLOCK_SETTING1, 0x08, 0x08);		//AINE=1(Analog MIC Use)
++#endif
++	snd_soc_write(codec, 0xCA, 0x01);
++	snd_soc_write(codec, 0xDA, 0x10);
++	snd_soc_write(codec, 0xCD, 0xC0);
++	snd_soc_write(codec, 0xE6, 0x01);
++	snd_soc_write(codec, 0xEA, 0x80);
++
++	if(aec == 1) {
++		/*Select DAC MUX as DSP DOUT4*/
++		snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0xC0, 0x00);
++		/*Lineout1 power on*/
++		snd_soc_update_bits(codec, AK7755_CE_POWER_MANAGEMENT, 0xC7, 0xC7);
++
++		/*Select SDOUT1 MUX as DOUT1 Of DSP*/
++		snd_soc_update_bits(codec, AK7755_CC_VOLUME_TRANSITION, 0x07, 0x00);
++	} else {
++		/*Select DAC MUX as SDIN1*/
++		snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0xC0, 0xC0);
++		/*Lineout1 power on*/
++		snd_soc_update_bits(codec, AK7755_CE_POWER_MANAGEMENT, 0xC7, 0xC7);
++
++		/*Select SDOUT1 MUX as SDOUTAD*/
++		snd_soc_update_bits(codec, AK7755_CC_VOLUME_TRANSITION, 0x07, 0x03);
++	}
++
++	return 0;
++}
++
++static int ak7755_parse_dt(struct ak7755_priv *ak7755)
++{
++	struct device *dev;
++	struct device_node *np;
++	enum of_gpio_flags flags;
++	int ret = 0;
++
++	if (ak7755->control_type == SND_SOC_SPI) {
++		dev = &(ak7755->spi->dev);
++	}
++	else {
++		dev = &(ak7755->i2c->dev);
++	}
++
++	np = dev->of_node;
++
++	if (!np)
++		return -1;
++
++	ak7755->pdn_gpio = of_get_named_gpio_flags(np, "ak7755,pdn-gpio", 0, &flags);
++	ak7755->pdn_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	if(ak7755->pdn_gpio < 0 || !gpio_is_valid(ak7755->pdn_gpio)) {
++		dev_err(dev, "ak7755 pdn pin(%u) is invalid\n", ret);
++		ak7755->pdn_gpio = -1;
++		return ret;
++	}
++	ret = devm_gpio_request(dev, ak7755->pdn_gpio, "ak7755 pdn_gpio");
++	if ( ret < 0 )
++		dev_err(dev, "Failed to request pdn_pin: %d\n", ret);
++
++
++	ak7755->power_gpio = of_get_named_gpio_flags(np, "ak7755,pwr-gpio", 0, &flags);
++	ak7755->power_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	if (ak7755->power_gpio < 0 || !gpio_is_valid(ak7755->power_gpio)) {
++		ak7755->power_gpio = -1;
++		dev_err(dev, "ak7755 power pin(%u) is invalid\n", ret);
++		return ret;
++	}
++	ret = devm_gpio_request(dev, ak7755->power_gpio, "ak7755 power_gpio");
++	if ( ret < 0 )
++		dev_err(dev, "Failed to request power_pin: %d\n", ret);
++
++
++	ak7755->amp_gpio = of_get_named_gpio_flags(np, "ak7755,amp-gpio", 0, &flags);
++	ak7755->amp_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	if (ak7755->amp_gpio < 0 || !gpio_is_valid(ak7755->amp_gpio)) {
++		ak7755->amp_gpio = -1;
++		dev_err(dev, "ak7755 amplifier pin(%u) is invalid\n", ret);
++		return ret;
++	}
++	ret = devm_gpio_request(dev, ak7755->amp_gpio, "ak7755 amp_gpio");
++	if ( ret < 0 )
++		dev_err(dev, "Failed to request amp_pin: %d\n", ret);
++
++	return 0;
++}
++
++static int ak7755_set_reg_table(void)
++{
++	int i;
++	int n;
++
++	n = 0;
++	do {
++		ak7755_reg[n] = 0;
++		ak7755_access_masks[n].readable = 0;
++		ak7755_access_masks[n].writable = 0;
++		n ++;
++	} while ( n < AK7755_C0_CLOCK_SETTING1 );
++
++	i = 0;
++	do {
++		ak7755_reg[n] = ak7755_reg2[i] ;
++		ak7755_access_masks[n].readable = ak7755_access_masks2[i].readable;
++		ak7755_access_masks[n].writable = ak7755_access_masks2[i].writable;
++		i++;
++		n++;
++	} while ( n < AK7755_MAX_REGISTERS);
++
++	return(0);
++
++}
++
++static int ak7755_probe(struct snd_soc_codec *codec)
++{
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++	int ret = 0;
++	int i;
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak7755->control_type);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++#ifdef AK7755_CONTIF_DEBUG
++	codec->read = ak7755_reg_read;
++	codec->write = ak7755_reg_write;
++
++#endif
++
++	akdbgprt("\t[AK7755] %s(%d) ak7755=%x\n",__FUNCTION__,__LINE__, (int)ak7755);
++	ak7755->codec = codec;
++	ret = ak7755_parse_dt(ak7755);
++	if ( ret != 0 ) {
++		dev_err(codec->dev, "Failed to parse devict tree: %d\n", ret);
++		return ret;
++	}
++
++	ak7755_set_reg_table();
++	ak7755_init_reg(codec);
++	akdbgprt("\t[AK7755 Effect] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak7755->fs = 48000;
++	ak7755->rclk = 0;
++	ak7755->lign = 7;	//lign:7 = LIGN:0(0dB)
++	ak7755->selmix = 0;	//SDOUTAD(L,R)
++	ak7755->MIRNo = 1;
++	ak7755->status = POWERDOWN;
++
++
++	ak7755->DSPPramMode = 0;
++	ak7755->DSPCramMode = 0;
++	ak7755->DSPOfregMode = 0;
++	ak7755->DSPAcramMode = 0;
++
++	for ( i = 0 ; i < 5 ; i ++ ) ak7755->EQLevel[i] = 24;
++	ak7755->HPFfc[0] = 0;
++	ak7755->HPFfc[1] = 0;
++ 	ak7755->LimRel = 2;
++	ak7755->LimVol = 0;
++
++	ak7755->bickfs = (AK7755_AUDIO_IF_MODE >> 4);
++
++	akdbgprt("\t[AK7755 init_ak7755_pd] %s(%d)\n",__FUNCTION__,__LINE__);
++
++#ifdef AK7755_IO_CONTROL
++	init_ak7755_pd(ak7755);
++#endif
++	return ret;
++}
++
++static int ak7755_remove(struct snd_soc_codec *codec)
++{
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak7755_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	if ( ak7755->pdn_gpio > 0 ) {
++		gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
++		gpio_free(ak7755->pdn_gpio);
++	}
++
++	return 0;
++}
++
++static int ak7755_suspend(struct snd_soc_codec *codec)
++{
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++	int i = 0;
++
++	for(i = 0; i < AK7755_MAX_REGNUM; i++) {
++		ak7755_data->reg_cache[i] = snd_soc_read(codec, i + 0xc0);
++	}
++	ak7755_data->reg_cache[1] &= 0xfe;		//Make sure  CKRESETN bit is reset
++
++	ak7755_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	if ( ak7755->amp_active > 0 ) {
++		gpio_direction_output(ak7755->amp_gpio, !ak7755->amp_active);
++	}
++	if ( ak7755->pdn_gpio > 0 ) {
++		gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
++	}
++	if ( ak7755->power_gpio > 0 ) {
++		gpio_direction_output(ak7755->power_gpio, !ak7755->power_active);
++	}
++
++	return 0;
++}
++
++static int ak7755_resume(struct snd_soc_codec *codec)
++{
++	struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
++	int i = 0;
++
++	if ( ak7755->pdn_gpio > 0 ) {
++		gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
++	}
++
++	if ( ak7755->power_gpio > 0 ) {
++		gpio_direction_output(ak7755->power_gpio, ak7755->power_active);
++		mdelay(10);
++	}
++
++	if ( ak7755->pdn_gpio > 0 ) {
++		gpio_direction_output(ak7755->pdn_gpio, !ak7755->pdn_active);
++		mdelay(2);
++	}
++
++	snd_soc_write(codec,AK7755_C0_CLOCK_SETTING1,0x08);
++	snd_soc_write(codec,AK7755_C1_CLOCK_SETTING2,0x00);
++	for(i = 0; i < AK7755_MAX_REGNUM; i++) {
++		snd_soc_write(codec, i+0xc0, ak7755_data->reg_cache[i]);
++	}
++
++	snd_soc_update_bits(codec, AK7755_C1_CLOCK_SETTING2, 0x01, 0x01);
++	snd_soc_write(codec,AK7755_CF_RESET_POWER_SETTING,0x01);
++	snd_soc_write(codec,AK7755_DA_MUTE_ADRC_ZEROCROSS_SET,0x10);
++	mdelay(12);
++
++	ak7755_firmware_write_ram(RAMTYPE_PRAM, ak7755_data->DSPPramMode);
++	ak7755_firmware_write_ram(RAMTYPE_CRAM, ak7755_data->DSPCramMode);
++
++	//snd_soc_cache_sync(codec);
++	snd_soc_write(codec, 0xE6, 0x01);
++	snd_soc_write(codec, 0xEA, 0x80);
++
++	snd_soc_write(codec,AK7755_DA_MUTE_ADRC_ZEROCROSS_SET,0x00);
++
++	ak7755_set_bias_level(codec, SND_SOC_BIAS_ON);
++
++	return 0;
++}
++
++
++struct snd_soc_codec_driver soc_codec_dev_ak7755 = {
++	.probe = ak7755_probe,
++	.remove = ak7755_remove,
++	.suspend =	ak7755_suspend,
++	.resume =	ak7755_resume,
++
++	//.idle_bias_off = false,
++	.set_bias_level = ak7755_set_bias_level,
++	.reg_cache_size = ARRAY_SIZE(ak7755_reg),
++	.reg_word_size = sizeof(u8),
++	.reg_cache_default = ak7755_reg,
++	.readable_register = ak7755_readable,
++	.volatile_register = ak7755_volatile,
++
++	.controls = ak7755_snd_controls,
++	.num_controls = ARRAY_SIZE(ak7755_snd_controls),
++	.dapm_widgets = ak7755_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(ak7755_dapm_widgets),
++	.dapm_routes = ak7755_intercon,
++	.num_dapm_routes = ARRAY_SIZE(ak7755_intercon),
++};
++EXPORT_SYMBOL_GPL(soc_codec_dev_ak7755);
++
++#ifdef CONFIG_OF
++static struct of_device_id ak7755_if_dt_ids[] = {
++	{ .compatible = "akm,ak7755"},
++	{ }
++};
++MODULE_DEVICE_TABLE(of, ak7755_if_dt_ids);
++#endif
++
++#ifdef AK7755_I2C_IF
++static int ak7755_i2c_probe(struct i2c_client *i2c,
++                            const struct i2c_device_id *id)
++{
++	struct ak7755_priv *ak7755;
++	int ret=0;
++
++	akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
++
++	ak7755 = kzalloc(sizeof(struct ak7755_priv), GFP_KERNEL);
++	if (ak7755 == NULL) return -ENOMEM;
++
++	i2c_set_clientdata(i2c, ak7755);
++
++	ak7755->control_type = SND_SOC_I2C;
++	ak7755->i2c = i2c;
++
++	ak7755_data = ak7755;
++
++	ret = snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_ak7755, &ak7755_dai[0], ARRAY_SIZE(ak7755_dai));
++	if (ret < 0){
++		kfree(ak7755);
++		akdbgprt("\t[AK7755 Error!] %s(%d)\n",__FUNCTION__,__LINE__);
++	}
++	return ret;
++}
++
++static int ak7755_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	kfree(i2c_get_clientdata(client));
++	return 0;
++}
++
++static const struct i2c_device_id ak7755_i2c_id[] = {
++	{ "ak7755", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, ak7755_i2c_id);
++
++static struct i2c_driver ak7755_i2c_driver = {
++	.driver = {
++		.name = "ak7755",
++		.owner = THIS_MODULE,
++#ifdef CONFIG_OF
++		.of_match_table = of_match_ptr(ak7755_if_dt_ids),
++#endif
++	},
++	.probe = ak7755_i2c_probe,
++	.remove = ak7755_i2c_remove,
++	.id_table = ak7755_i2c_id,
++};
++
++#else
++
++static int ak7755_spi_probe(struct spi_device *spi)
++{
++	struct ak7755_priv *ak7755;
++	int	ret;
++
++	akdbgprt("\t[AK7755] %s spi=%x\n",__FUNCTION__, (int)spi);
++
++	ak7755 = kzalloc(sizeof(struct ak7755_priv), GFP_KERNEL);
++	if (!ak7755)
++		return -ENOMEM;
++
++	ak7755->control_type = SND_SOC_SPI;
++	spi->bits_per_word = 8; // bits
++	spi->max_speed_hz = 7000000;
++	spi->mode = SPI_MODE_3;
++
++	akdbgprt("\t[AK7755] %s spi=%x, spi->chip_select = %d\n, cs_gpio = %d",__FUNCTION__, \
++		(int)spi, spi->chip_select, spi->cs_gpio);
++
++	ak7755->spi = spi;
++	ak7755_data = ak7755;
++
++	if ( 1 == fast_boot ) {
++		u8 reg[2],rx[1];
++		akdbgprt("Start loading AEC Firmware....\n");
++		reg[0] = AK7755_C1_CLOCK_SETTING2 & 0x7F;
++		ak7755_reads(reg,1,rx,1);
++		if (1 != (rx[0] & 0x1)) {
++			printk( "Fast audio setup error for ak7755: 0x%02X\n", rx[0]);
++			return -1;
++		}
++		reg[0] = AK7755_CF_RESET_POWER_SETTING;
++		reg[1] = 0x01;
++		ak7755_writes(reg,2);
++
++		msleep(1);
++		ret = ak7755_firmware_write_ram(RAMTYPE_PRAM, 1);
++		if ( ret < 0 ) {
++			printk( "Failed to RAMTYPE_PRAM %d\n", ret);
++			return ret;
++		}
++		ret = ak7755_firmware_write_ram(RAMTYPE_CRAM,1);
++		if ( ret < 0 ) {
++			printk( "Failed to RAMTYPE_CRAM: %d\n", ret);
++			return ret;
++		}
++		reg[0] = AK7755_CF_RESET_POWER_SETTING;
++		reg[1] = 0x0c;
++		ak7755_writes(reg,2);
++		akdbgprt("Loading AEC Firmware done\n");
++		reg[0] = AK7755_CC_VOLUME_TRANSITION;	   //change to DSP output
++		reg[1] = 0x00;
++		ak7755_writes(reg,2);
++		reg[0] = AK7755_D2_MIC_GAIN_SETTING;	   //change Mic Gain to 6dB
++		reg[1] = 0x03;
++		ak7755_writes(reg,2);
++		reg[0] = AK7755_C8_DAC_IN_SETTING;		 //change DAC out to DSP
++		reg[1] = 0x00;
++
++#ifdef AK7755_DEBUG
++		u32 i;
++		for(i = 0x40; i <= 0x5e; i++) {
++			reg[0] = i ;
++			ak7755_reads(reg,1,rx,1);
++			printk("0x%x: 0x%02x\n", i|0xc0, rx[0]);
++  }
++#endif
++		return 0;
++	} else {
++		spi_set_drvdata(spi, ak7755);
++	}
++
++	ret = snd_soc_register_codec(&spi->dev,
++			&soc_codec_dev_ak7755,  &ak7755_dai[0], ARRAY_SIZE(ak7755_dai));
++	if (ret < 0)
++		kfree(ak7755);
++
++	ak7755_data = ak7755;
++
++	return 0;
++}
++
++static int ak7755_spi_remove(struct spi_device *spi)
++{
++	if ( ak7755_data->amp_active > 0 ) {
++		gpio_direction_output(ak7755_data->amp_gpio, !ak7755_data->amp_active);
++		devm_gpio_free(&spi->dev,ak7755_data->amp_active);
++	}
++	if ( ak7755_data->pdn_gpio > 0 ) {
++		gpio_direction_output(ak7755_data->pdn_gpio, ak7755_data->pdn_active);
++		devm_gpio_free(&spi->dev,ak7755_data->pdn_gpio);
++	}
++	if ( ak7755_data->power_gpio > 0 ) {
++		gpio_direction_output(ak7755_data->power_gpio, !ak7755_data->power_active);
++		devm_gpio_free(&spi->dev,ak7755_data->power_gpio);
++		akdbgprt("\t[AK7755] %s(%d) Release power_gpio ->>> %d\n",__FUNCTION__,__LINE__,ak7755_data->power_gpio);
++	}
++	snd_soc_unregister_codec(&spi->dev);
++	kfree(spi_get_drvdata(spi));
++	return 0;
++}
++
++static struct spi_driver ak7755_spi_driver = {
++	.driver = {
++		.name = "ak7755",
++		.owner = THIS_MODULE,
++#ifdef CONFIG_OF
++		.of_match_table = of_match_ptr(ak7755_if_dt_ids),
++#endif
++	},
++	.probe = ak7755_spi_probe,
++	.remove = ak7755_spi_remove,
++};
++#endif
++
++static int __init ak7755_modinit(void)
++{
++	int ret = 0;
++
++	akdbgprt("\t[AK7755] %s(%d)\n", __FUNCTION__,__LINE__);
++
++#ifdef AK7755_I2C_IF
++	ret = i2c_add_driver(&ak7755_i2c_driver);
++	if ( ret != 0 ) {
++		printk(KERN_ERR "Failed to register AK7755 I2C driver: %d\n", ret);
++
++	}
++#else
++	ret = spi_register_driver(&ak7755_spi_driver);
++	if ( ret != 0 ) {
++		printk(KERN_ERR "Failed to register AK7755 SPI driver: %d\n",  ret);
++
++	}
++#endif
++
++#ifdef AK7755_IO_CONTROL
++	ret = misc_register(&ak7755_misc);
++	if (ret < 0) {
++		printk(KERN_ERR "Failed to register AK7755 MISC driver: %d\n",  ret);
++	}
++#endif
++
++	return ret;
++}
++
++module_init(ak7755_modinit);
++
++static void __exit ak7755_exit(void)
++{
++#ifdef AK7755_I2C_IF
++	i2c_del_driver(&ak7755_i2c_driver);
++#else
++	spi_unregister_driver(&ak7755_spi_driver);
++#endif
++
++#ifdef AK7755_IO_CONTROL
++	misc_deregister(&ak7755_misc);
++#endif
++
++}
++module_exit(ak7755_exit);
++
++MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
++MODULE_DESCRIPTION("ASoC ak7755 codec driver");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/ak7755.h b/sound/soc/codecs/ak7755.h
+new file mode 100644
+index 00000000..f320c39d
+--- /dev/null
++++ b/sound/soc/codecs/ak7755.h
+@@ -0,0 +1,172 @@
++/*
++ * ak7755.h  --  audio driver for ak7755
++ *
++ * Copyright (C) 2014 Asahi Kasei Microdevices Corporation
++ *  Author                Date        Revision
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *                      14/04/22	    1.0
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ */
++
++#ifndef _AK7755_H
++#define _AK7755_H
++
++//#define AK7755_I2C_IF
++#define AK7755_IO_CONTROL
++
++
++/* AK7755_C1_CLOCK_SETTING2 (0xC1)  Fields */
++#define AK7755_AIF_BICK32		(2 << 4)
++#define AK7755_AIF_BICK48		(1 << 4)
++#define AK7755_AIF_BICK64		(0 << 4)
++#define AK7755_AIF_TDM			(3 << 4)	//TDM256 bit is set "1" at initialization.
++
++/* TDMMODE Input Source */
++#define AK7755_TDM_DSP				(0 << 2)
++#define AK7755_TDM_DSP_AD1			(1 << 2)
++#define AK7755_TDM_DSP_AD1_AD2		(2 << 2)
++
++/* User Setting */
++//#define DIGITAL_MIC
++//#define CLOCK_MODE_BICK
++//#define CLOCK_MODE_18_432
++#define AK7755_AUDIO_IF_MODE		AK7755_AIF_BICK32	//32fs, 48fs, 64fs, 256fs(TDM)
++#define AK7755_TDM_INPUT_SOURCE		AK7755_TDM_DSP		//Effective only in TDM mode
++#define AK7755_BCKP_BIT				(0 << 6)	//BICK Edge Setting
++#define AK7755_SOCFG_BIT  			(0 << 4)	//SO pin Hi-z Setting
++#define AK7755_DMCLKP1_BIT			(0 << 6)	//DigitalMIC 1 Channnel Setting
++#define AK7755_DMCLKP2_BIT			(0 << 3)	//DigitalMIC 1 Channnel Setting
++/* User Setting */
++
++#define AK7755_C0_CLOCK_SETTING1			0xC0
++#define AK7755_C1_CLOCK_SETTING2			0xC1
++#define AK7755_C2_SERIAL_DATA_FORMAT		0xC2
++#define AK7755_C3_DELAY_RAM_DSP_IO			0xC3
++#define AK7755_C4_DATARAM_CRAM_SETTING		0xC4
++#define AK7755_C5_ACCELARETOR_SETTING		0xC5
++#define AK7755_C6_DAC_DEM_SETTING			0xC6
++#define AK7755_C7_DSP_OUT_SETTING			0xC7
++#define AK7755_C8_DAC_IN_SETTING			0xC8
++#define AK7755_C9_ANALOG_IO_SETTING			0xC9
++#define AK7755_CA_CLK_SDOUT_SETTING			0xCA
++#define AK7755_CB_TEST_SETTING				0xCB
++#define AK7755_CC_VOLUME_TRANSITION			0xCC
++#define AK7755_CD_STO_DLS_SETTING			0xCD
++#define AK7755_CE_POWER_MANAGEMENT			0xCE
++#define AK7755_CF_RESET_POWER_SETTING		0xCF
++#define AK7755_D0_FUNCTION_SETTING			0xD0
++#define AK7755_D1_DSPMCLK_SETTING			0xD1
++#define AK7755_D2_MIC_GAIN_SETTING			0xD2
++#define AK7755_D3_LIN_LO3_VOLUME_SETTING	0xD3
++#define AK7755_D4_LO1_LO2_VOLUME_SETTING	0xD4
++#define AK7755_D5_ADC_DVOLUME_SETTING1		0xD5
++#define AK7755_D6_ADC_DVOLUME_SETTING2		0xD6
++#define AK7755_D7_ADC2_DVOLUME_SETTING1		0xD7
++#define AK7755_D8_DAC_DVOLUME_SETTING1		0xD8
++#define AK7755_D9_DAC_DVOLUME_SETTING2		0xD9
++#define AK7755_DA_MUTE_ADRC_ZEROCROSS_SET	0xDA
++#define AK7755_DB_ADRC_MIC_GAIN_READ		0xDB
++#define AK7755_DC_TEST_SETTING				0xDC
++#define AK7755_DD_ADC2_DVOLUME_SETTING2		0xDD
++#define AK7755_DE_DMIC_IF_SETTING			0xDE
++
++#define AK7755_MAX_REGISTERS	(AK7755_DE_DMIC_IF_SETTING + 1)
++#define AK7755_MAX_REGNUM		(31)
++
++/* Bitfield Definitions */
++
++/* AK7755_C0_CLOCK_SETTING1 (0xC0) Fields */
++#define AK7755_FS				0x07
++#define AK7755_FS_8KHZ			(0x00 << 0)
++#define AK7755_FS_12KHZ			(0x01 << 0)
++#define AK7755_FS_16KHZ			(0x02 << 0)
++#define AK7755_FS_24KHZ			(0x03 << 0)
++#define AK7755_FS_32KHZ			(0x04 << 0)
++#define AK7755_FS_48KHZ			(0x05 << 0)
++#define AK7755_FS_96KHZ			(0x06 << 0)
++
++#define AK7755_M_S				0x30		//CKM1-0 (CKM2 bit is not use)
++#define AK7755_M_S_0			(0 << 4)	//Master, XTI=12.288MHz
++#define AK7755_M_S_1			(1 << 4)	//Master, XTI=18.432MHz
++#define AK7755_M_S_2			(2 << 4)	//Slave, XTI=12.288MHz
++#define AK7755_M_S_3			(3 << 4)	//Slave, BICK
++
++/* AK7755_C2_SERIAL_DATA_FORMAT (0xC2) Fields */
++/* LRCK I/F Format */
++#define AK7755_LRIF					0x30
++#define AK7755_LRIF_MSB_MODE		(0 << 4)
++#define AK7755_LRIF_I2S_MODE		(1 << 4)
++#define AK7755_LRIF_PCM_SHORT_MODE	(2 << 4)
++#define AK7755_LRIF_PCM_LONG_MODE	(3 << 4)
++/* Input Format is set as "MSB(24- bit)" by following register.
++   CONT03(DIF2,DOF2), CONT06(DIFDA, DIF1), CONT07(DOF4,DOF3,DOF1) */
++
++/* AK7755_CA_CLK_SDOUT_SETTING (0xCA) Fields */
++#define AK7755_BICK_LRCK			(3 << 5)	//BICKOE, LRCKOE
++
++
++
++#define MAX_LOOP_TIMES		3
++
++#define CRC_COMMAND_READ_RESULT			0x72
++#define	TOTAL_NUM_OF_PRAM_MAX		20483
++#define	TOTAL_NUM_OF_CRAM_MAX		6147
++#define	TOTAL_NUM_OF_OFREG_MAX		99
++#define	TOTAL_NUM_OF_ACRAM_MAX		6147
++
++static const char *ak7755_firmware_pram[] =
++{
++    "Off",
++    "basic",
++    "data2",
++    "data3",
++    "data4",
++    "data5",
++    "data6",
++    "data7",
++    "data8",
++    "data9",
++};
++
++static const char *ak7755_firmware_cram[] =
++{
++    "Off",
++    "basic",
++    "data2",
++    "data3",
++    "data4",
++    "data5",
++    "data6",
++    "data7",
++    "data8",
++    "data9",
++};
++
++static const char *ak7755_firmware_ofreg[] =
++{
++    "Off",
++    "basic",
++    "data2",
++    "data3",
++    "data4",
++};
++
++static const char *ak7755_firmware_acram[] =
++{
++    "Off",
++    "basic",
++    "data2",
++    "data3",
++    "data4",
++};
++
++#include "ak7755ctl.h"
++
++#endif
++
+diff --git a/sound/soc/codecs/ak7755_dsp_code.h b/sound/soc/codecs/ak7755_dsp_code.h
+new file mode 100644
+index 00000000..43a4cc5d
+--- /dev/null
++++ b/sound/soc/codecs/ak7755_dsp_code.h
+@@ -0,0 +1,6220 @@
++static u8 ak7755_pram_basic[]= {
++    0xB8, 0x00, 0x00,             // PRAM Write Command
++    0x0C, 0x94, 0xED, 0x1E, 0x74,
++    0x04, 0xA8, 0x9C, 0x6D, 0x55,
++    0x00, 0x44, 0x02, 0x11, 0x99,
++    0x09, 0x58, 0x6F, 0x4D, 0xD0,
++    0x01, 0x5A, 0x7C, 0xC9, 0x27,
++    0x09, 0x35, 0x31, 0x01, 0x86,
++    0x03, 0x4B, 0xFA, 0x2C, 0x60,
++    0x0E, 0xF8, 0x5B, 0xA8, 0xD6,
++    0x04, 0x02, 0x37, 0xDD, 0x00,
++    0x05, 0x79, 0x77, 0x03, 0x9D,
++    0x07, 0xAE, 0xA3, 0x43, 0x38,
++    0x0E, 0xD9, 0xA6, 0x5E, 0x1F,
++    0x00, 0x7B, 0xE3, 0xE6, 0x41,
++    0x09, 0x8A, 0xB8, 0x79, 0xB1,
++    0x03, 0x68, 0x1B, 0xB8, 0x98,
++    0x08, 0x55, 0xA7, 0x8B, 0x7A,
++    0x01, 0x8F, 0x58, 0x91, 0x42,
++    0x04, 0xAC, 0x14, 0xDB, 0xF2,
++    0x0B, 0x37, 0xC2, 0x1F, 0x0C,
++    0x06, 0xA5, 0x9C, 0xED, 0xE6,
++    0x01, 0xA6, 0xC0, 0xAD, 0xBB,
++    0x05, 0xFE, 0x2A, 0x81, 0x4A,
++    0x03, 0xBF, 0xC7, 0x3A, 0x4F,
++    0x0D, 0x44, 0x86, 0x74, 0x8C,
++    0x03, 0x43, 0xBC, 0x3B, 0x53,
++    0x07, 0xC5, 0xCD, 0x84, 0x59,
++    0x04, 0x79, 0xF3, 0xE4, 0x2E,
++    0x01, 0xB5, 0x71, 0x37, 0x20,
++    0x08, 0x46, 0x13, 0x93, 0xD3,
++    0x05, 0xB7, 0x82, 0x8D, 0x69,
++    0x02, 0xA4, 0x57, 0xEC, 0x94,
++    0x0C, 0x06, 0x32, 0x8D, 0x2F,
++    0x08, 0xB1, 0xD7, 0x59, 0xE3,
++    0x0E, 0x83, 0x5C, 0xF6, 0x0B,
++    0x0F, 0x55, 0x03, 0x95, 0xE5,
++    0x0C, 0x5E, 0xF0, 0x1E, 0xBA,
++    0x08, 0x5C, 0x20, 0x7B, 0x66,
++    0x07, 0x29, 0xFB, 0x43, 0x5F,
++    0x0A, 0xC8, 0xC7, 0xA7, 0x68,
++    0x03, 0xB7, 0x43, 0xC8, 0xE3,
++    0x0B, 0xB3, 0xA3, 0x26, 0x5A,
++    0x0D, 0x76, 0xEE, 0xC5, 0xB0,
++    0x0E, 0x14, 0x8B, 0xD3, 0xF6,
++    0x09, 0x3E, 0x49, 0xA9, 0x98,
++    0x0D, 0x34, 0xDA, 0x5F, 0xD1,
++    0x03, 0xAC, 0xB3, 0xC3, 0xEC,
++    0x06, 0xB6, 0xEC, 0x12, 0x0D,
++    0x0A, 0x05, 0x2A, 0xCD, 0xB2,
++    0x0C, 0xE9, 0x3D, 0xF3, 0x98,
++    0x09, 0xC2, 0xF6, 0xCB, 0x3E,
++    0x00, 0xFF, 0x83, 0xD9, 0xA5,
++    0x0A, 0x89, 0xEE, 0xD9, 0xE7,
++    0x04, 0x0A, 0x71, 0xCE, 0x95,
++    0x04, 0xC4, 0x40, 0x21, 0x18,
++    0x0E, 0x55, 0x87, 0xF4, 0xDC,
++    0x0A, 0x15, 0xA0, 0x6C, 0x92,
++    0x0F, 0x93, 0x52, 0x30, 0x18,
++    0x0A, 0x64, 0x3B, 0x22, 0xC7,
++    0x08, 0x37, 0x4E, 0xBA, 0x0D,
++    0x0D, 0x89, 0xA9, 0xFF, 0xE4,
++    0x0B, 0x06, 0x54, 0x70, 0x39,
++    0x02, 0x2B, 0x6C, 0xA4, 0x33,
++    0x04, 0xBC, 0x5B, 0x1B, 0xAB,
++    0x0E, 0x56, 0x7A, 0x28, 0xAE,
++    0x02, 0xCC, 0x22, 0xCF, 0x9B,
++    0x05, 0x72, 0x0D, 0xAB, 0x89,
++    0x09, 0xD1, 0x82, 0x30, 0x9C,
++    0x0B, 0x0D, 0xE9, 0xBD, 0x25,
++    0x0B, 0x4F, 0xD9, 0x21, 0x0C,
++    0x06, 0xA6, 0x61, 0x37, 0x9E,
++    0x09, 0x7F, 0x45, 0x08, 0x38,
++    0x0F, 0x1F, 0x74, 0x1C, 0xEB,
++    0x00, 0x5A, 0xFA, 0xAE, 0xA6,
++    0x07, 0xAE, 0x40, 0x7B, 0xA4,
++    0x0C, 0x54, 0xA8, 0x6F, 0x4B,
++    0x0B, 0x34, 0x3B, 0xC3, 0xFE,
++    0x0F, 0x7C, 0x5D, 0xC8, 0x25,
++    0x0B, 0x47, 0x98, 0xB6, 0x2A,
++    0x07, 0x1B, 0x56, 0x13, 0x11,
++    0x00, 0xD4, 0xE5, 0xB9, 0x56,
++    0x0A, 0x83, 0xB3, 0x28, 0x56,
++    0x0F, 0xE3, 0xCF, 0xFC, 0xFD,
++    0x0D, 0x91, 0xA0, 0x28, 0xD2,
++    0x0E, 0xDA, 0x9B, 0xE5, 0x9E,
++    0x0F, 0xB9, 0xF4, 0xB1, 0x2A,
++    0x04, 0xA4, 0x94, 0x2F, 0x94,
++    0x0D, 0x91, 0x66, 0x49, 0xEB,
++    0x08, 0xC1, 0x4E, 0x17, 0xB6,
++    0x09, 0x26, 0x47, 0xFC, 0x1E,
++    0x08, 0xB9, 0x90, 0x4E, 0x47,
++    0x0F, 0x3E, 0x6C, 0x50, 0x3D,
++    0x06, 0xAE, 0x27, 0x24, 0x0B,
++    0x08, 0xC2, 0x72, 0x2A, 0xBD,
++    0x06, 0xE4, 0x50, 0xAB, 0x0F,
++    0x04, 0x96, 0xFC, 0x9C, 0x2B,
++    0x08, 0x46, 0xF1, 0xAD, 0xFD,
++    0x0F, 0xBA, 0x2B, 0x34, 0x3D,
++    0x00, 0x6B, 0x6E, 0xC1, 0x6B,
++    0x0A, 0xA0, 0x53, 0xBC, 0xBB,
++    0x01, 0xCE, 0x94, 0x57, 0x51,
++    0x01, 0x9C, 0x2E, 0x6C, 0xD0,
++    0x0F, 0x5F, 0x7C, 0xBD, 0xF1,
++    0x02, 0x70, 0x55, 0xED, 0x1E,
++    0x0C, 0x89, 0x2D, 0x9E, 0xDD,
++    0x0D, 0x1D, 0x87, 0x02, 0x11,
++    0x04, 0xB4, 0xDE, 0xEF, 0x4D,
++    0x09, 0xF0, 0x9B, 0x78, 0x83,
++    0x0C, 0xA8, 0xF1, 0x35, 0xCB,
++    0x0C, 0xF2, 0xCA, 0xFA, 0x2C,
++    0x05, 0xC7, 0xF8, 0xFB, 0xA0,
++    0x07, 0x8C, 0x42, 0xD7, 0xD5,
++    0x00, 0xA5, 0x79, 0x73, 0x32,
++    0x0D, 0x27, 0xAE, 0xA6, 0xF0,
++    0x08, 0x5E, 0xD8, 0xA7, 0xD4,
++    0x0F, 0xF0, 0x7B, 0x64, 0x6C,
++    0x01, 0x29, 0xDA, 0x3A, 0xC9,
++    0x01, 0x52, 0x38, 0xDC, 0x0A,
++    0x04, 0x88, 0x04, 0x23, 0x01,
++    0x06, 0xB0, 0xDC, 0xDB, 0x99,
++    0x00, 0xB4, 0xF9, 0x9A, 0x1B,
++    0x0E, 0x6A, 0x62, 0x83, 0x11,
++    0x06, 0xC7, 0x70, 0x58, 0xEB,
++    0x00, 0xF1, 0xF1, 0x81, 0xA5,
++    0x0B, 0x54, 0x2B, 0xAA, 0x81,
++    0x06, 0xF2, 0xE7, 0x07, 0x32,
++    0x0F, 0x0C, 0xC0, 0x86, 0x70,
++    0x01, 0xB3, 0x48, 0xFC, 0x37,
++    0x00, 0xA6, 0x41, 0xCC, 0x82,
++    0x03, 0xB4, 0x79, 0xF3, 0x62,
++    0x04, 0x20, 0x31, 0x71, 0x31,
++    0x00, 0x08, 0x46, 0x13, 0x95,
++    0x01, 0xEC, 0xB7, 0x22, 0x85,
++    0x05, 0xFB, 0x2F, 0x37, 0xEC,
++    0x04, 0xCC, 0x06, 0x36, 0xBC,
++    0x0F, 0xE8, 0xB1, 0xD0, 0x53,
++    0x03, 0xEE, 0x83, 0xDD, 0x46,
++    0x0B, 0x5F, 0x55, 0x06, 0xB2,
++    0x09, 0xDC, 0x0E, 0x74, 0x96,
++    0x06, 0x89, 0x0D, 0x21, 0x73,
++    0x04, 0x87, 0x7C, 0x77, 0xC1,
++    0x03, 0x8B, 0x9D, 0x04, 0xAF,
++    0x08, 0xA3, 0x62, 0xC5, 0x48,
++    0x0F, 0x6A, 0xE4, 0x22, 0x28,
++    0x00, 0xDD, 0xA3, 0x2A, 0xC3,
++    0x06, 0x6E, 0x4D, 0x8A, 0xDB,
++    0x06, 0x18, 0xEB, 0xC9, 0xA9,
++    0x04, 0x0C, 0x6F, 0xDA, 0x57,
++    0x01, 0x32, 0x28, 0xB3, 0xC7,
++    0x0D, 0x06, 0xB6, 0xEC, 0x16,
++    0x0E, 0xFB, 0x81, 0x2B, 0xCB,
++    0x08, 0x1C, 0xE9, 0x3D, 0x75,
++    0x02, 0x48, 0x42, 0xF6, 0xCD,
++    0x02, 0xF0, 0xF4, 0x43, 0xD7,
++    0x07, 0x32, 0x09, 0x4A, 0xE0,
++    0x07, 0xCD, 0x8A, 0x97, 0xCC,
++    0x05, 0xC4, 0xC4, 0xC6, 0x11,
++    0x08, 0x4E, 0x55, 0x82, 0xD2,
++    0x04, 0x0A, 0xB5, 0xAE, 0x6C,
++    0x0B, 0x5F, 0x73, 0x5A, 0xF0,
++    0x08, 0xCA, 0x34, 0xBF, 0xA2,
++    0x07, 0x59, 0x66, 0x8F, 0xBA,
++    0x0D, 0x6D, 0xDF, 0xAD, 0x7D,
++    0x04, 0x0A, 0x56, 0x97, 0x70,
++    0x09, 0x82, 0xFE, 0x6A, 0x24,
++    0x02, 0xD5, 0x2C, 0x9A, 0x1D,
++    0x01, 0xAE, 0x83, 0x3C, 0x9E,
++    0x05, 0x43, 0x5E, 0xA3, 0xCF,
++    0x0B, 0x44, 0xA5, 0x0D, 0xAB,
++    0x08, 0xD9, 0x41, 0x44, 0x7A,
++    0x0D, 0xFA, 0xC9, 0xEF, 0x73,
++    0x04, 0x7A, 0xCE, 0xD9, 0x25,
++    0x0F, 0x77, 0x26, 0x60, 0x31,
++    0x05, 0x38, 0xBF, 0x45, 0x8E,
++    0x02, 0xCF, 0x1F, 0x70, 0x2B,
++    0x0B, 0xB0, 0x5A, 0xFE, 0x1B,
++    0x04, 0xAF, 0x2F, 0xE6, 0x79,
++    0x04, 0xF5, 0xD4, 0xCE, 0xED,
++    0x0B, 0xDB, 0x34, 0x3D, 0xF3,
++    0x0E, 0x0F, 0x7C, 0x5A, 0x7A,
++    0x09, 0x3B, 0x4A, 0x1F, 0x3E,
++    0x0A, 0x47, 0x1B, 0x57, 0x13,
++    0x01, 0x00, 0x84, 0x63, 0x89,
++    0x0A, 0x1B, 0xDD, 0x72, 0x20,
++    0x06, 0x9F, 0xB2, 0x4B, 0x7E,
++    0x0D, 0x4C, 0xC0, 0x61, 0x99,
++    0x0E, 0xFE, 0x85, 0x5D, 0x6D,
++    0x0E, 0x3E, 0xE8, 0x35, 0xB7,
++    0x08, 0xB6, 0x75, 0xDC, 0x23,
++    0x06, 0xDE, 0x60, 0x6B, 0x03,
++    0x02, 0xAA, 0xB0, 0xCA, 0x17,
++    0x0C, 0x68, 0x17, 0x87, 0xF8,
++    0x06, 0xF8, 0x39, 0x94, 0x0A,
++    0x0E, 0x0F, 0x9E, 0x6E, 0xD4,
++    0x06, 0xB4, 0x8E, 0x22, 0x22,
++    0x0B, 0x08, 0xA0, 0x72, 0xA4,
++    0x07, 0x25, 0xC4, 0x50, 0xAD,
++    0x0F, 0x64, 0x92, 0xFC, 0x9A,
++    0x0B, 0x80, 0xC2, 0x55, 0xE5,
++    0x0F, 0x16, 0x3E, 0xCF, 0x7C,
++    0x0D, 0xD1, 0xEF, 0x6E, 0xC1,
++    0x0B, 0xD3, 0x24, 0x52, 0xBC,
++    0x07, 0x9E, 0x31, 0x6F, 0xE7,
++    0x08, 0x22, 0x58, 0x2B, 0x67,
++    0x08, 0x6A, 0xAF, 0xF9, 0xEA,
++    0x08, 0x5B, 0xE0, 0x90, 0x6D,
++    0x07, 0x72, 0x18, 0xA5, 0x1C,
++    0x05, 0xDD, 0xE8, 0x44, 0xC2,
++    0x08, 0x9D, 0x45, 0x5C, 0xEF,
++    0x01, 0xC8, 0xAA, 0x5A, 0x60,
++    0x01, 0xAF, 0xBD, 0xB5, 0xF3,
++    0x0B, 0x8C, 0xC9, 0xCB, 0xF2,
++    0x04, 0xF5, 0x36, 0x78, 0xFB,
++    0x0C, 0xD6, 0xD6, 0x02, 0xC9,
++    0x04, 0xC5, 0x05, 0x7F, 0x7D,
++    0x0B, 0x9C, 0xC7, 0xAE, 0x62,
++    0x0B, 0x9E, 0xDA, 0xD5, 0xA1,
++    0x06, 0x1F, 0x70, 0x7F, 0xE2,
++    0x0E, 0x40, 0xAD, 0xDA, 0xFC,
++    0x01, 0x37, 0x72, 0x38, 0x1A,
++    0x08, 0x98, 0x88, 0x80, 0x34,
++    0x01, 0x62, 0x10, 0xDA, 0xDB,
++    0x09, 0x42, 0x3C, 0xFF, 0x12,
++    0x03, 0xF0, 0x6A, 0x62, 0x43,
++    0x03, 0x46, 0xE7, 0x74, 0x50,
++    0x0B, 0x2F, 0xF1, 0xF7, 0x41,
++    0x0D, 0xBB, 0x01, 0xAF, 0xAA,
++    0x03, 0x4A, 0xFA, 0xEA, 0x07,
++    0x08, 0x4F, 0x51, 0x40, 0x86,
++    0x00, 0x3C, 0x13, 0x43, 0xBC,
++    0x0F, 0x59, 0x57, 0xC5, 0xCC,
++    0x02, 0x53, 0xB4, 0xF9, 0xF3,
++    0x02, 0xA4, 0x73, 0x31, 0x3B,
++    0x01, 0x10, 0x0B, 0x46, 0x13,
++    0x05, 0x61, 0xBD, 0xB7, 0x22,
++    0x01, 0x69, 0xFA, 0xA0, 0xF7,
++    0x00, 0xD4, 0xCD, 0x02, 0x72,
++    0x0D, 0x2F, 0x68, 0xB1, 0xD6,
++    0x09, 0x63, 0x4E, 0x83, 0x5B,
++    0x0A, 0x2F, 0x5F, 0x55, 0x15,
++    0x05, 0xE5, 0xDC, 0x0A, 0x45,
++    0x0E, 0xBA, 0x89, 0x08, 0x92,
++    0x0B, 0x66, 0x87, 0xFE, 0x75,
++    0x01, 0xEF, 0x8B, 0x9F, 0x4E,
++    0x07, 0x68, 0xF3, 0x60, 0xF5,
++    0x08, 0xE3, 0x6A, 0xE4, 0x10,
++    0x0C, 0x10, 0x9C, 0x27, 0x22,
++    0x0F, 0x7A, 0x60, 0x45, 0x02,
++    0x03, 0xF6, 0x4D, 0x6F, 0xC9,
++    0x09, 0x98, 0x0C, 0x65, 0x1A,
++    0x0F, 0xB1, 0xE7, 0xAC, 0xB3,
++    0x07, 0xDD, 0x06, 0xB6, 0xEC,
++    0x06, 0xDF, 0x2A, 0x05, 0x2B,
++    0x07, 0xB8, 0x0C, 0xA9, 0x35,
++    0x05, 0x12, 0x19, 0xC6, 0xC7,
++    0x0D, 0x0E, 0xF0, 0xF9, 0x89,
++    0x0F, 0x17, 0x32, 0x8F, 0x7E,
++    0x01, 0xE7, 0xCD, 0x8E, 0xB0,
++    0x0E, 0x55, 0x60, 0x4D, 0x40,
++    0x01, 0x18, 0x4A, 0xD5, 0x86,
++    0x04, 0xDC, 0x8E, 0x95, 0xA7,
++    0x0C, 0xC2, 0x58, 0x11, 0xE2,
++    0x00, 0x49, 0x4E, 0x36, 0x0F,
++    0x00, 0x96, 0xDD, 0x61, 0xC5,
++    0x0A, 0x5C, 0xE0, 0xD8, 0x2D,
++    0x0D, 0x05, 0x8A, 0x57, 0x97,
++    0x00, 0x39, 0xD2, 0x7A, 0xEA,
++    0x04, 0x33, 0x85, 0xE9, 0xAB,
++    0x0D, 0xE1, 0xFF, 0x01, 0xB4,
++    0x0E, 0x64, 0x12, 0x1B, 0x93,
++    0x0F, 0x9B, 0x15, 0x27, 0xA9,
++    0x0B, 0x89, 0x88, 0x88, 0xE0,
++    0x00, 0x9C, 0xAB, 0x05, 0x0A,
++    0x05, 0x14, 0x26, 0xCF, 0xD1,
++    0x09, 0xBF, 0x29, 0x66, 0x68,
++    0x01, 0x94, 0x6D, 0x7F, 0x45,
++    0x0E, 0xB2, 0xCF, 0x1F, 0x74,
++    0x0A, 0xBB, 0x34, 0x5A, 0xFA,
++    0x08, 0x14, 0xAF, 0x2E, 0xE0,
++    0x03, 0xC5, 0x75, 0xD4, 0x48,
++    0x0B, 0x0B, 0xCA, 0xF4, 0x33,
++    0x03, 0xFE, 0x0F, 0x78, 0x6D,
++    0x08, 0x25, 0x3B, 0x41, 0x95,
++    0x06, 0x2A, 0x47, 0x9D, 0x67,
++    0x03, 0x11, 0x00, 0x80, 0x41,
++    0x05, 0x56, 0x0A, 0x53, 0x7A,
++    0x04, 0x56, 0x8D, 0xB2, 0x43,
++    0x06, 0x4D, 0xCC, 0xC2, 0xE3,
++    0x08, 0xD2, 0xFE, 0x8B, 0x1D,
++    0x05, 0x9E, 0x3E, 0xEC, 0x10,
++    0x08, 0x60, 0xB5, 0xF5, 0x50,
++};
++
++static u8 ak7755_cram_basic[]= {
++	0xB4, 0x00, 0x00,    // CRAM Write Command
++    0x00, 0x00, 0x00,  // EQ1 LPF fc = 125Hz
++    0x00, 0x42, 0x7A,
++    0x00, 0x00, 0x00,
++    0x1F, 0x7B, 0x0B,
++    0x00, 0x42, 0x7A,
++    0xFF, 0x50, 0x67,  // EQ2 BPF fo = 250Hz
++    0x00, 0x00, 0x00,
++    0xE2, 0x1C, 0x4C,
++    0x3D, 0xDB, 0x38,
++    0x00, 0xAF, 0x99,
++    0xFD, 0x7D, 0x8E,  // EQ3 BPF fo = 1000Hz
++    0x00, 0x00, 0x00,
++    0xE7, 0xB8, 0xC0,
++    0x37, 0xCB, 0xFE,
++    0x02, 0x82, 0x72,
++    0xF8, 0x9F, 0x19,  // EQ4 BPF fo = 4000Hz
++    0x00, 0x00, 0x00,
++    0xF6, 0xB4, 0x01,
++    0x23, 0xC3, 0x9E,
++    0x07, 0x60, 0xE7,
++    0x00, 0x00, 0x00,  // EQ5 HPF fc = 7500Hz
++    0xEB, 0x25, 0x7E,
++    0x00, 0x00, 0x00,
++    0x09, 0xB5, 0x04,
++    0x14, 0xDA, 0x82,
++    0x20, 0x00, 0x00, 
++    0x00, 0x00, 0x00, // EQ1 Gain
++    0x00, 0x00, 0x00, // EQ2 Gain
++    0x00, 0x00, 0x00, // EQ3 Gain
++    0x00, 0x00, 0x00, // EQ4 Gain
++    0x00, 0x00, 0x00, // EQ5 Gain
++    0x20, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00, // HPF1
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x20, 0x00, 0x00,
++    0x7D, 0x63, 0x00,
++    0x21, 0xF6, 0x00,
++    0x7D, 0x63, 0x00,
++    0x21, 0xF6, 0x00,
++    0x7F, 0xFA, 0x00,
++    0x55, 0x72, 0x00,
++    0xF8, 0x6E, 0x00,
++    0xE6, 0xDA, 0xB0,
++    0x17, 0x92, 0x00,
++    0x08, 0x00, 0x00,
++    0x00, 0x00, 0x00, // MIX_VOL_L
++    0x08, 0x00, 0x00,
++    0x00, 0x00, 0x00, // HPF2
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x00, 0x00, 0x00,
++    0x20, 0x00, 0x00,
++    0x08, 0x00, 0x00,
++    0x00, 0x00, 0x00,  // MIX_VOL_R
++};
++
++static u8 ak7755_pram_aec[]= {
++	0xB8,0x00,0x00,               // PRAM Write Command
++	0x0C, 0xB4, 0xED, 0x1E, 0x42,
++	0x04, 0xA9, 0x1C, 0x6D, 0x49,
++	0x04, 0x44, 0x82, 0x1A, 0x44,
++	0x0F, 0x58, 0x76, 0xCD, 0x88,
++	0x0D, 0x5A, 0x7E, 0x89, 0x1D,
++	0x03, 0x35, 0x29, 0x03, 0x8C,
++	0x0F, 0x4A, 0x05, 0x6C, 0x68,
++	0x0A, 0x70, 0xFE, 0x20, 0xE7,
++	0x01, 0x86, 0xD2, 0x15, 0x72,
++	0x09, 0x79, 0x37, 0xC3, 0xAE,
++	0x07, 0xAE, 0xA2, 0x4F, 0x79,
++	0x0E, 0xD9, 0xA1, 0xD2, 0xA2,
++	0x00, 0x7B, 0xE2, 0xEA, 0xAB,
++	0x09, 0xDA, 0x38, 0xF5, 0xEE,
++	0x02, 0x38, 0xDE, 0xB4, 0x07,
++	0x08, 0x04, 0x23, 0x05, 0x15,
++	0x0C, 0xDE, 0x9B, 0xD1, 0x73,
++	0x04, 0xFD, 0x92, 0x57, 0x99,
++	0x06, 0x67, 0xD8, 0x99, 0x75,
++	0x0B, 0xF4, 0x58, 0xEB, 0x2A,
++	0x0D, 0xF6, 0xA0, 0x2D, 0x8E,
++	0x09, 0xAF, 0xC4, 0x01, 0x43,
++	0x0E, 0xEC, 0x54, 0x3A, 0x4B,
++	0x06, 0xC1, 0x84, 0xF0, 0xBD,
++	0x0F, 0x42, 0x33, 0x3F, 0xFD,
++	0x0B, 0xC5, 0x8C, 0x02, 0x5A,
++	0x0F, 0xFB, 0x3C, 0x62, 0xA4,
++	0x0D, 0xB4, 0xE6, 0xF1, 0x0D,
++	0x04, 0x46, 0x63, 0x95, 0x68,
++	0x06, 0xB5, 0xD0, 0x85, 0x69,
++	0x07, 0x25, 0x38, 0xE4, 0xC9,
++	0x00, 0x06, 0x63, 0xCD, 0x26,
++	0x03, 0x33, 0x19, 0x59, 0xE3,
++	0x02, 0x82, 0xC8, 0xB6, 0x16,
++	0x03, 0x55, 0x73, 0x15, 0xEC,
++	0x07, 0x8C, 0x86, 0x9E, 0xBA,
++	0x05, 0x1C, 0xE1, 0x7B, 0x60,
++	0x0B, 0x68, 0x7F, 0xC1, 0xE8,
++	0x07, 0x98, 0xB3, 0xE7, 0x75,
++	0x0F, 0xE6, 0xA1, 0xC8, 0xEA,
++	0x01, 0x61, 0xAF, 0x20, 0x10,
++	0x00, 0x26, 0xEA, 0x03, 0x67,
++	0x02, 0x45, 0x68, 0xD3, 0xFF,
++	0x02, 0xEC, 0x04, 0xA9, 0x98,
++	0x07, 0xE1, 0x8D, 0x5F, 0xD1,
++	0x0F, 0xAC, 0xB3, 0xC7, 0xE3,
++	0x0A, 0xB7, 0x76, 0xD6, 0xA3,
++	0x06, 0x05, 0x58, 0x0B, 0xB1,
++	0x0C, 0xE9, 0x3F, 0x75, 0x12,
++	0x09, 0xC2, 0xF6, 0x4D, 0xC4,
++	0x00, 0xFF, 0x81, 0xDF, 0xDD,
++	0x0D, 0x89, 0x4E, 0xD1, 0xE7,
++	0x01, 0x8A, 0x91, 0xC6, 0xD3,
++	0x08, 0xC4, 0x40, 0x21, 0x1F,
++	0x05, 0xD2, 0xD0, 0xF4, 0xDC,
++	0x06, 0x14, 0x27, 0xAC, 0x8F,
++	0x03, 0x93, 0x53, 0x70, 0x29,
++	0x03, 0xB4, 0x5F, 0xAE, 0x87,
++	0x03, 0x67, 0x91, 0xBA, 0x4D,
++	0x0D, 0xD8, 0x2D, 0x7D, 0x4B,
++	0x0A, 0x57, 0x97, 0x70, 0x39,
++	0x0E, 0x7A, 0x15, 0xE4, 0x3B,
++	0x09, 0xEF, 0x65, 0xDD, 0xE5,
++	0x0F, 0x07, 0xBE, 0x2E, 0x6E,
++	0x02, 0x9D, 0xA3, 0xCF, 0x99,
++	0x09, 0x23, 0x4A, 0xAB, 0x80,
++	0x08, 0x80, 0x40, 0x30, 0x9C,
++	0x07, 0x0D, 0xE9, 0xB9, 0x2B,
++	0x02, 0xCF, 0x3B, 0x27, 0x3F,
++	0x0C, 0xA6, 0x43, 0xB1, 0xB4,
++	0x05, 0x5F, 0x45, 0x8E, 0x8D,
++	0x07, 0x1F, 0x74, 0x1A, 0xDB,
++	0x0C, 0x5B, 0x66, 0xA8, 0x09,
++	0x04, 0xA8, 0xA0, 0x7B, 0x96,
++	0x09, 0xD4, 0x37, 0xA7, 0x02,
++	0x07, 0x35, 0xBA, 0x03, 0xE3,
++	0x0F, 0x7C, 0x5E, 0xC8, 0x25,
++	0x03, 0x47, 0x1F, 0x3A, 0xA0,
++	0x0F, 0x9B, 0xF5, 0x13, 0xD1,
++	0x0A, 0x84, 0x4E, 0xB9, 0x76,
++	0x07, 0xD3, 0xFE, 0x68, 0x5E,
++	0x03, 0xB2, 0x71, 0xFE, 0x50,
++	0x07, 0x46, 0x56, 0xA8, 0xD2,
++	0x02, 0x8B, 0x60, 0xA5, 0x97,
++	0x0E, 0xE8, 0x37, 0xB7, 0x60,
++	0x0C, 0x75, 0xB0, 0x25, 0x5E,
++	0x04, 0x41, 0x07, 0x4B, 0x6B,
++	0x00, 0x96, 0x2E, 0x1B, 0xB6,
++	0x08, 0x77, 0x87, 0x79, 0xD4,
++	0x02, 0xB9, 0xBE, 0xCA, 0x36,
++	0x07, 0x3E, 0xEC, 0x50, 0xCE,
++	0x06, 0xAE, 0x26, 0x26, 0x8B,
++	0x02, 0xC2, 0x5D, 0xAC, 0x36,
++	0x0E, 0xE4, 0xD0, 0xAF, 0xBF,
++	0x04, 0x96, 0xFE, 0x9A, 0x99,
++	0x0C, 0xC7, 0xD3, 0xA5, 0xE0,
++	0x0E, 0x3A, 0x4B, 0x38, 0x7D,
++	0x08, 0xEB, 0xCE, 0xC1, 0xAB,
++	0x00, 0xA0, 0x13, 0xBC, 0x9B,
++	0x0D, 0xCE, 0xEF, 0xD7, 0x58,
++	0x01, 0x9C, 0x2D, 0x60, 0xC1,
++	0x0F, 0x0F, 0xF8, 0x3D, 0xF1,
++	0x0B, 0xA3, 0xB4, 0xEF, 0x9E,
++	0x05, 0xDE, 0x09, 0x10, 0x6D,
++	0x0C, 0x4C, 0x44, 0x02, 0x11,
++	0x04, 0xE5, 0x5A, 0x6A, 0x07,
++	0x02, 0xA1, 0x60, 0x7E, 0xE9,
++	0x01, 0xF8, 0x55, 0x33, 0x39,
++	0x00, 0xA3, 0x54, 0xBA, 0x15,
++	0x09, 0x96, 0x04, 0x7B, 0x9A,
++	0x0A, 0xDF, 0xD1, 0x97, 0xEE,
++	0x0B, 0x20, 0x77, 0x77, 0x03,
++	0x01, 0x27, 0xD2, 0xE2, 0x4A,
++	0x00, 0x5E, 0x5B, 0xA7, 0x9E,
++	0x0F, 0xF0, 0x79, 0xE4, 0x6C,
++	0x0B, 0x29, 0x9B, 0x3C, 0xF8,
++	0x0D, 0x52, 0x1B, 0x9A, 0xB0,
++	0x02, 0x48, 0x0C, 0xA3, 0x7E,
++	0x0A, 0xB0, 0xDE, 0x1B, 0x91,
++	0x02, 0xB4, 0xFE, 0x90, 0xD1,
++	0x0E, 0x68, 0x33, 0x03, 0x1D,
++	0x0C, 0x57, 0xF0, 0x58, 0x96,
++	0x0C, 0xF1, 0xF7, 0x41, 0xAD,
++	0x0B, 0x05, 0xAF, 0xBA, 0x81,
++	0x0A, 0xF2, 0xEE, 0x37, 0xB8,
++	0x0F, 0x5D, 0x44, 0xB6, 0x70,
++	0x01, 0xB3, 0x3F, 0xFC, 0x36,
++	0x00, 0xF7, 0xC7, 0xCC, 0x82,
++	0x03, 0xB4, 0x79, 0xF3, 0x62,
++	0x0C, 0x71, 0x37, 0x73, 0xB1,
++	0x0C, 0x09, 0xC4, 0xD3, 0x88,
++	0x09, 0xBD, 0x37, 0x22, 0x85,
++	0x0B, 0xFB, 0x24, 0xB1, 0xE4,
++	0x0C, 0xCC, 0x06, 0x32, 0x8D,
++	0x0F, 0x98, 0x31, 0xD6, 0x59,
++	0x0F, 0xEE, 0xDB, 0x5B, 0x7F,
++	0x0B, 0x5F, 0x57, 0x02, 0x95,
++	0x05, 0xDC, 0x0C, 0x70, 0x94,
++	0x06, 0x88, 0x91, 0x61, 0x66,
++	0x0D, 0x05, 0xF9, 0xFF, 0xC1,
++	0x04, 0x09, 0x18, 0x84, 0xA7,
++	0x04, 0xF3, 0xA6, 0x85, 0x41,
++	0x0F, 0x6B, 0x62, 0xA2, 0x3D,
++	0x09, 0x0C, 0xC7, 0x26, 0xC3,
++	0x03, 0xC8, 0xA7, 0x0A, 0x13,
++	0x0E, 0x49, 0x6D, 0xCD, 0xA3,
++	0x04, 0x0D, 0xEA, 0x1A, 0x42,
++	0x0A, 0xE1, 0x1D, 0xB7, 0x3C,
++	0x0D, 0x06, 0xB4, 0xEC, 0x16,
++	0x02, 0xAA, 0x76, 0xEB, 0xC2,
++	0x04, 0x1D, 0x73, 0xFD, 0x68,
++	0x02, 0x19, 0xC0, 0xF4, 0x52,
++	0x02, 0xF1, 0x7E, 0xC3, 0xC2,
++	0x0E, 0xB2, 0xE9, 0x42, 0xD1,
++	0x0E, 0x6B, 0x6A, 0x91, 0x06,
++	0x0F, 0xC4, 0x94, 0x40, 0x01,
++	0x08, 0x4E, 0x57, 0x86, 0xF4,
++	0x00, 0x8A, 0x61, 0xA7, 0xE5,
++	0x0E, 0xDE, 0x09, 0x93, 0x2D,
++	0x08, 0xCA, 0x36, 0xBD, 0x3D,
++	0x0B, 0x59, 0x26, 0x4F, 0xB3,
++	0x01, 0x6C, 0x4F, 0xED, 0x60,
++	0x08, 0x0A, 0x27, 0xD7, 0x79,
++	0x05, 0xD3, 0xAE, 0xEA, 0x20,
++	0x08, 0x07, 0x3C, 0x1A, 0x1D,
++	0x0D, 0xFF, 0x44, 0xFE, 0x27,
++	0x04, 0x12, 0x9F, 0xA3, 0xCF,
++	0x0B, 0x15, 0x23, 0x89, 0xA1,
++	0x05, 0x88, 0xCC, 0x42, 0x39,
++	0x00, 0xAB, 0x64, 0x29, 0xB0,
++	0x04, 0x2B, 0x4F, 0xDB, 0x97,
++	0x0F, 0x26, 0xA4, 0x62, 0x85,
++	0x08, 0x69, 0x3C, 0xC5, 0x87,
++	0x0E, 0xCE, 0x9F, 0x74, 0x07,
++	0x07, 0xB1, 0xD4, 0xFA, 0xB5,
++	0x0F, 0x2D, 0xDB, 0x60, 0x82,
++	0x08, 0xF4, 0x56, 0x08, 0x7A,
++	0x07, 0xDA, 0xD1, 0xFB, 0xC0,
++	0x07, 0x8F, 0x9C, 0x5C, 0x08,
++	0x0C, 0xBA, 0xA7, 0x9F, 0x76,
++	0x06, 0x47, 0x5F, 0x57, 0x1A,
++	0x01, 0x00, 0x8E, 0x65, 0xE7,
++	0x06, 0x1B, 0xD1, 0x76, 0x22,
++	0x04, 0x9F, 0xBA, 0x47, 0xBE,
++	0x0F, 0x4C, 0xC0, 0x65, 0x1B,
++	0x02, 0x7E, 0x2B, 0x1D, 0x65,
++	0x0E, 0x5E, 0x6A, 0x35, 0xB7,
++	0x00, 0xB5, 0xF5, 0x50, 0x29,
++	0x0E, 0x5D, 0xC0, 0xE3, 0x43,
++	0x07, 0xA8, 0xCB, 0x0E, 0x1E,
++	0x06, 0x68, 0x77, 0x81, 0xB6,
++	0x02, 0xF8, 0xF4, 0x90, 0x43,
++	0x06, 0x8F, 0x3C, 0x6A, 0x1E,
++	0x0E, 0x36, 0xAE, 0x20, 0x11,
++	0x0D, 0x09, 0x41, 0x72, 0xB1,
++	0x07, 0xA6, 0xE4, 0x50, 0xAD,
++	0x0D, 0x64, 0x96, 0xFA, 0x9A,
++	0x05, 0x81, 0x64, 0xD1, 0xB8,
++	0x0D, 0x66, 0xB8, 0xCB, 0x3C,
++	0x01, 0xD0, 0x2F, 0xAE, 0xC8,
++	0x0B, 0xEA, 0xA2, 0x56, 0xB6,
++	0x00, 0x03, 0x4F, 0x13, 0xD7,
++	0x0A, 0xA3, 0x1D, 0xAF, 0x6C,
++	0x0C, 0xEF, 0x9D, 0xB8, 0x20,
++	0x0D, 0x73, 0x33, 0x54, 0xE5,
++	0x05, 0xFE, 0xA4, 0x29, 0x1C,
++	0x01, 0x5D, 0xC9, 0xC4, 0x1F,
++	0x0D, 0x84, 0xA1, 0xD8, 0x66,
++	0x0D, 0xC8, 0xA1, 0x5A, 0xB6,
++	0x09, 0x2D, 0xFB, 0x31, 0x39,
++	0x01, 0x8C, 0xA1, 0x4F, 0xF0,
++	0x04, 0x75, 0x16, 0x74, 0x3B,
++	0x0C, 0xD6, 0x9A, 0x82, 0xDE,
++	0x09, 0x41, 0x05, 0x79, 0x6A,
++	0x08, 0x1F, 0xA6, 0x2E, 0xA2,
++	0x08, 0xBA, 0xDF, 0x59, 0xA1,
++	0x02, 0x1E, 0x73, 0x3B, 0xFF,
++	0x0E, 0x41, 0x29, 0xDA, 0x3C,
++	0x0B, 0xB1, 0x52, 0x3E, 0xDA,
++	0x00, 0x98, 0x88, 0x04, 0x23,
++	0x09, 0xBA, 0x30, 0xDE, 0x9B,
++	0x0D, 0x43, 0x28, 0xBD, 0x8F,
++	0x00, 0x74, 0x0E, 0x66, 0x03,
++	0x09, 0x46, 0x95, 0xF4, 0x58,
++	0x03, 0xAC, 0x53, 0xF3, 0x4B,
++	0x01, 0xBB, 0x6A, 0x6F, 0xA3,
++	0x0D, 0x4B, 0x6E, 0x6E, 0x1A,
++	0x01, 0xC9, 0x1D, 0x4D, 0x34,
++	0x08, 0xBD, 0xB1, 0x43, 0xBC,
++	0x07, 0xE0, 0x71, 0xC9, 0x46,
++	0x09, 0xD5, 0xF4, 0x70, 0x01,
++	0x0A, 0xA4, 0x73, 0xB5, 0x71,
++	0x09, 0x90, 0xAA, 0x4A, 0x99,
++	0x09, 0x61, 0x36, 0x37, 0x2B,
++	0x0D, 0x69, 0xF9, 0x24, 0xB7,
++	0x0C, 0xD4, 0xCE, 0x0F, 0x38,
++	0x01, 0x2F, 0x71, 0x31, 0xDF,
++	0x01, 0xE3, 0xEC, 0x83, 0x5B,
++	0x0E, 0x0B, 0x5D, 0x5C, 0x48,
++	0x09, 0xE4, 0x5D, 0x0E, 0x69,
++	0x02, 0xBB, 0x52, 0x8C, 0xD2,
++	0x07, 0x67, 0x5A, 0xF8, 0x4B,
++	0x0D, 0xEE, 0x6A, 0x19, 0x31,
++	0x0B, 0x68, 0x9D, 0x66, 0xCC,
++	0x04, 0xE1, 0x39, 0xE2, 0x66,
++	0x0C, 0x12, 0xDC, 0x27, 0x2F,
++	0x08, 0xFE, 0xA0, 0x45, 0xFB,
++	0x0F, 0xF7, 0xCA, 0xEF, 0xD4,
++	0x05, 0x99, 0xA9, 0x65, 0x07,
++	0x0D, 0xD1, 0x63, 0xAA, 0xB3,
++	0x0B, 0xD7, 0x06, 0xB6, 0xF0,
++	0x06, 0xCE, 0x28, 0x05, 0x2B,
++	0x07, 0xB8, 0x55, 0xA9, 0x34,
++	0x05, 0x12, 0x1B, 0xC6, 0xFC,
++	0x06, 0x8C, 0x71, 0x7F, 0x83,
++	0x04, 0x95, 0xB3, 0x89, 0x4E,
++	0x0D, 0xE7, 0x40, 0x0A, 0x98,
++	0x06, 0xD5, 0xC6, 0xC4, 0x40,
++	0x01, 0x18, 0x4C, 0x51, 0x8C,
++	0x08, 0xDC, 0xC1, 0x95, 0xAE,
++	0x00, 0x92, 0x4D, 0xD3, 0x4E,
++	0x0C, 0x18, 0xCA, 0x34, 0xB7,
++	0x09, 0x45, 0x25, 0xE7, 0x8F,
++	0x06, 0x0D, 0x41, 0x98, 0x25,
++	0x0D, 0x54, 0x0A, 0x53, 0xAC,
++	0x00, 0x39, 0xD0, 0x78, 0x50,
++	0x04, 0x33, 0x85, 0x63, 0x10,
++	0x0D, 0xE1, 0xFF, 0x89, 0x74,
++	0x02, 0x65, 0x92, 0x9D, 0xBE,
++	0x03, 0x9B, 0x63, 0x63, 0x84,
++	0x0B, 0x89, 0x88, 0x80, 0xB3,
++	0x08, 0x9C, 0x2B, 0x0F, 0x69,
++	0x03, 0x14, 0xA2, 0x4F, 0xF9,
++	0x05, 0xBF, 0x26, 0xA6, 0x51,
++	0x0D, 0x94, 0x25, 0x7F, 0x4C,
++	0x02, 0xB3, 0x49, 0x9F, 0x69,
++	0x0A, 0xDB, 0xB0, 0xDA, 0xFA,
++	0x08, 0x14, 0xAD, 0x2C, 0x52,
++	0x03, 0xA4, 0xF5, 0xD6, 0xFB,
++	0x0C, 0x88, 0xDC, 0x34, 0x3B,
++	0x03, 0xFE, 0x0D, 0x7C, 0x5C,
++	0x00, 0x25, 0x3B, 0xC9, 0xD5,
++	0x0E, 0x2A, 0xC5, 0x15, 0x5D,
++	0x03, 0x11, 0x02, 0x84, 0x61,
++	0x05, 0x57, 0x9B, 0xD3, 0x6F,
++	0x04, 0x56, 0xE9, 0xF2, 0x42,
++	0x0E, 0x4D, 0x4C, 0xC0, 0x92,
++	0x00, 0xD2, 0x7C, 0x89, 0x9D,
++	0x0F, 0x9E, 0xAF, 0xE8, 0x15,
++	0x07, 0x60, 0xB5, 0xF5, 0x61,
++	0x05, 0x5E, 0x12, 0x40, 0xEE,
++	0x05, 0xEA, 0x2F, 0x50, 0xD3,
++	0x0C, 0x35, 0x44, 0x77, 0x87,
++	0x0C, 0x1E, 0xFA, 0xB9, 0x90,
++	0x06, 0x76, 0xF9, 0x7E, 0x65,
++	0x0C, 0x8E, 0x36, 0xAE, 0x26,
++	0x0A, 0x01, 0x88, 0xC0, 0xF2,
++	0x06, 0x37, 0x30, 0xE4, 0x70,
++	0x01, 0x3F, 0x0C, 0xD6, 0xF5,
++	0x0A, 0x99, 0x80, 0xC6, 0x5B,
++	0x09, 0xFD, 0x59, 0xFA, 0xC2,
++	0x04, 0x85, 0x70, 0xE7, 0x6E,
++	0x01, 0x6B, 0xEA, 0xA2, 0xE6,
++	0x0C, 0xBB, 0x81, 0xCC, 0x26,
++	0x0B, 0x51, 0x54, 0x5C, 0x26,
++	0x00, 0xD1, 0x5E, 0xCF, 0xE5,
++	0x05, 0xF1, 0xF3, 0x2D, 0xD4,
++	0x05, 0x1C, 0x7C, 0xD5, 0xA9,
++	0x04, 0x6F, 0x5C, 0x4C, 0x84,
++	0x02, 0x11, 0x84, 0x61, 0x52,
++	0x0F, 0x4D, 0xC8, 0x25, 0x50,
++	0x0E, 0xC9, 0x2D, 0xF9, 0x3F,
++	0x09, 0x01, 0x11, 0xA3, 0x4F,
++	0x0A, 0x2C, 0x75, 0x9A, 0x72,
++	0x0B, 0xA0, 0xD4, 0xDD, 0x82,
++	0x0B, 0xD5, 0x0C, 0xA5, 0x70,
++	0x07, 0x03, 0x9F, 0x27, 0xAE,
++	0x02, 0x43, 0x38, 0xD2, 0x53,
++	0x01, 0xDE, 0x1D, 0xFC, 0xB1,
++	0x0E, 0xE6, 0x31, 0x29, 0xD3,
++	0x00, 0xF8, 0x35, 0x12, 0x25,
++	0x0A, 0xB8, 0x9A, 0x88, 0x04,
++	0x0F, 0x08, 0x6D, 0x30, 0xC3,
++	0x09, 0x91, 0x42, 0xB6, 0x7D,
++	0x02, 0x5B, 0xF2, 0x6A, 0x66,
++	0x03, 0x69, 0xC6, 0x97, 0xF4,
++	0x04, 0xEB, 0x79, 0x71, 0xFE,
++	0x01, 0xAD, 0xB9, 0x01, 0xA5,
++	0x01, 0x03, 0xCB, 0x72, 0xEE,
++	0x0C, 0xB8, 0xCE, 0xDD, 0x44,
++	0x0A, 0x70, 0x30, 0x73, 0x4A,
++	0x0C, 0x3F, 0xE2, 0xF7, 0xC5,
++	0x0C, 0x82, 0x51, 0xB0, 0x73,
++	0x0F, 0x62, 0xF3, 0xB1, 0xBC,
++	0x0D, 0x31, 0x82, 0x48, 0x5B,
++	0x0F, 0x95, 0x61, 0x3D, 0x3F,
++	0x09, 0x07, 0x15, 0x7B, 0x24,
++	0x07, 0xE4, 0xD6, 0xC8, 0x3D,
++	0x02, 0x8D, 0x2F, 0x66, 0x7B,
++	0x06, 0x59, 0xE1, 0xEE, 0x83,
++	0x07, 0x76, 0x40, 0xDF, 0x5C,
++	0x02, 0x95, 0xE7, 0xDC, 0x0E,
++	0x04, 0x9E, 0xBA, 0x89, 0x0C,
++	0x01, 0x7B, 0x64, 0x85, 0xC2,
++	0x0F, 0xC1, 0xED, 0x8B, 0x99,
++	0x08, 0xA7, 0x32, 0x33, 0xEF,
++	0x09, 0x49, 0x63, 0x6A, 0xFF,
++	0x0E, 0x21, 0x9A, 0xCC, 0x3A,
++	0x0A, 0xC3, 0x7A, 0xEE, 0xB4,
++	0x0A, 0xD3, 0xF4, 0x4B, 0xDD,
++	0x02, 0x2A, 0x8D, 0x8E, 0xD6,
++	0x0A, 0x5F, 0xD3, 0x63, 0xAC,
++	0x03, 0xC7, 0xDD, 0x88, 0xFC,
++	0x0C, 0x16, 0xBE, 0x24, 0x0F,
++	0x0B, 0xCB, 0xB8, 0x1C, 0xE9,
++	0x0D, 0x75, 0x10, 0x1B, 0x70,
++	0x06, 0xCD, 0x0C, 0xF0, 0xFF,
++	0x0F, 0xDE, 0x97, 0x32, 0x14,
++	0x02, 0xD1, 0x90, 0xCD, 0x83,
++	0x01, 0xC6, 0xD5, 0xC4, 0x35,
++	0x08, 0x21, 0x9A, 0x4C, 0xD5,
++	0x0C, 0xF4, 0x69, 0x0A, 0x35,
++	0x07, 0xEC, 0x92, 0xDF, 0xA2,
++	0x0F, 0x30, 0x46, 0x8A, 0x3D,
++	0x03, 0xA3, 0x4C, 0xD9, 0x7A,
++	0x04, 0x39, 0x21, 0x6D, 0xD8,
++	0x0D, 0x7D, 0x56, 0x0A, 0x57,
++	0x0B, 0x70, 0x4E, 0xD2, 0x73,
++	0x02, 0x24, 0x33, 0x85, 0xED,
++	0x02, 0x1D, 0x61, 0xFD, 0x87,
++	0x04, 0x2E, 0xDE, 0x92, 0xBD,
++	0x0F, 0xCF, 0xF0, 0xD5, 0x2A,
++	0x0D, 0xAB, 0x89, 0x88, 0x8A,
++	0x0E, 0x30, 0xC2, 0x2B, 0x04,
++	0x01, 0x41, 0xB4, 0xA7, 0x4F,
++	0x09, 0x25, 0xBF, 0x24, 0x12,
++	0x00, 0x31, 0x94, 0x6B, 0xCA,
++	0x09, 0x8E, 0xC4, 0x4F, 0x16,
++	0x08, 0x1B, 0x69, 0xB0, 0x47,
++	0x02, 0xA8, 0x94, 0xA2, 0x6E,
++	0x08, 0x71, 0xA4, 0xF8, 0xD4,
++	0x00, 0x65, 0x0B, 0xDB, 0xF4,
++	0x0B, 0xC3, 0xFE, 0x8B, 0x76,
++	0x0C, 0xC8, 0x25, 0xBF, 0x4D,
++	0x0F, 0x36, 0x2A, 0x47, 0x11,
++	0x0D, 0x13, 0xD0, 0x80, 0x80,
++	0x01, 0x39, 0x56, 0x17, 0xD9,
++	0x02, 0x28, 0x54, 0x9F, 0xB2,
++	0x07, 0x7E, 0x17, 0x8C, 0xC9,
++	0x03, 0x28, 0xD0, 0xFE, 0x8B,
++	0x0D, 0x65, 0x9E, 0xB2, 0x62,
++	0x05, 0xB7, 0x62, 0xB9, 0x3F,
++	0x0C, 0x28, 0xDF, 0xDD, 0xDD,
++	0x07, 0x49, 0xE9, 0xA8, 0x90,
++	0x02, 0x17, 0xFA, 0xE8, 0x7E,
++	0x0B, 0xFC, 0x45, 0xB8, 0xB0,
++	0x08, 0x4A, 0xF6, 0x8D, 0xBE,
++	0x04, 0xD4, 0x2C, 0x34, 0x2E,
++	0x0A, 0x22, 0x55, 0xC8, 0xFB,
++	0x0E, 0xAD, 0x7A, 0x26, 0xDC,
++	0x0B, 0x28, 0x1B, 0x64, 0x6D,
++	0x00, 0x9A, 0xE6, 0xC0, 0xCF,
++	0x01, 0xA5, 0xFF, 0x16, 0x3A,
++	0x0B, 0x3C, 0x7D, 0x54, 0x61,
++	0x0E, 0xC1, 0x69, 0xEE, 0xEA,
++	0x0E, 0xBD, 0x3D, 0x81, 0xD3,
++	0x0F, 0xD7, 0x1D, 0xA1, 0x95,
++	0x0F, 0x6C, 0xD2, 0xEF, 0xCB,
++	0x08, 0x3D, 0xF1, 0xF3, 0x20,
++	0x0C, 0x6D, 0xBE, 0xF8, 0xD8,
++	0x01, 0x1C, 0xED, 0x5E, 0xCC,
++	0x04, 0x02, 0x11, 0x86, 0x57,
++	0x04, 0x6F, 0x18, 0xC8, 0xA8,
++	0x0A, 0x7E, 0xCA, 0xA9, 0xB3,
++	0x05, 0x33, 0x03, 0x8A, 0xE1,
++	0x07, 0xFB, 0x0C, 0x75, 0x92,
++	0x08, 0xFB, 0xA0, 0xD6, 0xDD,
++	0x02, 0xD7, 0xD5, 0x40, 0xA5,
++	0x05, 0x77, 0x3C, 0x5D, 0x23,
++	0x0E, 0xA2, 0x43, 0x38, 0xE4,
++	0x09, 0xA1, 0xDE, 0x11, 0x72,
++	0x07, 0xE3, 0x79, 0x81, 0x2D,
++	0x06, 0x3C, 0x74, 0x31, 0x5B,
++	0x08, 0xDA, 0xBA, 0x98, 0x88,
++	0x04, 0x23, 0x09, 0xCA, 0xB0,
++	0x0E, 0x9B, 0x91, 0x40, 0x36,
++	0x01, 0x90, 0x14, 0x32, 0x6E,
++	0x0A, 0x03, 0x94, 0x86, 0x9E,
++	0x04, 0x58, 0xEB, 0x2C, 0xF1,
++	0x07, 0x41, 0xAD, 0xBB, 0x05,
++	0x0F, 0xAA, 0x83, 0x48, 0x70,
++	0x02, 0x07, 0x77, 0x0F, 0x54,
++	0x08, 0x87, 0xDC, 0x3D, 0xAE,
++	0x08, 0x3E, 0xBE, 0x60, 0xF7,
++	0x0E, 0x4E, 0x03, 0xD3, 0xB4,
++	0x05, 0xF3, 0xFD, 0x64, 0x75,
++	0x09, 0x70, 0xB1, 0x10, 0x15,
++	0x06, 0x13, 0x97, 0x67, 0xBF,
++	0x07, 0x22, 0x87, 0x6D, 0xF1,
++	0x08, 0xB7, 0x6F, 0xD4, 0xC5,
++	0x0A, 0x33, 0x08, 0x2F, 0xF5,
++	0x01, 0xD6, 0x5B, 0xE3, 0xEE,
++	0x0F, 0x5A, 0xD3, 0x0B, 0x42,
++	0x07, 0x02, 0x95, 0x67, 0x5C,
++	0x0E, 0x74, 0x9E, 0xBA, 0x89,
++	0x0C, 0x91, 0xFB, 0x66, 0x87,
++	0x08, 0x7F, 0xC1, 0xEF, 0x8B,
++	0x09, 0x04, 0xA5, 0x6C, 0xF9,
++	0x0D, 0x47, 0xC9, 0x63, 0x6A,
++	0x09, 0xE0, 0xA1, 0x90, 0x8C,
++	0x0B, 0x28, 0x56, 0x7A, 0x6A,
++	0x05, 0x0A, 0xD1, 0xF6, 0x49,
++	0x0F, 0xC9, 0xA8, 0x98, 0x0C,
++	0x05, 0x1A, 0x5D, 0xD5, 0x69,
++	0x0C, 0xB3, 0xC7, 0xD9, 0x04,
++	0x0A, 0xEC, 0x8F, 0x3E, 0xA3,
++	0x09, 0x2A, 0x4E, 0xB8, 0x01,
++	0x09, 0x3D, 0x77, 0x12, 0x19,
++	0x0E, 0xF7, 0x68, 0x0E, 0xED,
++	0x0D, 0x83, 0xDF, 0x95, 0xB2,
++	0x09, 0x4E, 0xD1, 0xE7, 0xCD,
++	0x0A, 0xE1, 0x46, 0xD5, 0xC4,
++	0x04, 0x40, 0x21, 0x18, 0x4E,
++	0x05, 0x86, 0xF6, 0xD8, 0x80,
++	0x0E, 0x25, 0x6D, 0x12, 0xDF,
++	0x08, 0xD1, 0xB1, 0x98, 0xCA,
++	0x08, 0xBF, 0x2C, 0x87, 0x50,
++	0x0B, 0x8F, 0x45, 0xCD, 0x69,
++	0x08, 0x2D, 0x7F, 0x54, 0x0A,
++	0x07, 0x97, 0x72, 0x3D, 0xD8,
++	0x0A, 0xEA, 0x24, 0x37, 0x87,
++	0x01, 0x9A, 0x5D, 0xE1, 0xFB,
++	0x0B, 0xBE, 0x8E, 0x64, 0x16,
++	0x01, 0xA2, 0x4B, 0x5B, 0x08,
++	0x0F, 0x8D, 0xFA, 0x89, 0x81,
++	0x08, 0x42, 0xB0, 0x9C, 0x2B,
++	0x0F, 0xE9, 0xB9, 0x14, 0xAB,
++	0x03, 0xD9, 0xB7, 0xFF, 0x3B,
++	0x06, 0x11, 0xB1, 0x94, 0x69,
++	0x03, 0x45, 0x9D, 0xF2, 0xC7,
++	0x04, 0xF6, 0x64, 0x5B, 0xB0,
++	0x06, 0xFB, 0x28, 0xD4, 0xB2,
++	0x07, 0x60, 0x93, 0xA8, 0xF5,
++	0x0D, 0xCE, 0x87, 0x0B, 0x1B,
++	0x08, 0x3A, 0x43, 0xBE, 0x12,
++	0x0C, 0x5C, 0xC8, 0x25, 0x3B,
++	0x0E, 0x1E, 0xD4, 0x2A, 0x87,
++	0x0B, 0x57, 0x11, 0x15, 0x0A,
++	0x08, 0x60, 0xB6, 0x56, 0x06,
++	0x0F, 0x72, 0x79, 0x56, 0x96,
++	0x02, 0x4B, 0x7C, 0x4D, 0x4C,
++	0x00, 0x63, 0x28, 0xD2, 0xFE,
++	0x03, 0x1D, 0xE7, 0x9C, 0xBE,
++	0x04, 0x35, 0xE4, 0xE0, 0xBC,
++	0x0D, 0x50, 0x2B, 0x5E, 0x5D,
++	0x0C, 0xE6, 0x89, 0xEB, 0x91,
++	0x09, 0xCE, 0xD7, 0xB4, 0xE8,
++	0x0F, 0x05, 0xBC, 0x10, 0xB8,
++	0x03, 0x90, 0xB1, 0x76, 0x87,
++	0x07, 0x6D, 0x94, 0x82, 0x36,
++	0x07, 0xA6, 0xC2, 0x01, 0x08,
++	0x02, 0x72, 0xAC, 0x33, 0x2C,
++	0x0C, 0x50, 0xAF, 0x3F, 0x64,
++	0x0A, 0xFC, 0xCB, 0xD9, 0x89,
++	0x0D, 0xD3, 0x14, 0xF9, 0xED,
++	0x0A, 0xCB, 0x3E, 0x7D, 0xD0,
++	0x07, 0x6E, 0x92, 0xAB, 0xE3,
++	0x00, 0x52, 0xBE, 0xB7, 0x0B,
++	0x02, 0x92, 0x57, 0x91, 0x3C,
++	0x05, 0xAF, 0x8C, 0xDC, 0xEF,
++	0x06, 0x7E, 0xDD, 0xF1, 0xB3,
++	0x00, 0x94, 0xED, 0x1E, 0x7C,
++	0x08, 0xA9, 0x1C, 0x69, 0xA7,
++	0x00, 0x45, 0x91, 0xD1, 0x99,
++	0x09, 0x58, 0x1E, 0x8D, 0xC1,
++	0x0D, 0x5B, 0xBE, 0xC9, 0x29,
++	0x02, 0xB7, 0xE2, 0x81, 0x8C,
++	0x0F, 0x4B, 0xAE, 0x2C, 0x7C,
++	0x06, 0x78, 0xF9, 0xA0, 0xD6,
++	0x0D, 0x82, 0xD5, 0xD1, 0x4A,
++	0x09, 0x79, 0x28, 0xC3, 0x94,
++	0x0B, 0xAF, 0x08, 0x43, 0x25,
++	0x05, 0x5B, 0x20, 0x5E, 0x1F,
++	0x0B, 0xF9, 0x63, 0x66, 0x41,
++	0x05, 0xDB, 0xB8, 0x79, 0xAC,
++	0x02, 0x38, 0xDA, 0xB8, 0x98,
++	0x0A, 0x04, 0x23, 0x0F, 0xCA,
++	0x00, 0xDE, 0x9B, 0x91, 0x42,
++	0x04, 0x8D, 0x12, 0x5B, 0xF2,
++	0x06, 0x67, 0x82, 0xD9, 0x5B,
++	0x07, 0xF4, 0x58, 0xEB, 0x2C,
++	0x09, 0x77, 0xE1, 0xAD, 0x7B,
++	0x0F, 0xAE, 0xA1, 0x01, 0x0A,
++	0x02, 0xEE, 0x07, 0x3E, 0x7D,
++	0x07, 0x45, 0x95, 0xF0, 0xBC,
++	0x0F, 0x43, 0xC2, 0x7F, 0xE9,
++	0x07, 0xC5, 0xCE, 0x82, 0x53,
++	0x0D, 0xF9, 0x13, 0x6E, 0xA4,
++	0x08, 0x34, 0x91, 0x33, 0x90,
++	0x00, 0xC0, 0xF3, 0x99, 0x61,
++	0x0D, 0x37, 0x22, 0x00, 0xA3,
++	0x01, 0x25, 0xA5, 0x64, 0xF4,
++	0x04, 0x86, 0x90, 0x8F, 0xAF,
++	0x01, 0xB1, 0x16, 0x5D, 0xE3,
++	0x02, 0x81, 0xC7, 0x76, 0x0F,
++	0x03, 0x55, 0x51, 0x55, 0xF8,
++	0x07, 0x88, 0x4E, 0x1E, 0xBA,
++	0x09, 0x0C, 0xE1, 0x7F, 0x54,
++	0x0D, 0x79, 0x6C, 0xC1, 0xEE,
++	0x0B, 0x99, 0x06, 0xA3, 0x62,
++	0x03, 0xE6, 0xC5, 0x48, 0xE3,
++	0x0A, 0xE2, 0x62, 0x20, 0x10,
++	0x00, 0x26, 0xB7, 0xC3, 0x67,
++	0x02, 0x45, 0x6B, 0x13, 0xFF,
++	0x02, 0xE9, 0xB7, 0x29, 0x98,
++	0x0C, 0x65, 0x18, 0x5F, 0xD1,
++	0x0B, 0x2C, 0x11, 0xC3, 0xD7,
++	0x06, 0xB6, 0xEC, 0x10, 0x84,
++	0x06, 0x07, 0x2B, 0xCB, 0x8A,
++	0x00, 0xE8, 0x40, 0x75, 0x0F,
++	0x05, 0xC2, 0x82, 0x8D, 0x07,
++	0x0B, 0x7B, 0x45, 0x5F, 0x17,
++	0x02, 0x09, 0x4E, 0xDF, 0xE7,
++	0x0D, 0x8A, 0x91, 0xC8, 0xD5,
++	0x08, 0xC4, 0x40, 0x21, 0x1E,
++	0x02, 0x45, 0x86, 0xF4, 0xDB,
++	0x06, 0x14, 0xDB, 0xEC, 0x8F,
++	0x03, 0x93, 0xAB, 0x30, 0x11,
++	0x01, 0xB3, 0xF0, 0xA2, 0xC7,
++	0x05, 0x66, 0x14, 0x7A, 0x10,
++	0x0D, 0xD8, 0x2D, 0x7D, 0x54,
++	0x0A, 0x57, 0x97, 0x70, 0xCE,
++	0x0E, 0x7B, 0x03, 0xE4, 0x2E,
++	0x0E, 0x6F, 0x15, 0x1D, 0xE1,
++	0x03, 0x07, 0xBB, 0x2E, 0x6D,
++	0x02, 0x9D, 0xA1, 0xC3, 0x8A,
++	0x09, 0x23, 0xCD, 0xAB, 0xBE,
++	0x00, 0x03, 0x62, 0x32, 0x1C,
++	0x03, 0x07, 0xC9, 0xB4, 0xD4,
++	0x01, 0x4E, 0xE2, 0xA5, 0x9F,
++	0x06, 0xA6, 0x61, 0x35, 0xDE,
++	0x01, 0x7E, 0xC5, 0x82, 0xB2,
++	0x05, 0x1E, 0x9B, 0x9A, 0xFB,
++	0x0C, 0x5A, 0xFA, 0xA8, 0x1D,
++	0x0F, 0x2E, 0xE0, 0xF3, 0xA4,
++	0x0D, 0xD4, 0xC8, 0xE5, 0x8B,
++	0x03, 0xB4, 0x9B, 0x41, 0x7E,
++	0x06, 0x7C, 0x9C, 0x4A, 0xA5,
++	0x02, 0xC7, 0x7F, 0xB4, 0xAA,
++	0x07, 0x1B, 0x57, 0x91, 0xAA,
++	0x00, 0x84, 0x61, 0xBB, 0xEC,
++	0x0B, 0xD3, 0x72, 0xAA, 0xEF,
++	0x0F, 0xB2, 0x4B, 0xFC, 0xF5,
++	0x0C, 0xC0, 0x63, 0xAA, 0x65,
++	0x0E, 0x8B, 0x1D, 0xE7, 0x28,
++	0x0E, 0xE8, 0x35, 0x35, 0xD5,
++	0x05, 0xF5, 0x50, 0xAB, 0xEA,
++	0x0D, 0xC0, 0xE7, 0xCB, 0x58,
++	0x08, 0x90, 0xCE, 0x95, 0x04,
++	0x08, 0x77, 0x87, 0x7E, 0xAF,
++	0x08, 0xB9, 0x90, 0xC8, 0xC6,
++	0x0F, 0x3E, 0x6C, 0xD6, 0x08,
++	0x06, 0xAE, 0x26, 0xA0, 0x86,
++	0x08, 0xC2, 0x70, 0xAE, 0xB3,
++	0x06, 0xE4, 0x50, 0xAF, 0xBA,
++	0x08, 0x96, 0xFC, 0x9A, 0xA7,
++	0x0E, 0xC6, 0x51, 0xA5, 0xFD,
++	0x09, 0xBA, 0xCB, 0x3C, 0x7D,
++	0x0C, 0x6B, 0x6E, 0xC1, 0x62,
++	0x0A, 0xA0, 0x50, 0xBC, 0xBB,
++	0x01, 0xCE, 0x93, 0x51, 0x5B,
++	0x01, 0x9C, 0x2F, 0xEA, 0x9A,
++	0x0F, 0x0F, 0xF8, 0xBB, 0x7B,
++	0x03, 0x20, 0x94, 0x6B, 0xD4,
++	0x0C, 0xD8, 0xA9, 0x92, 0xA7,
++	0x0C, 0x4C, 0x44, 0x8C, 0x9B,
++	0x04, 0xE5, 0x58, 0xE1, 0x07,
++	0x08, 0xA1, 0x5A, 0xF0, 0xC3,
++	0x0D, 0xF9, 0x35, 0xBE, 0xCB,
++	0x0C, 0xA3, 0x4B, 0x77, 0xA6,
++	0x05, 0x96, 0x78, 0x76, 0xEA,
++	0x06, 0xDD, 0x82, 0x5A, 0xDF,
++	0x00, 0xA5, 0x79, 0xFB, 0xC9,
++	0x0D, 0x27, 0xAE, 0x2E, 0xC9,
++	0x08, 0x5E, 0xD9, 0x2D, 0x94,
++	0x0F, 0xF0, 0x7B, 0x6E, 0xEC,
++	0x01, 0x29, 0xDA, 0xBF, 0x73,
++	0x01, 0x52, 0x38, 0x59, 0x72,
++	0x08, 0x88, 0x04, 0xA0, 0x03,
++	0x0A, 0xB0, 0xDC, 0x98, 0xDB,
++	0x0D, 0x34, 0xFD, 0x92, 0x5B,
++	0x02, 0x6A, 0x67, 0x03, 0x13,
++	0x06, 0x97, 0xF6, 0x54, 0xE1,
++	0x00, 0xF1, 0xF7, 0x41, 0xAB,
++	0x07, 0x15, 0xAF, 0xAA, 0x86,
++	0x06, 0xF2, 0xE6, 0x07, 0x00,
++	0x03, 0x5D, 0x44, 0x86, 0x42,
++	0x01, 0xB0, 0x43, 0xBC, 0x0C,
++	0x0B, 0x76, 0x3D, 0xCC, 0x82,
++	0x0F, 0xB5, 0x19, 0xF3, 0x50,
++	0x08, 0x73, 0x35, 0x71, 0x02,
++	0x0B, 0x89, 0xBE, 0x13, 0x95,
++	0x0D, 0xBD, 0x57, 0x22, 0xB7,
++	0x05, 0xF8, 0xE4, 0xB7, 0xD7,
++	0x0F, 0x4D, 0xFE, 0x32, 0x8D,
++	0x03, 0xEA, 0xA1, 0xD6, 0x6B,
++	0x0F, 0xEC, 0x43, 0x5B, 0x45,
++	0x00, 0xDE, 0xAD, 0x02, 0x95,
++	0x09, 0xDE, 0x5B, 0x34, 0xAC,
++	0x06, 0x8B, 0x4C, 0xE1, 0x48,
++	0x0D, 0x06, 0x80, 0x7F, 0xC1,
++	0x03, 0x8B, 0x59, 0x04, 0x95,
++	0x04, 0xF2, 0xE6, 0xC5, 0x7B,
++	0x08, 0xEB, 0x1A, 0x62, 0x20,
++	0x0C, 0x8C, 0x27, 0x2A, 0xFD,
++	0x06, 0x7E, 0x45, 0x0A, 0xD5,
++	0x0A, 0x49, 0x2F, 0xC9, 0x9E,
++	0x04, 0x3E, 0x65, 0x1A, 0x6D,
++	0x0D, 0x61, 0x2C, 0xB3, 0xC3,
++	0x01, 0x04, 0x16, 0xEC, 0x13,
++	0x05, 0x28, 0x14, 0x2B, 0xCB,
++	0x04, 0x1C, 0xA9, 0x3D, 0x42,
++	0x0E, 0x2B, 0xC2, 0xF6, 0xFF,
++	0x02, 0xF2, 0x3F, 0x83, 0xDB,
++	0x0B, 0x30, 0xE9, 0x4E, 0xD4,
++	0x0C, 0x4F, 0x9B, 0x91, 0xC6,
++	0x09, 0xC4, 0x84, 0x40, 0x16,
++	0x04, 0x7C, 0x55, 0x86, 0xC6,
++	0x00, 0x88, 0x55, 0xA7, 0xE8,
++	0x0E, 0xDD, 0xF3, 0x53, 0x35,
++	0x03, 0x48, 0x25, 0xBF, 0xA2,
++	0x0B, 0x59, 0x27, 0x8F, 0x8D,
++	0x01, 0x5F, 0xD8, 0x2D, 0x4F,
++	0x08, 0x0B, 0x57, 0x97, 0x74,
++	0x05, 0xD3, 0x5A, 0xEA, 0x21,
++	0x08, 0x07, 0xFC, 0x9A, 0x1D,
++	0x0D, 0xFF, 0x47, 0xBE, 0x19,
++	0x08, 0x20, 0x9D, 0xA3, 0xFD,
++	0x07, 0x16, 0x23, 0x8D, 0xAF,
++	0x05, 0x8B, 0xA0, 0x42, 0x35,
++	0x07, 0x29, 0x1C, 0xE9, 0xB9,
++	0x08, 0x2B, 0x4F, 0x99, 0x2B,
++	0x03, 0x26, 0xA6, 0x20, 0x09,
++	0x08, 0x6A, 0x7F, 0x45, 0xB7,
++	0x0E, 0xCF, 0x1C, 0xF4, 0x20,
++	0x07, 0xB0, 0x5A, 0xFA, 0x93,
++	0x0C, 0xAF, 0xAE, 0xE0, 0x73,
++	0x0F, 0x77, 0xCF, 0xC8, 0x67,
++	0x0B, 0xDB, 0x34, 0x35, 0x87,
++	0x05, 0x8D, 0x0D, 0x5F, 0xCD,
++	0x09, 0x3B, 0x47, 0xDF, 0x38,
++	0x06, 0x47, 0x1B, 0x17, 0x2B,
++	0x0D, 0x02, 0x04, 0x61, 0x00,
++	0x0A, 0x1B, 0xD0, 0xF2, 0x12,
++	0x0A, 0x9F, 0xB2, 0x4B, 0x45,
++	0x05, 0x4C, 0x40, 0x63, 0x28,
++	0x09, 0x7C, 0x90, 0x9D, 0x65,
++	0x0E, 0x3E, 0xE8, 0x3B, 0xF3,
++	0x0B, 0x37, 0x84, 0x53, 0x2C,
++	0x02, 0x5D, 0xC0, 0xA7, 0x47,
++	0x07, 0xA8, 0x90, 0x8E, 0x2F,
++	0x0A, 0x6A, 0xB7, 0x87, 0xC5,
++	0x02, 0xF8, 0xBA, 0x10, 0x70,
++	0x0A, 0x8F, 0x3E, 0x6C, 0x6F,
++	0x06, 0x36, 0x2E, 0x26, 0x22,
++	0x0A, 0x8A, 0xD9, 0xF2, 0xAC,
++	0x07, 0xA6, 0xE4, 0x5E, 0xE9,
++	0x04, 0xE6, 0xE7, 0xFF, 0x9F,
++	0x05, 0x80, 0xC6, 0x11, 0xAB,
++	0x01, 0x16, 0x3A, 0x8B, 0x04,
++	0x01, 0xD2, 0x2B, 0x6E, 0xF8,
++	0x07, 0xEA, 0xA3, 0xD2, 0x86,
++	0x07, 0x81, 0xCE, 0x93, 0xEC,
++	0x09, 0x21, 0x1C, 0x2F, 0x6C,
++	0x0B, 0x6D, 0x14, 0x78, 0x3D,
++	0x01, 0x73, 0x20, 0x9A, 0xA9,
++	0x05, 0xFE, 0xA9, 0xAA, 0x19,
++	0x01, 0x5C, 0x4C, 0x04, 0x0C,
++	0x0D, 0x84, 0xE5, 0x18, 0x57,
++	0x01, 0xC9, 0xA1, 0x5A, 0x47,
++	0x05, 0x2D, 0xFA, 0xB5, 0x09,
++	0x0D, 0x8C, 0xA3, 0x4B, 0xC1,
++	0x04, 0x75, 0x16, 0x78, 0xFB,
++	0x0B, 0x54, 0xC6, 0x02, 0xD7,
++	0x05, 0x40, 0xA5, 0x77, 0x33,
++	0x08, 0x1F, 0x56, 0xAD, 0xA7,
++	0x0F, 0x3B, 0x5E, 0xD9, 0x95,
++	0x02, 0x1F, 0xC7, 0xFB, 0xDA,
++	0x0D, 0xC7, 0x2E, 0xD4, 0x21,
++	0x05, 0xB0, 0xD2, 0x78, 0xC7,
++	0x08, 0x98, 0x88, 0x04, 0x23,
++	0x01, 0xCA, 0x30, 0xDE, 0x5B,
++	0x0B, 0x43, 0x74, 0xFD, 0xB2,
++	0x07, 0xC0, 0x6A, 0x66, 0x35,
++	0x05, 0x46, 0xD7, 0xF4, 0x6F,
++	0x07, 0x2E, 0x71, 0xF7, 0x79,
++	0x01, 0xBB, 0xC5, 0xAF, 0x93,
++	0x0A, 0xCC, 0x6B, 0xEE, 0x07,
++	0x06, 0x4F, 0x72, 0x44, 0x9B,
++	0x0C, 0xBC, 0x13, 0x43, 0x8A,
++	0x03, 0xE0, 0xD7, 0x85, 0xF4,
++	0x0E, 0x52, 0x00, 0x39, 0xC9,
++	0x0E, 0xA4, 0xF1, 0xB5, 0x4A,
++	0x0A, 0x96, 0x96, 0xC6, 0x13,
++	0x09, 0x61, 0x35, 0x77, 0x14,
++	0x0E, 0xEE, 0xB0, 0x29, 0x3E,
++	0x08, 0xD4, 0x9F, 0xC6, 0x06,
++	0x01, 0x2F, 0x6E, 0x31, 0xE3,
++	0x05, 0xE3, 0x2A, 0x83, 0x63,
++	0x0A, 0x0B, 0x70, 0x95, 0x1F,
++	0x09, 0xE5, 0xDC, 0xCE, 0x77,
++	0x07, 0x3A, 0x69, 0x0C, 0xA1,
++	0x02, 0xE4, 0xE7, 0x78, 0xBF,
++	0x0B, 0xEE, 0xF0, 0x99, 0x00,
++	0x0B, 0x68, 0xDC, 0x66, 0xD8,
++	0x04, 0xE3, 0xEC, 0x62, 0x6B,
++	0x0B, 0x96, 0x25, 0xA7, 0x2A,
++	0x09, 0x7B, 0x12, 0xC5, 0x0B,
++	0x0F, 0xF6, 0xFD, 0x6F, 0xFF,
++	0x05, 0x98, 0x23, 0xA5, 0x07,
++	0x04, 0x57, 0xD5, 0xAC, 0xB3,
++	0x0F, 0xDD, 0x06, 0xB6, 0xEC,
++	0x0A, 0x8C, 0xAA, 0x05, 0x1D,
++	0x07, 0xB8, 0x5C, 0xE9, 0x0A,
++	0x09, 0x10, 0x59, 0xC2, 0xCE,
++	0x01, 0x0E, 0x30, 0xFF, 0xBA,
++	0x04, 0x91, 0xAB, 0x09, 0x4E,
++	0x0D, 0xE7, 0xE2, 0x8A, 0x8C,
++	0x0A, 0xD4, 0x04, 0xC4, 0x76,
++	0x0D, 0x18, 0x25, 0x15, 0xBE,
++	0x08, 0xDD, 0x5E, 0x55, 0x9D,
++	0x00, 0x92, 0x4F, 0x93, 0x68,
++	0x0B, 0x9E, 0x54, 0xB4, 0xBF,
++	0x0E, 0xC7, 0xCE, 0xE7, 0xB9,
++	0x01, 0x8A, 0x26, 0xD5, 0xA4,
++	0x01, 0x54, 0x59, 0x97, 0xA3,
++	0x0C, 0x39, 0x44, 0xFA, 0xDF,
++	0x08, 0x33, 0x41, 0xAD, 0xA2,
++	0x01, 0xE1, 0xD0, 0xC7, 0xA3,
++	0x02, 0x64, 0x12, 0x5D, 0xA0,
++	0x06, 0x1B, 0xF5, 0x23, 0xCD,
++	0x02, 0x0B, 0xE8, 0x80, 0x82,
++	0x0A, 0x9D, 0x22, 0x8D, 0xED,
++	0x05, 0x14, 0x04, 0xCF, 0xC4,
++	0x09, 0xBF, 0xB0, 0x26, 0x69,
++	0x0A, 0x12, 0xC0, 0xFF, 0x45,
++	0x04, 0xB3, 0x44, 0x1F, 0x75,
++	0x06, 0xDB, 0x08, 0x5A, 0xCC,
++	0x04, 0x14, 0x80, 0xEE, 0xFD,
++	0x08, 0x22, 0x43, 0xD4, 0x48,
++	0x0F, 0x0B, 0xDB, 0x34, 0x3B,
++	0x0F, 0xFE, 0x07, 0x7C, 0x66,
++	0x04, 0x27, 0xFB, 0x47, 0xAD,
++	0x0A, 0x28, 0x47, 0x1B, 0x64,
++	0x08, 0x90, 0xF8, 0x84, 0x61,
++	0x05, 0x64, 0x1B, 0xD3, 0x44,
++	0x04, 0x56, 0xDF, 0xB2, 0x7C,
++	0x02, 0x4F, 0x4C, 0xC0, 0x5B,
++	0x04, 0xD2, 0x3E, 0x8B, 0x24,
++	0x0E, 0x18, 0xA7, 0xE8, 0x35,
++	0x0B, 0x60, 0x9A, 0xF5, 0x4D,
++	0x05, 0x5F, 0xBD, 0xC0, 0xD1,
++	0x05, 0xEB, 0x3C, 0x90, 0xF6,
++	0x0B, 0xB7, 0x9C, 0x37, 0xBD,
++	0x00, 0x1E, 0x50, 0xB9, 0xAB,
++	0x01, 0xF0, 0x11, 0xBE, 0x6C,
++	0x08, 0x8E, 0x99, 0x2E, 0x10,
++	0x09, 0x86, 0x43, 0xCF, 0xFB,
++	0x00, 0x37, 0xF5, 0x24, 0x64,
++	0x01, 0x3F, 0xCA, 0x16, 0xC9,
++	0x06, 0x99, 0x44, 0x06, 0x69,
++	0x09, 0xFD, 0x39, 0xFA, 0xD6,
++	0x00, 0x7D, 0xD0, 0xAB, 0x6D,
++	0x08, 0xEB, 0x0A, 0xA0, 0x12,
++	0x05, 0x39, 0xE1, 0xCE, 0x53,
++	0x0D, 0x50, 0xBB, 0x9C, 0x2B,
++	0x00, 0xD0, 0xC0, 0x8F, 0xE5,
++	0x01, 0xF1, 0xDD, 0xA0, 0x9D,
++	0x06, 0x98, 0xD5, 0x58, 0xA9,
++	0x06, 0x6C, 0xC7, 0xCC, 0x45,
++	0x0E, 0x11, 0x44, 0xE5, 0x6E,
++	0x03, 0x4D, 0xE7, 0x61, 0x47,
++	0x05, 0x4F, 0x9B, 0xF9, 0x35,
++	0x0B, 0x01, 0x8C, 0xA3, 0x4B,
++	0x0A, 0x2C, 0x77, 0x96, 0x78,
++	0x07, 0xA0, 0x12, 0xDD, 0x8B,
++	0x0B, 0xD5, 0x70, 0xE5, 0x64,
++	0x0F, 0x03, 0x1D, 0xA5, 0x2E,
++	0x0B, 0xC3, 0xD8, 0x5E, 0x19,
++	0x0B, 0xDF, 0xBE, 0xF0, 0x3B,
++	0x0E, 0xE6, 0x42, 0x69, 0xD9,
++	0x04, 0x79, 0x11, 0x52, 0x78,
++	0x03, 0xB8, 0x58, 0x84, 0x04,
++	0x09, 0x08, 0x68, 0x30, 0xDF,
++	0x07, 0x91, 0x86, 0x74, 0xF4,
++	0x0A, 0xDB, 0x52, 0x68, 0xE6,
++	0x0A, 0x19, 0x86, 0x95, 0x74,
++	0x01, 0x25, 0xCE, 0xFD, 0xF7,
++	0x0B, 0xAC, 0x1F, 0x85, 0xEF,
++	0x01, 0x07, 0xA9, 0x72, 0xEE,
++	0x0D, 0x3B, 0xEA, 0x5D, 0x45,
++	0x0D, 0xF7, 0xBD, 0x33, 0x43,
++	0x0C, 0x3F, 0xE0, 0xF7, 0xC5,
++	0x00, 0x82, 0x94, 0x74, 0x70,
++	0x03, 0x62, 0xA6, 0x71, 0xB5,
++	0x01, 0x31, 0x12, 0x06, 0x8C,
++	0x03, 0x95, 0x63, 0xBD, 0x37,
++	0x0E, 0x85, 0xAD, 0xFB, 0x2D,
++	0x0B, 0xE4, 0x10, 0x8C, 0x0F,
++	0x0B, 0x0D, 0xCF, 0xEA, 0x31,
++	0x0A, 0x59, 0x27, 0x2E, 0x8A,
++	0x02, 0x97, 0xEB, 0x5D, 0xD5,
++	0x0B, 0x64, 0x05, 0xDE, 0x8E,
++	0x08, 0x9E, 0x7D, 0xC9, 0x05,
++	0x09, 0x7B, 0x66, 0x83, 0xB8,
++	0x07, 0xC1, 0xED, 0x8F, 0x53,
++	0x04, 0xA7, 0x6A, 0xF3, 0xE6,
++	0x09, 0x48, 0x24, 0x6A, 0xEB,
++	0x02, 0x20, 0x10, 0x8C, 0x2D,
++	0x06, 0xC3, 0x29, 0xAE, 0x4C,
++	0x0A, 0xD3, 0xF6, 0x49, 0x6F,
++	0x00, 0x29, 0x78, 0x0E, 0xE5,
++	0x00, 0x5E, 0x61, 0xE3, 0xEC,
++	0x03, 0xC7, 0xDD, 0x06, 0xB7,
++	0x06, 0x17, 0x01, 0x2A, 0x04,
++	0x07, 0xCB, 0x97, 0xDC, 0xF4,
++	0x01, 0x75, 0x12, 0xD9, 0xC1,
++	0x0F, 0x4D, 0xEE, 0xF0, 0xBF,
++	0x0A, 0x5D, 0x77, 0x32, 0xC9,
++	0x04, 0xD0, 0x5B, 0xCD, 0x82,
++	0x0D, 0xC6, 0xD6, 0x04, 0xFD,
++	0x09, 0x21, 0xD8, 0x40, 0x15,
++	0x0A, 0xF4, 0x68, 0x8A, 0x1C,
++	0x07, 0xEC, 0x92, 0xDF, 0x93,
++	0x0A, 0xB2, 0x58, 0xC8, 0xB4,
++	0x05, 0xA3, 0x78, 0xD9, 0x27,
++	0x03, 0xBA, 0xB5, 0x6D, 0xD1,
++	0x0D, 0x7D, 0x54, 0x0A, 0x57,
++	0x0E, 0xF2, 0x79, 0xD0, 0xFA,
++	0x00, 0x25, 0x8C, 0x05, 0xAD,
++	0x06, 0x1D, 0xD1, 0xBF, 0x1A,
++	0x07, 0xAE, 0x84, 0x1E, 0x9D,
++	0x0A, 0x41, 0x7B, 0x15, 0xE3,
++	0x07, 0xAA, 0x35, 0x88, 0xA0,
++	0x0E, 0x30, 0x5C, 0xAB, 0x04,
++	0x09, 0xB9, 0x14, 0x2B, 0x4F,
++	0x00, 0xA7, 0xFF, 0x24, 0x26,
++	0x0A, 0x30, 0x2B, 0xE9, 0x3F,
++	0x05, 0x8E, 0xB2, 0xC3, 0x1E,
++	0x08, 0x1A, 0x1C, 0xB0, 0x53,
++	0x0A, 0xA8, 0x14, 0xA3, 0x24,
++	0x0C, 0x73, 0x63, 0xB5, 0xDD,
++	0x04, 0x67, 0xCC, 0x1B, 0x3D,
++	0x0B, 0xC3, 0xFE, 0x0D, 0xFC,
++	0x0C, 0xC8, 0x25, 0x39, 0xEC,
++	0x07, 0x36, 0x28, 0x47, 0x1B,
++	0x0B, 0x12, 0x91, 0x80, 0x99,
++	0x09, 0x39, 0xD6, 0x17, 0xD3,
++	0x0A, 0x26, 0xD6, 0x9F, 0x72,
++	0x07, 0x7D, 0x4D, 0x4C, 0xF4,
++	0x0F, 0x28, 0xC2, 0xFE, 0xBE,
++	0x01, 0x66, 0xFE, 0x3E, 0xDE,
++	0x09, 0xB7, 0x20, 0xB5, 0xC2,
++	0x0C, 0x28, 0xED, 0x9D, 0xF8,
++	0x0B, 0x49, 0x8F, 0x28, 0xA9,
++	0x05, 0x94, 0xFC, 0xEC, 0x4C,
++	0x0B, 0xFD, 0x60, 0xF8, 0xA4,
++	0x08, 0xCA, 0xD6, 0x81, 0xBE,
++	0x07, 0xD0, 0x32, 0xB6, 0xAE,
++	0x0A, 0x22, 0x75, 0x08, 0xCB,
++	0x00, 0xAC, 0x31, 0xA2, 0x64,
++	0x00, 0xAD, 0x3F, 0x64, 0x96,
++	0x0D, 0x9A, 0x59, 0x80, 0xC6,
++	0x01, 0xA5, 0xFD, 0x16, 0x3A,
++	0x0A, 0x3D, 0xBD, 0xD0, 0x6B,
++	0x0E, 0xC1, 0x6B, 0xEA, 0xA0,
++	0x02, 0xBC, 0xB9, 0x85, 0x44,
++	0x0F, 0xD7, 0x11, 0x21, 0xAB,
++	0x03, 0x5E, 0xD0, 0xEF, 0x3D,
++	0x04, 0x3E, 0x31, 0x73, 0x24,
++	0x08, 0xEE, 0xFE, 0x7C, 0xDD,
++	0x02, 0x9E, 0x7C, 0x5C, 0x4C,
++	0x08, 0x02, 0x11, 0xC4, 0xEB,
++	0x04, 0x6F, 0x4D, 0x88, 0x99,
++	0x06, 0x7D, 0x09, 0x2D, 0xC0,
++	0x09, 0x33, 0x02, 0x0C, 0x99,
++	0x07, 0xFA, 0x2C, 0x75, 0xAD,
++	0x00, 0xFB, 0x20, 0xD6, 0xDD,
++	0x09, 0x55, 0xCE, 0xC0, 0xA5,
++	0x05, 0x76, 0x83, 0x9D, 0x3A,
++	0x02, 0xA1, 0x43, 0x38, 0x6A,
++	0x05, 0xA2, 0x1E, 0x1F, 0xC5,
++	0x07, 0xE2, 0xF6, 0x41, 0x1F,
++	0x06, 0x3C, 0xB9, 0xB1, 0x65,
++	0x04, 0xDB, 0xF8, 0x98, 0xB0,
++	0x08, 0x23, 0x6E, 0xCA, 0x89,
++	0x05, 0x18, 0x6A, 0xC2, 0x4F,
++	0x01, 0x91, 0x5B, 0xF2, 0x6E,
++	0x0D, 0x81, 0x68, 0x45, 0x92,
++	0x08, 0x58, 0xEB, 0x6C, 0xFF,
++	0x0B, 0x41, 0xED, 0xBB, 0x32,
++	0x03, 0xAA, 0x81, 0x0A, 0xCA,
++	0x02, 0x04, 0x3A, 0x4F, 0x64,
++	0x08, 0x86, 0x73, 0x3D, 0x89,
++	0x0F, 0xBC, 0x3F, 0xE0, 0xCC,
++	0x0D, 0xCC, 0x02, 0x5F, 0xB4,
++	0x02, 0x71, 0x79, 0x24, 0x71,
++	0x09, 0x72, 0xF1, 0x10, 0x31,
++	0x0E, 0x13, 0x15, 0x6D, 0xBD,
++	0x0C, 0xA0, 0x9E, 0xE9, 0xFB,
++	0x08, 0xB7, 0xA4, 0xD4, 0xFB,
++	0x0A, 0x31, 0x8D, 0x2F, 0xEC,
++	0x0D, 0xD5, 0x79, 0xE3, 0xEB,
++	0x08, 0xD9, 0x67, 0x0B, 0x6D,
++	0x09, 0x01, 0x55, 0xE5, 0xD8,
++	0x02, 0x77, 0x7E, 0xBA, 0x8C,
++	0x07, 0x63, 0x6A, 0x66, 0xB5,
++	0x04, 0x7F, 0xC4, 0x6F, 0x82,
++	0x09, 0x04, 0xA5, 0x68, 0xF3,
++	0x06, 0xC5, 0x4A, 0xE3, 0x60,
++	0x0E, 0x62, 0x5D, 0x90, 0x85,
++	0x07, 0x2A, 0xC1, 0x7A, 0x6E,
++	0x05, 0x0A, 0xD1, 0xFA, 0x43,
++	0x03, 0xC9, 0xA9, 0x98, 0x11,
++	0x09, 0x1A, 0x5F, 0xD1, 0x6B,
++	0x06, 0x73, 0xC5, 0x5E, 0xC0,
++	0x06, 0x6D, 0xB2, 0x3E, 0xAA,
++	0x0B, 0xAA, 0xFB, 0xB8, 0x1C,
++	0x05, 0x3D, 0x08, 0x92, 0x10,
++	0x02, 0xF6, 0xCF, 0x0E, 0xF0,
++	0x0F, 0x83, 0xDF, 0x17, 0x32,
++	0x01, 0x4E, 0x53, 0xE5, 0x4D,
++	0x00, 0x90, 0x27, 0x55, 0x84,
++	0x08, 0x40, 0x5C, 0x98, 0x47,
++	0x05, 0x86, 0xF6, 0xDC, 0x8A,
++	0x05, 0xA7, 0xEE, 0x9E, 0xD5,
++	0x0F, 0x53, 0x30, 0x18, 0xD7,
++	0x08, 0xBF, 0xA2, 0xC7, 0x51,
++	0x0D, 0x4F, 0xB8, 0x8E, 0xBE,
++	0x08, 0xAC, 0xD9, 0xD4, 0x0A,
++	0x09, 0x16, 0x9D, 0xB9, 0xD2,
++	0x06, 0xEA, 0x59, 0xB3, 0x8C,
++	0x0D, 0x9A, 0x1F, 0xE1, 0xFF,
++	0x07, 0xBE, 0x2E, 0x64, 0x12,
++	0x05, 0xA3, 0x4D, 0x99, 0x95,
++	0x09, 0x8C, 0x43, 0x89, 0xC8,
++	0x0F, 0xC2, 0x30, 0x9C, 0xAB,
++	0x01, 0xE9, 0xC4, 0x94, 0x22,
++	0x0F, 0xD9, 0x27, 0xBF, 0x26,
++	0x06, 0x60, 0x33, 0x94, 0x63,
++	0x05, 0x44, 0xAD, 0x32, 0xCE,
++	0x03, 0x64, 0x1A, 0xDB, 0xB6,
++	0x06, 0xFA, 0xA8, 0x14, 0xA8,
++	0x06, 0xE0, 0xF3, 0x26, 0x75,
++	0x0E, 0x49, 0x94, 0x8B, 0xFB,
++	0x0C, 0x38, 0xC3, 0xFC, 0x8F,
++	0x0C, 0x5C, 0xC8, 0x25, 0x3B,
++	0x07, 0x9F, 0x36, 0x2E, 0x4D,
++	0x0B, 0x57, 0x13, 0x15, 0x00,
++	0x04, 0x61, 0x3B, 0x56, 0x1B,
++	0x0F, 0x71, 0x68, 0x56, 0x9B,
++	0x0E, 0x4B, 0x3E, 0x0D, 0x49,
++	0x0B, 0xE1, 0x2B, 0x52, 0xFE,
++	0x07, 0x19, 0x65, 0x9E, 0x3A,
++	0x04, 0x35, 0x17, 0x20, 0xB0,
++	0x0E, 0xD2, 0x2A, 0xDE, 0x5D,
++	0x0C, 0xE7, 0x49, 0xEB, 0x96,
++	0x0A, 0xCF, 0xFA, 0x36, 0x69,
++	0x07, 0x87, 0xFC, 0x12, 0x7C,
++	0x09, 0x90, 0x4A, 0x7A, 0x4A,
++	0x04, 0x8C, 0x49, 0x8A, 0x32,
++	0x0E, 0x26, 0x22, 0x11, 0x08,
++	0x02, 0x72, 0xAC, 0x27, 0xA6,
++	0x04, 0x50, 0xAD, 0x2F, 0xD5,
++	0x06, 0xFC, 0x9A, 0x89, 0x32,
++	0x06, 0x51, 0xA5, 0xED, 0xA5,
++	0x0A, 0xCB, 0x3C, 0x6D, 0x64,
++	0x0B, 0x6E, 0xC1, 0x7B, 0x5F,
++	0x00, 0x52, 0xBC, 0x9B, 0x37,
++	0x0E, 0x93, 0xD7, 0x51, 0x96,
++	0x0C, 0x2F, 0x6C, 0xD0, 0x57,
++	0x0F, 0xF8, 0x3D, 0xED, 0x31,
++	0x00, 0x94, 0xED, 0x02, 0xFE,
++	0x08, 0xA9, 0x1C, 0x71, 0x9E,
++	0x0C, 0x44, 0x02, 0x0C, 0x86,
++	0x05, 0x58, 0x6F, 0x50, 0x8A,
++	0x01, 0x5A, 0x7E, 0xD4, 0xAF,
++	0x09, 0x35, 0x33, 0x1C, 0x4E,
++	0x03, 0x4B, 0xFA, 0x02, 0x77,
++	0x08, 0xF9, 0xCB, 0xA0, 0xD6,
++	0x06, 0x82, 0xD7, 0xD5, 0x40,
++	0x09, 0x46, 0xB7, 0x03, 0x8E,
++	0x0B, 0xAE, 0x82, 0x43, 0x2C,
++	0x04, 0x19, 0xB1, 0xDA, 0x3F,
++	0x00, 0x7B, 0xE2, 0xF6, 0x41,
++	0x09, 0xDA, 0x3C, 0xE9, 0xB1,
++	0x0A, 0x38, 0x5A, 0xA8, 0x18,
++	0x00, 0x84, 0x83, 0x49, 0x4A,
++	0x09, 0xDE, 0x5B, 0xA1, 0xC2,
++	0x0D, 0x7D, 0x72, 0x6B, 0x72,
++	0x03, 0xE7, 0xE3, 0x29, 0xC6,
++	0x0E, 0xF5, 0x98, 0xBB, 0xAC,
++	0x09, 0x76, 0xE1, 0xBD, 0x3B,
++	0x0D, 0xAE, 0x2A, 0x91, 0xCA,
++	0x02, 0xEE, 0x07, 0x2A, 0xFE,
++	0x0D, 0x44, 0x86, 0x20, 0x0F,
++	0x03, 0x43, 0xBC, 0x0F, 0x53,
++	0x07, 0xC5, 0xCC, 0xB2, 0xE7,
++	0x04, 0x79, 0xF3, 0x52, 0xA4,
++	0x01, 0xB5, 0x71, 0x2D, 0x52,
++	0x08, 0x46, 0x13, 0x89, 0xE3,
++	0x0D, 0x37, 0x22, 0x99, 0xAB,
++	0x0B, 0x24, 0xB7, 0xC9, 0xD6,
++	0x0C, 0x06, 0x32, 0x99, 0x2D,
++	0x08, 0xB1, 0xD6, 0x4D, 0xA1,
++	0x0E, 0x83, 0x5B, 0x62, 0x89,
++	0x0F, 0x55, 0x02, 0xB1, 0x27,
++	0x07, 0x0E, 0x74, 0x9E, 0xBA,
++	0x05, 0x0D, 0xFE, 0xBB, 0x65,
++	0x0B, 0x79, 0x7F, 0xC1, 0xEC,
++	0x03, 0x99, 0x84, 0xA7, 0x28,
++	0x0B, 0x66, 0x65, 0x48, 0xA3,
++	0x03, 0x62, 0x82, 0x20, 0x10,
++	0x00, 0x27, 0x2A, 0x83, 0x6B,
++	0x02, 0x7A, 0xF5, 0x13, 0xE6,
++	0x09, 0x6F, 0xC9, 0xA5, 0x0E,
++	0x04, 0x66, 0x1A, 0x7B, 0xCC,
++	0x0B, 0x2E, 0x1B, 0xF3, 0x83,
++	0x04, 0xB6, 0xE4, 0x36, 0x3E,
++	0x08, 0x05, 0x2B, 0xFB, 0x38,
++	0x0D, 0xA9, 0xFD, 0x75, 0x12,
++	0x08, 0x82, 0x36, 0xCD, 0x0E,
++	0x09, 0x7E, 0x63, 0xD3, 0x17,
++	0x02, 0x09, 0x4E, 0xF7, 0x65,
++	0x0D, 0x8A, 0x91, 0xE0, 0x57,
++	0x0A, 0x45, 0x70, 0x21, 0x18,
++	0x07, 0x5F, 0xE6, 0xF9, 0x1C,
++	0x00, 0x17, 0xB4, 0x6C, 0x96,
++	0x04, 0x93, 0x53, 0x30, 0x18,
++	0x06, 0x34, 0xBF, 0x22, 0xD7,
++	0x05, 0x77, 0x8F, 0xBA, 0x01,
++	0x01, 0xD9, 0xD3, 0xBD, 0x49,
++	0x02, 0x57, 0x17, 0x74, 0x26,
++	0x08, 0x78, 0xF5, 0x24, 0x73,
++	0x09, 0xED, 0x9A, 0x1D, 0xED,
++	0x04, 0x85, 0x86, 0xAE, 0x64,
++	0x02, 0x9D, 0xA3, 0xC1, 0x96,
++	0x0C, 0xA1, 0x6D, 0xAB, 0x89,
++	0x00, 0x8A, 0x22, 0x3D, 0x5C,
++	0x01, 0x0F, 0xDC, 0x39, 0x1C,
++	0x03, 0xCF, 0x79, 0x28, 0x7F,
++	0x0E, 0x24, 0x40, 0x34, 0x66,
++	0x00, 0xFE, 0xA5, 0x80, 0xF2,
++	0x07, 0x9E, 0xD4, 0x14, 0x9B,
++	0x00, 0x5A, 0xFA, 0xAD, 0xD0,
++	0x03, 0x2F, 0x1E, 0xB3, 0xB9,
++	0x05, 0xD4, 0x48, 0x62, 0x4E,
++	0x0B, 0x34, 0x3B, 0xE3, 0xF7,
++	0x07, 0x74, 0xDC, 0xC8, 0xA5,
++	0x02, 0xCA, 0x7F, 0x16, 0xAA,
++	0x0F, 0x12, 0xD7, 0x13, 0x91,
++	0x09, 0x0D, 0x81, 0x19, 0xD6,
++	0x03, 0x5B, 0xD2, 0x28, 0xD6,
++	0x06, 0xBA, 0x8B, 0x4E, 0xCD,
++	0x04, 0x4A, 0x43, 0x18, 0x52,
++	0x07, 0x82, 0xDF, 0x45, 0x1E,
++	0x0E, 0xE8, 0x35, 0x81, 0x6A,
++	0x0D, 0xF5, 0xC0, 0x19, 0x9E,
++	0x07, 0xC2, 0xCC, 0xC9, 0xCB,
++	0x09, 0x95, 0x0E, 0x17, 0xB6,
++	0x09, 0xF2, 0x67, 0xFC, 0x1E,
++	0x00, 0xB9, 0x18, 0x48, 0xF6,
++	0x0D, 0x3E, 0x6C, 0x52, 0x0E,
++	0x04, 0xAE, 0x26, 0xA4, 0xC1,
++	0x0B, 0xC3, 0xF2, 0x2A, 0xBD,
++	0x05, 0x65, 0xF8, 0xAB, 0xF5,
++	0x05, 0x17, 0x1F, 0x1A, 0x99,
++	0x01, 0xC4, 0x19, 0x25, 0xFD,
++	0x06, 0x3A, 0xCB, 0x3C, 0x7D,
++	0x00, 0xEE, 0xC5, 0x41, 0x6B,
++	0x0A, 0xA2, 0x50, 0xBC, 0xBB,
++	0x01, 0x4F, 0x33, 0xD7, 0x51,
++	0x01, 0x9D, 0xAF, 0x7A, 0x52,
++	0x0F, 0x8E, 0x58, 0x3B, 0x33,
++	0x0A, 0xA2, 0x60, 0xC1, 0x9E,
++	0x0C, 0xD8, 0xB9, 0x0A, 0x6F,
++	0x0C, 0x4C, 0x44, 0x24, 0x53,
++	0x0A, 0x64, 0x68, 0x6F, 0x4D,
++	0x04, 0xA1, 0x5A, 0xFE, 0xD9,
++	0x01, 0xF9, 0x35, 0x73, 0x0F,
++	0x06, 0xA1, 0x6B, 0xFA, 0x2D,
++	0x09, 0x97, 0x86, 0x3B, 0xBD,
++	0x06, 0xDD, 0x82, 0xD7, 0xD5,
++	0x08, 0xA5, 0xF9, 0x77, 0xC3,
++	0x07, 0x25, 0x96, 0xA2, 0x63,
++	0x03, 0xDC, 0xE1, 0x21, 0xDE,
++	0x04, 0xF0, 0x7B, 0xE2, 0xE6,
++	0x0D, 0x29, 0xDA, 0xBC, 0xCC,
++	0x08, 0x52, 0xF8, 0xDA, 0xB8,
++	0x00, 0x08, 0xA4, 0x23, 0x09,
++	0x00, 0xB2, 0xE5, 0x9B, 0x90,
++	0x0A, 0x35, 0x5D, 0x9F, 0x1B,
++	0x0A, 0x78, 0x46, 0x0E, 0xD9,
++	0x0C, 0x95, 0xBF, 0xD8, 0xE3,
++	0x04, 0xF3, 0xD7, 0x44, 0x2D,
++	0x01, 0x07, 0xEC, 0xAA, 0x89,
++	0x02, 0xF2, 0x6E, 0x09, 0x7A,
++	0x06, 0x94, 0xC4, 0x83, 0x30,
++	0x05, 0xFA, 0xC3, 0xB9, 0xBF,
++	0x00, 0xF7, 0xC5, 0xC9, 0x46,
++	0x08, 0x36, 0x12, 0x76, 0x67,
++	0x0C, 0x79, 0x35, 0x7C, 0xF1,
++	0x08, 0x09, 0xC6, 0x1E, 0xD5,
++	0x09, 0xBC, 0xB7, 0x2C, 0xC5,
++	0x00, 0x32, 0xA4, 0xB2, 0xA4,
++	0x0C, 0x85, 0x86, 0x37, 0x0D,
++	0x0F, 0xE8, 0xB1, 0xD3, 0x9D,
++	0x08, 0x6C, 0xE8, 0xDE, 0x73,
++	0x03, 0x5F, 0xD5, 0x0C, 0xD5,
++	0x0C, 0x55, 0x8E, 0x79, 0x5E,
++	0x02, 0x88, 0x8C, 0xEC, 0x3B,
++	0x0F, 0x4E, 0x98, 0x7A, 0x81,
++	0x07, 0xC2, 0x19, 0x01, 0x27,
++	0x08, 0xF3, 0xE6, 0xC0, 0x8C,
++	0x08, 0xE8, 0x89, 0xE7, 0x25,
++	0x09, 0x14, 0xC7, 0x27, 0x03,
++	0x03, 0x69, 0x25, 0x0F, 0x53,
++	0x0E, 0x4B, 0x2F, 0xCC, 0x69,
++	0x02, 0x0E, 0x2C, 0x9A, 0x57,
++	0x08, 0xEB, 0x4C, 0xB6, 0x07,
++	0x07, 0x04, 0xF1, 0xEC, 0x17,
++	0x00, 0x2B, 0x35, 0x2B, 0xCB,
++	0x04, 0x1C, 0xE9, 0xBD, 0x65,
++	0x0E, 0x19, 0xC2, 0xB6, 0xC3,
++	0x04, 0xF2, 0xC5, 0x03, 0xDE,
++	0x07, 0x32, 0x09, 0x40, 0x95,
++	0x0B, 0xCD, 0x8A, 0x11, 0xF3,
++	0x0C, 0xD4, 0x04, 0x4D, 0xE1,
++	0x00, 0xCE, 0xF5, 0x86, 0xF4,
++	0x0C, 0x8A, 0x15, 0xA3, 0x5A,
++	0x0A, 0xDD, 0xB3, 0x5D, 0xB0,
++	0x02, 0xC8, 0x5F, 0xBF, 0xAA,
++	0x0E, 0x59, 0xA7, 0x8F, 0xBA,
++	0x05, 0x6F, 0x98, 0x20, 0x3D,
++	0x0E, 0x08, 0x3F, 0x17, 0x78,
++	0x05, 0xD3, 0x85, 0xEA, 0x39,
++	0x03, 0x85, 0xED, 0x97, 0x82,
++	0x03, 0xFF, 0x07, 0xBB, 0xAE,
++	0x0D, 0x92, 0x7D, 0xA3, 0xCF,
++	0x0B, 0x6D, 0xA3, 0x83, 0x7C,
++	0x09, 0x88, 0x80, 0x42, 0x30,
++	0x04, 0x83, 0x8D, 0xEC, 0xB9,
++	0x04, 0x2B, 0x4F, 0xD9, 0x25,
++	0x0F, 0x26, 0xA6, 0x65, 0x3C,
++	0x0C, 0x23, 0x1F, 0x48, 0x0E,
++	0x08, 0xCD, 0x78, 0xF4, 0x12,
++	0x07, 0xB1, 0xA5, 0xFA, 0xB5,
++	0x04, 0xAF, 0x2E, 0xE5, 0xAC,
++	0x06, 0xF5, 0xD4, 0x45, 0x27,
++	0x0B, 0xDB, 0x34, 0x3E, 0x70,
++	0x0E, 0x76, 0xBC, 0x59, 0xBA,
++	0x0D, 0xBA, 0xC7, 0x92, 0x76,
++	0x02, 0x46, 0x9B, 0x59, 0x53,
++	0x09, 0x81, 0x24, 0x6F, 0x79,
++	0x06, 0x1B, 0xD3, 0x77, 0x2C,
++	0x06, 0x9F, 0xB2, 0x4E, 0x3B,
++	0x0D, 0x4C, 0xCC, 0x46, 0xF7,
++	0x02, 0xFE, 0x9B, 0x0D, 0x6C,
++	0x07, 0x3E, 0x22, 0x05, 0x37,
++	0x02, 0xB5, 0xF5, 0xE0, 0xA3,
++	0x0C, 0x5D, 0xC3, 0x47, 0xC3,
++	0x09, 0xA8, 0x18, 0xCC, 0x97,
++	0x04, 0xE8, 0xC7, 0x85, 0x7C,
++	0x0E, 0xFA, 0xB9, 0xA0, 0x4A,
++	0x06, 0x0E, 0x9E, 0x5C, 0x54,
++	0x07, 0xB6, 0x4E, 0x26, 0xA2,
++	0x09, 0x0A, 0x82, 0xF4, 0xA6,
++	0x0F, 0x24, 0x87, 0xD6, 0xE7,
++	0x06, 0xE5, 0x74, 0xFE, 0x1A,
++	0x00, 0x81, 0x06, 0x73, 0x25,
++	0x0D, 0x16, 0x3A, 0xDD, 0x3E,
++	0x0D, 0xD0, 0x6B, 0x48, 0x83,
++	0x0B, 0xEA, 0xA0, 0x44, 0x3E,
++	0x0B, 0x81, 0xCE, 0x95, 0x15,
++	0x09, 0xA1, 0x3C, 0x23, 0xEC,
++	0x09, 0xEF, 0xCF, 0xF4, 0xFD,
++	0x08, 0xF1, 0xC0, 0x94, 0x2D,
++	0x00, 0xFD, 0xE8, 0xA9, 0x1C,
++	0x01, 0x5C, 0x4C, 0xC4, 0x12,
++	0x0D, 0x84, 0xE5, 0x18, 0x61,
++	0x07, 0xCA, 0xF4, 0x5A, 0x7F,
++	0x08, 0x2F, 0x39, 0x35, 0x33,
++	0x0B, 0x8E, 0xEC, 0xCB, 0xFB,
++	0x04, 0x3D, 0x16, 0x75, 0xBB,
++	0x09, 0xDE, 0x1D, 0x8F, 0x57,
++	0x05, 0x40, 0xA5, 0x7C, 0x42,
++	0x03, 0x1F, 0x87, 0xAB, 0x14,
++	0x09, 0x3A, 0x10, 0xD9, 0xA0,
++	0x05, 0x1F, 0xF0, 0x7B, 0xE2,
++	0x06, 0x41, 0x29, 0xCA, 0x3C,
++	0x09, 0xB1, 0x52, 0x18, 0xDA,
++	0x08, 0x98, 0x88, 0x14, 0x92,
++	0x09, 0xCA, 0xB0, 0xDE, 0x29,
++	0x01, 0x42, 0xB4, 0xFD, 0x21,
++	0x0B, 0xF2, 0x6A, 0x66, 0xB7,
++	0x09, 0x46, 0x97, 0xC1, 0x9C,
++	0x0B, 0x2C, 0xF1, 0xEB, 0x03,
++	0x0D, 0xBB, 0x05, 0x83, 0x28,
++	0x01, 0x4A, 0xF2, 0xF2, 0xC5,
++	0x01, 0x4F, 0x5D, 0x49, 0x84,
++	0x0C, 0xBD, 0xB3, 0xC3, 0xAF,
++	0x0F, 0xE0, 0xF7, 0xD5, 0xCC,
++	0x08, 0x93, 0xA4, 0x7D, 0x1D,
++	0x02, 0xA4, 0x71, 0xF5, 0x71,
++	0x01, 0x10, 0x08, 0x06, 0x13,
++	0x0D, 0x64, 0x3D, 0x77, 0xA2,
++	0x0D, 0xEC, 0x5B, 0x34, 0x37,
++	0x0D, 0xD1, 0x0C, 0x26, 0xB2,
++	0x04, 0xAA, 0x08, 0xA1, 0x56,
++	0x09, 0xE3, 0xEE, 0xC5, 0x59,
++	0x06, 0x0B, 0x5F, 0x13, 0x40,
++	0x05, 0xE5, 0xDC, 0x48, 0xF6,
++	0x0E, 0xBA, 0x89, 0x2A, 0x23,
++	0x00, 0x66, 0x87, 0x78, 0x7F,
++	0x01, 0xEF, 0x8B, 0x9F, 0x07,
++	0x0F, 0x68, 0x73, 0xE6, 0xC5,
++	0x02, 0x23, 0x72, 0xE6, 0x91,
++	0x00, 0x59, 0x08, 0xA7, 0x2A,
++	0x03, 0x33, 0xEA, 0x45, 0x0A,
++	0x01, 0xBF, 0xC9, 0xEF, 0x83,
++	0x09, 0xD1, 0x8C, 0x65, 0x1A,
++	0x0F, 0x98, 0xE3, 0xAC, 0xB3,
++	0x0C, 0xDD, 0x06, 0xB6, 0xEC,
++	0x06, 0xBE, 0xAA, 0x85, 0x2B,
++	0x03, 0xB8, 0x9C, 0x6F, 0x37,
++	0x05, 0x10, 0x19, 0xC2, 0xF6,
++	0x06, 0x0E, 0xF0, 0xFF, 0x83,
++	0x0F, 0x17, 0x32, 0x89, 0x4E,
++	0x01, 0xE7, 0xCD, 0x8A, 0x91,
++	0x06, 0xD4, 0x44, 0xC4, 0x40,
++	0x01, 0x18, 0x4E, 0x55, 0x86,
++	0x04, 0xDC, 0x8A, 0x15, 0xA7,
++	0x07, 0x92, 0xDF, 0x95, 0x59,
++	0x00, 0x18, 0xC8, 0x34, 0xBF,
++	0x0B, 0xE7, 0x9D, 0xE1, 0x8F,
++	0x0A, 0x0D, 0x69, 0x58, 0x2D,
++	0x0D, 0x54, 0x0E, 0xD5, 0x14,
++	0x00, 0x71, 0x56, 0x7A, 0xEA,
++	0x04, 0x7A, 0x01, 0xEF, 0x19,
++	0x0F, 0xA8, 0x7C, 0x81, 0x3E,
++	0x0E, 0x2D, 0x91, 0x1D, 0xE9,
++	0x0F, 0xD2, 0x96, 0xA5, 0x07,
++	0x0B, 0x89, 0x89, 0x00, 0x08,
++	0x00, 0x9C, 0xAB, 0x0D, 0xE9,
++	0x01, 0x74, 0xA9, 0x49, 0xD3,
++	0x0E, 0xBF, 0x26, 0xA6, 0x60,
++	0x0D, 0x95, 0x96, 0xBF, 0x74,
++	0x02, 0xBE, 0xCF, 0x1F, 0x46,
++	0x06, 0xF3, 0xB0, 0x5A, 0xE6,
++	0x04, 0x02, 0xAF, 0x2E, 0xF7,
++	0x03, 0xA4, 0xF1, 0xD4, 0x48,
++	0x0F, 0xA3, 0x7F, 0x34, 0xFB,
++	0x0B, 0xFE, 0x8F, 0x7C, 0x9C,
++	0x03, 0xA7, 0x9C, 0xC3, 0xC8,
++	0x0A, 0x3C, 0x47, 0x1B, 0x40,
++	0x03, 0x11, 0x04, 0x80, 0x45,
++	0x01, 0xFE, 0xBF, 0xD3, 0xB2,
++	0x00, 0x56, 0x1F, 0xB2, 0x8B,
++	0x05, 0xCF, 0xEB, 0x44, 0x34,
++	0x03, 0xD2, 0xFE, 0x8F, 0x38,
++	0x09, 0x9F, 0xC1, 0x28, 0x04,
++	0x0B, 0x6C, 0xB5, 0xF5, 0x62,
++	0x05, 0x76, 0x5D, 0xC0, 0xFB,
++	0x05, 0xFD, 0xA8, 0x90, 0xD9,
++	0x07, 0xB6, 0x6C, 0x77, 0x87,
++	0x04, 0xB6, 0x5C, 0xB9, 0x50,
++	0x02, 0x76, 0x0F, 0x3E, 0xAC,
++	0x0F, 0x0C, 0x91, 0x2A, 0x71,
++	0x0A, 0x81, 0xA8, 0xCF, 0xB2,
++	0x06, 0x35, 0x33, 0xE4, 0x10,
++	0x0D, 0x3F, 0x64, 0x92, 0xD8,
++	0x00, 0x9B, 0x1B, 0x46, 0x50,
++	0x0D, 0x7F, 0x36, 0x36, 0xCB,
++	0x06, 0x7F, 0x47, 0x6B, 0x2E,
++	0x01, 0x6B, 0xEA, 0xA4, 0x72,
++	0x06, 0xB9, 0x1A, 0x4E, 0x92,
++	0x0F, 0xD3, 0x01, 0x90, 0x2F,
++	0x06, 0xD2, 0x76, 0x0F, 0xB8,
++	0x0D, 0xF1, 0x73, 0x24, 0xB6,
++	0x07, 0x1C, 0xE7, 0x58, 0xA8,
++	0x04, 0xEF, 0x7C, 0x40, 0x44,
++	0x08, 0x13, 0x1F, 0xE5, 0x18,
++	0x0F, 0x4D, 0xC8, 0xA5, 0x7E,
++	0x04, 0xCB, 0xB6, 0x79, 0x34,
++	0x03, 0x01, 0x8C, 0xA7, 0x6D,
++	0x06, 0x3A, 0x75, 0x96, 0x6F,
++	0x0B, 0xA0, 0xD2, 0xDD, 0x82,
++	0x0F, 0x7D, 0xE4, 0xA5, 0xB9,
++	0x0F, 0x03, 0x1D, 0x27, 0x6E,
++	0x09, 0xC1, 0x9F, 0xDA, 0x8E,
++	0x09, 0x5E, 0xBF, 0xFD, 0xBB,
++	0x08, 0xE4, 0xE1, 0x29, 0x9A,
++	0x0C, 0xF9, 0xB1, 0x56, 0x1D,
++	0x00, 0xBA, 0x3E, 0x08, 0x05,
++	0x0B, 0x8B, 0xEA, 0xBC, 0xDE,
++	0x01, 0x93, 0xE0, 0xB4, 0xBD,
++	0x02, 0x5B, 0xF2, 0x6E, 0x47,
++	0x09, 0x1B, 0xE0, 0x17, 0xF5,
++	0x00, 0x69, 0x0C, 0xFD, 0xF7,
++	0x0B, 0xAF, 0x1F, 0x05, 0xEF,
++	0x0A, 0x81, 0x4A, 0xF6, 0xCD,
++	0x0D, 0x38, 0xE9, 0xDD, 0x45,
++	0x0E, 0xF2, 0x9D, 0xBF, 0x43,
++	0x06, 0x3D, 0x46, 0xF7, 0x85,
++	0x0C, 0x82, 0x53, 0xB0, 0x5C,
++	0x09, 0x60, 0x02, 0xF1, 0xB4,
++	0x01, 0x31, 0x10, 0x0C, 0x61,
++	0x03, 0x95, 0x61, 0xBD, 0x37,
++	0x09, 0x85, 0x69, 0xFB, 0x24,
++	0x0E, 0xE2, 0x54, 0xC0, 0x86,
++	0x0A, 0x0B, 0xAF, 0xE4, 0xF1,
++	0x0F, 0x19, 0x23, 0xEA, 0x03,
++	0x01, 0x74, 0xA7, 0x5F, 0x15,
++	0x08, 0x97, 0x4B, 0xDC, 0x4E,
++	0x04, 0x9E, 0xB2, 0x8D, 0x52,
++	0x01, 0x7B, 0x6E, 0x87, 0x78,
++	0x07, 0xC1, 0x63, 0x8B, 0x59,
++	0x0E, 0xA5, 0xD8, 0xF3, 0xE7,
++	0x0C, 0x4A, 0xA3, 0x66, 0xE2,
++	0x08, 0x22, 0xBE, 0x8C, 0x37,
++	0x0A, 0xC3, 0x7A, 0x6A, 0x0D,
++	0x00, 0xD1, 0x59, 0x49, 0x6E,
++	0x09, 0xA9, 0x9A, 0x08, 0x2C,
++	0x0A, 0x5F, 0xD3, 0x63, 0xAC,
++	0x0B, 0xC7, 0x5D, 0x04, 0x36,
++	0x0C, 0x16, 0xBE, 0xAA, 0x05,
++	0x03, 0xE3, 0x38, 0x18, 0xE9,
++	0x06, 0x75, 0x12, 0x19, 0xC2,
++	0x0F, 0x4D, 0xEE, 0xFE, 0x3F,
++	0x09, 0xDD, 0xD8, 0x32, 0x29,
++	0x0E, 0xD1, 0xE1, 0xCD, 0x8A,
++	0x01, 0xC6, 0xD1, 0x44, 0xC4,
++	0x00, 0x21, 0x1C, 0xCE, 0x55,
++	0x06, 0xF4, 0xD8, 0x08, 0x96,
++	0x07, 0x24, 0x36, 0xDF, 0x93,
++	0x03, 0xF9, 0xBC, 0xC8, 0xB7,
++	0x0D, 0x6B, 0x64, 0xDF, 0x67,
++	0x0F, 0x73, 0xAE, 0xED, 0x92,
++	0x0D, 0xB4, 0xF7, 0x8C, 0x5D,
++	0x07, 0x70, 0x38, 0x52, 0x30,
++	0x06, 0x24, 0x33, 0x81, 0xFC,
++	0x02, 0x9E, 0x41, 0x79, 0x4D,
++	0x0E, 0x2E, 0x60, 0x12, 0x9D,
++	0x03, 0xCF, 0x9F, 0x95, 0x23,
++	0x0F, 0xAB, 0x8D, 0x8E, 0xC0,
++	0x03, 0x30, 0x5B, 0x2B, 0x0D,
++	0x0A, 0xB8, 0xD4, 0x2D, 0x0F,
++	0x08, 0xA5, 0x5F, 0x26, 0xA6,
++	0x01, 0xB0, 0x74, 0x69, 0x7F,
++	0x0C, 0x8C, 0xD2, 0x49, 0x95,
++	0x05, 0x19, 0x1B, 0xB0, 0x5A,
++	0x03, 0xA9, 0xD4, 0x29, 0xE4,
++	0x00, 0x73, 0xA1, 0xF5, 0xD4,
++	0x08, 0x67, 0x0F, 0xDB, 0x34,
++	0x09, 0xC3, 0xFA, 0x09, 0xFC,
++	0x0D, 0xC8, 0xE1, 0x3B, 0xB4,
++	0x0E, 0x37, 0xEA, 0x47, 0xEF,
++	0x0E, 0x91, 0x51, 0x06, 0x71,
++	0x09, 0xB9, 0xF5, 0x19, 0x53,
++	0x02, 0x28, 0x56, 0x19, 0x38,
++	0x02, 0x7C, 0x6D, 0x41, 0x80,
++	0x01, 0x28, 0xD6, 0xF8, 0x4B,
++	0x04, 0xE6, 0xFE, 0xBC, 0x68,
++	0x04, 0xB5, 0x20, 0xB5, 0xC7,
++	0x0A, 0x2B, 0x98, 0xDD, 0xC2,
++	0x0E, 0xC9, 0x0C, 0xA8, 0x90,
++	0x0E, 0x17, 0xB3, 0x68, 0x77,
++	0x07, 0xFC, 0x1E, 0xF8, 0xB9,
++	0x00, 0xCA, 0xD6, 0x8F, 0x3E,
++	0x0C, 0xD5, 0x2E, 0x36, 0xAE,
++	0x0C, 0x20, 0xCB, 0x08, 0xC3,
++	0x0B, 0xAE, 0x53, 0xAA, 0x24,
++	0x0A, 0xAF, 0xF6, 0x64, 0x92,
++	0x08, 0x9A, 0x99, 0x8D, 0xC6,
++	0x01, 0xA5, 0xFD, 0x16, 0x3A,
++	0x0B, 0xF4, 0xDD, 0xD0, 0x6B,
++	0x0E, 0xC1, 0x6F, 0xEA, 0xA0,
++	0x02, 0xBC, 0xBB, 0x81, 0xCE,
++	0x01, 0xD7, 0x56, 0xA7, 0xD6,
++	0x03, 0x60, 0xD0, 0xEF, 0x16,
++	0x08, 0x95, 0x51, 0xF7, 0xEA,
++	0x0D, 0xEF, 0x3C, 0x7C, 0x18,
++	0x03, 0x1E, 0xA0, 0x5C, 0x44,
++	0x0C, 0x82, 0xB1, 0x84, 0x25,
++	0x01, 0x6D, 0x69, 0xC5, 0xE1,
++	0x00, 0x7C, 0x07, 0xAD, 0xF1,
++	0x05, 0x33, 0x01, 0x80, 0x91,
++	0x00, 0xFA, 0x2C, 0x75, 0x96,
++	0x00, 0x7B, 0x02, 0xD6, 0xEF,
++	0x08, 0x17, 0xD1, 0x45, 0x05,
++	0x09, 0x77, 0x03, 0x1D, 0x2D,
++	0x0E, 0xA2, 0x41, 0x38, 0x94,
++	0x02, 0xA1, 0xDE, 0x1F, 0xF0,
++	0x02, 0xE7, 0x26, 0x41, 0xFA,
++	0x03, 0xBC, 0x19, 0xFF, 0x92,
++	0x02, 0xD8, 0x4A, 0x98, 0xA8,
++	0x0C, 0x20, 0x8F, 0xCC, 0xB2,
++	0x0E, 0x9B, 0x94, 0xC6, 0x27,
++	0x01, 0x92, 0x5B, 0x72, 0x65,
++	0x0F, 0x01, 0x1A, 0x44, 0x17,
++	0x0E, 0x5A, 0x3D, 0x2C, 0xF5,
++	0x07, 0x41, 0xB5, 0xBB, 0x0A,
++	0x05, 0x6A, 0x80, 0xCF, 0x43,
++	0x0E, 0x07, 0x3E, 0x4F, 0x5D,
++	0x04, 0x86, 0x7F, 0x3D, 0xB3,
++	0x01, 0xBC, 0x3E, 0xE6, 0xFD,
++	0x05, 0xCC, 0x02, 0x53, 0xB4,
++	0x09, 0xF2, 0xE2, 0xA4, 0x71,
++	0x05, 0x71, 0x29, 0x10, 0x08,
++	0x0F, 0x93, 0x72, 0xA3, 0x3D,
++	0x0B, 0x2A, 0x85, 0x69, 0xE2,
++	0x04, 0xB7, 0xE0, 0x52, 0xC6,
++	0x02, 0x32, 0x8D, 0x29, 0x28,
++	0x09, 0x46, 0xF9, 0xE3, 0x1A,
++	0x03, 0x73, 0xF6, 0x0B, 0x5F,
++	0x0E, 0x81, 0x67, 0x65, 0xDC,
++	0x06, 0xF4, 0x32, 0xBC, 0x89,
++	0x07, 0x62, 0x89, 0xE0, 0xC4,
++	0x00, 0xFD, 0xE5, 0xEF, 0xCB,
++	0x01, 0x86, 0x83, 0x68, 0x33,
++	0x06, 0xC5, 0x4C, 0xE3, 0x99,
++	0x08, 0x60, 0xC2, 0x90, 0x9C,
++	0x0F, 0xBA, 0x6F, 0x77, 0x6E,
++	0x0D, 0x88, 0xF3, 0xF0, 0x49,
++	0x0F, 0xC9, 0xAD, 0x98, 0xFF,
++	0x0F, 0x18, 0xBD, 0x51, 0x61,
++	0x0C, 0xB3, 0xC7, 0xDD, 0xF5,
++	0x0F, 0xEC, 0xD6, 0xB2, 0x2A,
++	0x0F, 0x29, 0x2F, 0xB8, 0x5C,
++	0x05, 0x2D, 0x75, 0x12, 0x2A,
++	0x06, 0xF6, 0xC9, 0x02, 0x30,
++	0x0F, 0x83, 0xDF, 0x17, 0x32,
++	0x08, 0x86, 0x31, 0xE7, 0xCD,
++	0x03, 0x93, 0xA2, 0xD5, 0x37,
++	0x0E, 0x42, 0xC6, 0x18, 0x46,
++	0x0C, 0x06, 0x14, 0xD0, 0x4A,
++	0x0C, 0xA5, 0x88, 0x92, 0x2C,
++	0x09, 0x51, 0xD9, 0x18, 0xC8,
++	0x0D, 0x3F, 0x42, 0xCB, 0x99,
++	0x07, 0x8F, 0xBA, 0x0D, 0x6D,
++	0x08, 0x2D, 0x7D, 0x54, 0x80,
++	0x03, 0x97, 0x70, 0xBF, 0x18,
++	0x06, 0xE6, 0x24, 0x33, 0x9C,
++	0x0D, 0xB2, 0x9D, 0xE1, 0xFF,
++	0x0E, 0xBE, 0xEE, 0x68, 0x92,
++	0x07, 0xA1, 0x22, 0x9B, 0x35,
++	0x03, 0x8D, 0xAF, 0x89, 0x88,
++	0x00, 0x42, 0x3C, 0x9C, 0xAB,
++	0x0D, 0xE9, 0xBD, 0x14, 0x2B,
++	0x0F, 0xD9, 0x21, 0xBF, 0x26,
++	0x07, 0xA8, 0xD1, 0x94, 0x69,
++	0x06, 0x47, 0xEE, 0xB2, 0x05,
++	0x05, 0x76, 0xEA, 0xDB, 0xB4,
++	0x0A, 0xFA, 0xA8, 0x12, 0x65,
++	0x0A, 0xE0, 0x73, 0xA2, 0xF5,
++	0x04, 0x48, 0x67, 0x0B, 0xDB,
++	0x04, 0x3B, 0x41, 0xFE, 0x0F,
++	0x07, 0x5C, 0xC8, 0x25, 0x3B,
++	0x0B, 0x80, 0xC9, 0xD6, 0x44,
++	0x0B, 0x57, 0x15, 0x11, 0x00,
++	0x0E, 0xA1, 0x3B, 0x53, 0xFC,
++	0x03, 0x72, 0x28, 0xD6, 0x95,
++	0x02, 0x4B, 0x7E, 0xCD, 0x86,
++	0x00, 0x63, 0x2A, 0xD2, 0xB4,
++	0x00, 0x1D, 0x65, 0x9E, 0x3E,
++	0x08, 0x35, 0xB1, 0x60, 0x46,
++	0x0C, 0xD0, 0xC9, 0x5E, 0x5D,
++	0x08, 0x67, 0xE9, 0xE7, 0xB9,
++	0x08, 0x48, 0xB7, 0xBA, 0x28,
++	0x0D, 0x85, 0x02, 0x1E, 0xD8,
++	0x01, 0x40, 0xEA, 0x7A, 0x8F,
++	0x06, 0xEA, 0xF4, 0x82, 0x76,
++	0x04, 0x24, 0xDC, 0x01, 0x48,
++	0x0A, 0xF2, 0x0C, 0x3A, 0xA6,
++	0x0E, 0x52, 0x56, 0xBF, 0x24,
++	0x0E, 0x7C, 0x3A, 0x95, 0x00,
++	0x0C, 0x53, 0x5B, 0xFD, 0x56,
++	0x0A, 0xCB, 0x38, 0x7D, 0x23,
++	0x02, 0xED, 0xAD, 0x69, 0x6A,
++	0x09, 0x50, 0xDC, 0xBB, 0x41,
++	0x04, 0x91, 0x29, 0x51, 0x31,
++	0x00, 0x3F, 0x6C, 0xD0, 0xDC,
++	0x0F, 0xF8, 0x3D, 0x75, 0xB9,
++	0x00, 0x94, 0xED, 0x1E, 0x7C,
++	0x0C, 0xA9, 0x18, 0x61, 0x9C,
++	0x0C, 0x44, 0x06, 0x11, 0x84,
++	0x05, 0x90, 0xCF, 0x4D, 0xC8,
++	0x08, 0x58, 0x5E, 0xC9, 0xDE,
++	0x03, 0x36, 0x31, 0x01, 0x84,
++	0x0B, 0xCB, 0x5A, 0x20, 0xB5,
++	0x06, 0x78, 0xFB, 0xA6, 0xDC,
++	0x09, 0x82, 0xD7, 0xD1, 0x0A,
++	0x05, 0x79, 0x77, 0x03, 0x9D,
++	0x07, 0xAE, 0x20, 0x43, 0x38,
++	0x05, 0xD9, 0xA1, 0xDA, 0x6C,
++	0x0C, 0x7B, 0xE2, 0x26, 0x4E,
++	0x09, 0xDA, 0x26, 0xF9, 0xB1,
++	0x02, 0x38, 0xDA, 0x38, 0x92,
++	0x08, 0x04, 0x21, 0x09, 0x00,
++	0x0B, 0xDE, 0x9B, 0x91, 0xB1,
++	0x0C, 0xFD, 0x12, 0x57, 0xF2,
++	0x02, 0x60, 0x83, 0x15, 0x06,
++	0x0D, 0xF7, 0x48, 0x6B, 0x0C,
++	0x01, 0xF7, 0x45, 0xAD, 0x73,
++	0x05, 0xAF, 0xAA, 0x8F, 0xE4,
++	0x0A, 0xEE, 0x87, 0x34, 0xA1,
++	0x0D, 0x44, 0x82, 0x70, 0x53,
++	0x09, 0xC0, 0x98, 0x39, 0xAF,
++	0x0D, 0xC6, 0xC2, 0x02, 0x13,
++	0x04, 0x79, 0xF3, 0x68, 0x1D,
++	0x01, 0xB5, 0x71, 0x3B, 0xA8,
++	0x02, 0xC5, 0x3B, 0x93, 0x36,
++	0x07, 0x34, 0x2C, 0x05, 0x29,
++	0x03, 0x24, 0x37, 0xE8, 0x54,
++	0x06, 0x05, 0x3D, 0x0D, 0x6F,
++	0x01, 0x31, 0x36, 0x59, 0xE3,
++	0x0E, 0x83, 0x5B, 0x7B, 0x01,
++	0x0F, 0x55, 0x02, 0x91, 0x0B,
++	0x07, 0x0E, 0x74, 0x9E, 0x94,
++	0x09, 0x0C, 0xE5, 0x7B, 0xAE,
++	0x07, 0x78, 0x7F, 0xC1, 0xC1,
++	0x0B, 0x99, 0x04, 0xA7, 0x46,
++	0x03, 0xE6, 0xC5, 0x48, 0x0D,
++	0x02, 0x9A, 0xE2, 0x2C, 0x3E,
++	0x06, 0xE7, 0x28, 0x45, 0x5D,
++	0x0E, 0x45, 0x0A, 0x53, 0xFC,
++	0x09, 0x6F, 0xC9, 0xAC, 0xB6,
++	0x0C, 0x65, 0x1A, 0x51, 0x28,
++	0x08, 0xAC, 0xB3, 0xC7, 0xE5,
++	0x0E, 0xB6, 0x6C, 0x1A, 0xBE,
++	0x02, 0x03, 0xAB, 0xC7, 0xF8,
++	0x06, 0xEA, 0x22, 0x75, 0x32,
++	0x09, 0xC2, 0xF2, 0xCD, 0xC6,
++	0x00, 0xFF, 0x83, 0xD1, 0xB8,
++	0x0A, 0x09, 0xCE, 0xDF, 0x08,
++	0x0D, 0x8A, 0x95, 0xC6, 0x3A,
++	0x0E, 0x47, 0x64, 0x27, 0x57,
++	0x04, 0x56, 0x9B, 0xF4, 0x9C,
++	0x0A, 0x15, 0xA7, 0xE6, 0x6B,
++	0x0F, 0x93, 0x53, 0x3A, 0xE0,
++	0x00, 0xB7, 0x97, 0xA4, 0x90,
++	0x03, 0x64, 0x92, 0xBA, 0x4D,
++	0x05, 0xD8, 0xAD, 0x71, 0xD4,
++	0x00, 0x54, 0x89, 0x70, 0x79,
++	0x0B, 0xFA, 0x0A, 0x24, 0x33,
++	0x05, 0xED, 0x9A, 0x10, 0xEB,
++	0x0F, 0x07, 0xBE, 0x2A, 0x8B,
++	0x09, 0x9D, 0xA3, 0xCF, 0xB4,
++	0x05, 0x23, 0x89, 0xAB, 0x41,
++	0x08, 0x80, 0x42, 0x30, 0xB3,
++	0x0B, 0x0D, 0xE9, 0xB9, 0x3B,
++	0x0B, 0x4F, 0xD9, 0x25, 0x50,
++	0x0E, 0xDE, 0xE0, 0x3D, 0xBB,
++	0x03, 0xBF, 0x47, 0x08, 0xF6,
++	0x0F, 0x1F, 0x74, 0x9A, 0xD1,
++	0x00, 0x5A, 0xFA, 0xAD, 0x3B,
++	0x0F, 0x2E, 0xE0, 0x7D, 0x5D,
++	0x0E, 0xD4, 0x48, 0x67, 0x33,
++	0x0B, 0x34, 0x3A, 0xC1, 0x47,
++	0x0F, 0x7C, 0x58, 0x4C, 0x2F,
++	0x02, 0xC7, 0x7F, 0x36, 0xEA,
++	0x0F, 0x98, 0x77, 0x91, 0xA5,
++	0x00, 0x84, 0x61, 0x39, 0x6E,
++	0x0B, 0xD3, 0x72, 0x2C, 0x1C,
++	0x07, 0xE2, 0xCB, 0x72, 0x4D,
++	0x04, 0xC6, 0xE3, 0x24, 0x92,
++	0x0E, 0x8B, 0x19, 0x65, 0x49,
++	0x07, 0xE8, 0xF5, 0xBB, 0xA0,
++	0x0F, 0xF6, 0x7B, 0x29, 0x1E,
++	0x04, 0xC2, 0xC7, 0x49, 0x2B,
++	0x02, 0x93, 0xE5, 0x17, 0xB4,
++	0x01, 0xDF, 0x67, 0xF8, 0xDE,
++	0x00, 0xE1, 0x10, 0x46, 0x76,
++	0x07, 0x38, 0xEC, 0x58, 0xCE,
++	0x0E, 0xAE, 0xA6, 0x2E, 0x01,
++	0x00, 0xC4, 0xF2, 0xA0, 0x77,
++	0x0C, 0xE7, 0x16, 0xAD, 0x1F,
++	0x0C, 0x95, 0x7C, 0x94, 0x19,
++	0x08, 0x45, 0xF3, 0xAB, 0x3D,
++	0x0F, 0x39, 0x0F, 0x32, 0x3D,
++	0x00, 0x6B, 0x62, 0x41, 0x58,
++	0x08, 0xA0, 0x56, 0xBA, 0xBB,
++	0x01, 0xCE, 0x1F, 0x57, 0x51,
++	0x03, 0x9D, 0xAB, 0x6A, 0x90,
++	0x0F, 0x8F, 0x5F, 0x3D, 0xF1,
++	0x01, 0xA1, 0x38, 0xEB, 0x9E,
++	0x0F, 0xD8, 0x69, 0x10, 0xED,
++	0x0D, 0x4D, 0x84, 0x84, 0x1B,
++	0x05, 0x07, 0x58, 0xE9, 0x07,
++	0x02, 0xA2, 0x6F, 0x7E, 0xD9,
++	0x0D, 0xF9, 0x37, 0x35, 0x8B,
++	0x07, 0xA3, 0x4B, 0xFA, 0x1E,
++	0x0E, 0x15, 0x8A, 0x7D, 0x2A,
++	0x0E, 0x5D, 0x21, 0xD5, 0x55,
++	0x0B, 0x26, 0x8B, 0xF1, 0x76,
++	0x04, 0x25, 0x8E, 0xAF, 0x03,
++	0x01, 0x5C, 0x99, 0xA1, 0x1E,
++	0x05, 0xF3, 0x43, 0x62, 0xE2,
++	0x01, 0x29, 0xDA, 0x30, 0xCA,
++	0x09, 0xD2, 0x99, 0x58, 0x38,
++	0x03, 0x0B, 0xF6, 0xA5, 0x7F,
++	0x02, 0x32, 0xFE, 0x96, 0x11,
++	0x0A, 0xB4, 0x79, 0x10, 0xDB,
++	0x0B, 0x68, 0x66, 0x03, 0xD9,
++	0x0F, 0x95, 0xB7, 0xDE, 0xA1,
++	0x06, 0xF2, 0xC9, 0x41, 0xA9,
++	0x09, 0x05, 0xAB, 0xAC, 0x01,
++	0x0A, 0xF2, 0xEA, 0x0B, 0xC8,
++	0x0F, 0xDF, 0x40, 0x86, 0x70,
++	0x07, 0xB0, 0x02, 0xBC, 0x3E,
++	0x00, 0xF7, 0xC1, 0xC0, 0xB0,
++	0x03, 0xB4, 0x7D, 0x73, 0x62,
++	0x04, 0x71, 0xB2, 0xF1, 0x31,
++	0x00, 0x08, 0x46, 0x13, 0x95,
++	0x01, 0x3D, 0x97, 0x22, 0x85,
++	0x09, 0x7A, 0x84, 0xB7, 0xE4,
++	0x0D, 0x4E, 0x22, 0x32, 0x79,
++	0x05, 0xEB, 0xF3, 0x56, 0x5B,
++	0x0B, 0x6E, 0x23, 0x56, 0x76,
++	0x02, 0xDD, 0x71, 0x02, 0x61,
++	0x0F, 0xDF, 0x4A, 0x74, 0x96,
++	0x02, 0x09, 0xAC, 0xEC, 0x7B,
++	0x06, 0x87, 0x79, 0x7F, 0xC1,
++	0x0F, 0x8B, 0x9A, 0x00, 0x2D,
++	0x08, 0xF3, 0xE4, 0xC3, 0x02,
++	0x08, 0x6A, 0xE2, 0x62, 0x20,
++	0x0C, 0x8C, 0x25, 0x6A, 0xCC,
++	0x0A, 0x6E, 0x5F, 0x0A, 0xE1,
++	0x06, 0x49, 0x6F, 0x49, 0xA3,
++	0x08, 0x0C, 0x65, 0x9A, 0x55,
++	0x01, 0x63, 0xAC, 0x33, 0xCD,
++	0x0D, 0x06, 0xB6, 0x6C, 0xDC,
++	0x0E, 0xAA, 0x05, 0xAB, 0xC1,
++	0x08, 0x1C, 0xEB, 0x3D, 0x7F,
++	0x09, 0x19, 0xC2, 0xF6, 0xFE,
++	0x06, 0xF0, 0x7F, 0x8F, 0xDF,
++	0x0F, 0x34, 0x89, 0x40, 0x11,
++	0x0D, 0xCE, 0xC6, 0x11, 0x86,
++	0x0E, 0xC4, 0xC4, 0x40, 0x1B,
++	0x08, 0x4E, 0x55, 0x8B, 0xF0,
++	0x05, 0x0A, 0xF5, 0xA7, 0xDE,
++	0x0C, 0x5E, 0xA3, 0x53, 0x30,
++	0x01, 0x4B, 0xD4, 0xA3, 0xA2,
++	0x07, 0x59, 0x67, 0x91, 0xA7,
++	0x0B, 0x6D, 0xD8, 0x2D, 0xFD,
++	0x02, 0x0A, 0x57, 0x97, 0xF0,
++	0x09, 0xD2, 0xFA, 0xEA, 0xF7,
++	0x03, 0x84, 0x6D, 0x94, 0x54,
++	0x09, 0x7D, 0x07, 0xB2, 0xAE,
++	0x0E, 0x11, 0xCF, 0x23, 0xCB,
++	0x0B, 0x15, 0x23, 0x89, 0x99,
++	0x01, 0x02, 0xE0, 0x4F, 0xF0,
++	0x06, 0xA8, 0x40, 0x69, 0xBD,
++	0x04, 0x2B, 0x4D, 0xD5, 0xAE,
++	0x06, 0x26, 0x66, 0x61, 0xF1,
++	0x0C, 0x6B, 0x3F, 0x47, 0x0E,
++	0x02, 0xCF, 0x1D, 0x70, 0x90,
++	0x0B, 0xB0, 0x5A, 0xFE, 0x9A,
++	0x04, 0xAF, 0x2E, 0xED, 0xF7,
++	0x0C, 0xED, 0x54, 0x05, 0xA7,
++	0x0B, 0xDB, 0x34, 0x38, 0xC6,
++	0x05, 0x8C, 0xAE, 0xD8, 0xF9,
++	0x0E, 0xB8, 0x95, 0x1F, 0x36,
++	0x0A, 0x47, 0x19, 0x5A, 0x17,
++	0x01, 0x00, 0x86, 0x6C, 0x7C,
++	0x0D, 0x98, 0x0A, 0x70, 0x9A,
++	0x06, 0x9F, 0xB6, 0x46, 0x3A,
++	0x05, 0x49, 0x40, 0x6F, 0xA8,
++	0x0B, 0x7E, 0x67, 0x1D, 0xB6,
++	0x0E, 0x3E, 0xE8, 0x71, 0xA0,
++	0x08, 0xB5, 0x75, 0x50, 0x29,
++	0x07, 0xDC, 0x20, 0xEB, 0x49,
++	0x03, 0x81, 0x10, 0xDE, 0x97,
++	0x0F, 0x62, 0x17, 0x8A, 0x3C,
++	0x04, 0xFB, 0xE5, 0x10, 0x4E,
++	0x06, 0x8F, 0x3C, 0x62, 0x1D,
++	0x0E, 0x36, 0xAE, 0xAB, 0xA6,
++	0x08, 0x88, 0x22, 0x7E, 0xBD,
++	0x0F, 0x25, 0xC0, 0x52, 0x3E,
++	0x06, 0x66, 0xB2, 0xBC, 0x68,
++	0x03, 0x83, 0xA4, 0x51, 0xA1,
++	0x05, 0x96, 0x9A, 0xCB, 0x3C,
++	0x0D, 0xD0, 0x6B, 0x63, 0x45,
++	0x09, 0xEA, 0xA0, 0x54, 0xBE,
++	0x0B, 0x81, 0xCE, 0x93, 0xD7,
++	0x01, 0x21, 0x1E, 0x2B, 0x26,
++	0x08, 0x6F, 0xAF, 0xE8, 0xBD,
++	0x0F, 0xF2, 0x10, 0x94, 0xED,
++	0x07, 0xFD, 0x38, 0xA5, 0x1C,
++	0x04, 0x5E, 0x6C, 0x54, 0xB3,
++	0x0B, 0x87, 0x82, 0x58, 0x6D,
++	0x05, 0x48, 0x01, 0x56, 0x3E,
++	0x00, 0x2F, 0x99, 0x39, 0xB3,
++	0x0B, 0x8F, 0xC7, 0xCB, 0xFE,
++	0x0C, 0x75, 0x96, 0x7B, 0xCD,
++	0x00, 0xD6, 0xDD, 0x81, 0xD2,
++	0x05, 0x40, 0xA5, 0x74, 0x33,
++	0x0A, 0x1D, 0xC7, 0xAE, 0xA2,
++	0x0B, 0x3A, 0x5E, 0xDF, 0xE1,
++	0x04, 0x1C, 0x86, 0x7B, 0xE6,
++	0x08, 0xC0, 0x19, 0xDA, 0x3C,
++	0x09, 0xB1, 0x52, 0x26, 0xC7,
++	0x01, 0x19, 0x6C, 0x28, 0x23,
++	0x01, 0xCA, 0x34, 0xCE, 0x1B,
++	0x08, 0x42, 0x70, 0xFD, 0x12,
++	0x03, 0xF0, 0x6A, 0x66, 0x83,
++	0x03, 0x45, 0xF8, 0xF4, 0x5C,
++	0x03, 0x2C, 0x71, 0xF7, 0x41,
++	0x04, 0xB9, 0x45, 0x9F, 0x2A,
++	0x0B, 0x49, 0x82, 0x6E, 0x03,
++	0x03, 0x4F, 0x9D, 0x44, 0x86,
++	0x02, 0xBD, 0xB3, 0x45, 0xBC,
++	0x07, 0xE0, 0x77, 0xD5, 0x4C,
++	0x02, 0x52, 0x36, 0x77, 0xBA,
++	0x00, 0xA4, 0x70, 0x33, 0xF1,
++	0x08, 0x10, 0xC9, 0xF6, 0x93,
++	0x04, 0x60, 0x7D, 0x37, 0x22,
++	0x05, 0x69, 0xFB, 0x32, 0xB5,
++	0x0C, 0xC6, 0xAC, 0x0B, 0xF2,
++	0x0D, 0x2F, 0xEE, 0x97, 0x54,
++	0x03, 0xE0, 0x85, 0x83, 0x5F,
++	0x0C, 0x08, 0xDE, 0xD5, 0x03,
++	0x0B, 0x64, 0xEC, 0x0E, 0x74,
++	0x0E, 0xBA, 0x8B, 0x12, 0xA8,
++	0x02, 0xE7, 0x66, 0xD4, 0x7F,
++	0x09, 0xEF, 0x0A, 0x19, 0x84,
++	0x0E, 0x68, 0x32, 0xE6, 0x45,
++	0x00, 0xE1, 0x6A, 0xE2, 0xE2,
++	0x0A, 0x13, 0xF6, 0xA7, 0x2E,
++	0x03, 0x7A, 0x6E, 0xC5, 0x0A,
++	0x03, 0xF6, 0x4A, 0xEF, 0xC9,
++	0x0D, 0x98, 0x0C, 0x73, 0x1A,
++	0x07, 0xD1, 0xE3, 0xAC, 0x33,
++	0x07, 0xDC, 0x86, 0xB8, 0xF1,
++	0x0F, 0xBC, 0xEA, 0x05, 0xAB,
++	0x01, 0xBB, 0x62, 0xE9, 0x39,
++	0x05, 0x12, 0x19, 0x42, 0xF6,
++	0x0D, 0x0E, 0xF3, 0x7F, 0x83,
++	0x0B, 0x17, 0x32, 0x0F, 0xCE,
++	0x08, 0xE7, 0x0D, 0xBA, 0x11,
++	0x07, 0xD4, 0x00, 0xC4, 0x40,
++	0x01, 0x18, 0x4A, 0x43, 0x84,
++	0x0C, 0xCE, 0xED, 0x18, 0x67,
++	0x0C, 0x92, 0xD9, 0xB5, 0xD1,
++	0x0A, 0x1B, 0xBC, 0x34, 0xBB,
++	0x09, 0x44, 0xBB, 0xE7, 0x8F,
++	0x0A, 0x0D, 0x6D, 0xDC, 0x97,
++	0x04, 0xD6, 0x4E, 0x57, 0x66,
++	0x0A, 0x3A, 0x56, 0x7A, 0xE8,
++	0x0D, 0x33, 0x45, 0xE1, 0xDA,
++	0x04, 0x63, 0xBB, 0x07, 0x4C,
++	0x04, 0x67, 0x97, 0x1D, 0xAB,
++	0x06, 0x9B, 0xD5, 0x2F, 0x0D,
++	0x09, 0x89, 0x88, 0x8C, 0x02,
++	0x02, 0x9C, 0xAB, 0x09, 0x69,
++	0x08, 0x94, 0xCD, 0x4F, 0xD9,
++	0x04, 0x3D, 0x46, 0xA6, 0x60,
++	0x09, 0x14, 0xC9, 0x7D, 0xC5,
++	0x0C, 0xB2, 0xCF, 0x1B, 0xB4,
++	0x0B, 0x59, 0x90, 0x57, 0xFF,
++	0x09, 0x95, 0x4F, 0x2E, 0xD3,
++	0x0B, 0xA4, 0x75, 0xD4, 0x7A,
++	0x07, 0x0B, 0xD9, 0x30, 0xF1,
++	0x0D, 0x7F, 0x3F, 0x7C, 0x5C,
++	0x04, 0x25, 0x39, 0x47, 0x91,
++	0x06, 0x2A, 0x47, 0x15, 0x4A,
++	0x0B, 0x90, 0x94, 0x89, 0x21,
++	0x00, 0x57, 0x9B, 0xDE, 0xF2,
++	0x01, 0xDF, 0x5F, 0xBF, 0x8B,
++	0x0E, 0x4D, 0x4C, 0xC4, 0x27,
++	0x08, 0xD2, 0xFE, 0x8F, 0x99,
++	0x05, 0x9E, 0x3C, 0xE6, 0x7C,
++	0x07, 0x60, 0xB4, 0xF1, 0x94,
++	0x00, 0x5E, 0x9D, 0x40, 0x6D,
++	0x0B, 0xEB, 0xA8, 0x90, 0x4E,
++	0x05, 0xB6, 0x6C, 0x77, 0x07,
++	0x0D, 0xFE, 0x18, 0xB5, 0x81,
++	0x0B, 0x14, 0xCF, 0x3E, 0x6C,
++	0x0E, 0x8D, 0xA5, 0xAE, 0x2E,
++	0x0B, 0x01, 0xC8, 0xC2, 0x72,
++	0x0C, 0x37, 0xA6, 0x62, 0x9A,
++	0x01, 0x1F, 0x64, 0x96, 0xFF,
++	0x03, 0x19, 0x60, 0xC4, 0xD1,
++	0x0C, 0x7C, 0xF6, 0xBA, 0x8B,
++	0x0D, 0xF8, 0x33, 0xED, 0xE4,
++	0x09, 0xEB, 0x4A, 0x2C, 0x92,
++	0x08, 0xBB, 0x82, 0xCE, 0x13,
++	0x03, 0x51, 0x21, 0x9A, 0xEF,
++	0x0D, 0xD0, 0x2B, 0x0F, 0x2F,
++	0x0C, 0xF0, 0xB3, 0x20, 0x94,
++	0x04, 0x9F, 0xBF, 0x5A, 0x29,
++	0x0C, 0x6D, 0x5C, 0x4C, 0x44,
++	0x0E, 0x11, 0x85, 0x65, 0x56,
++	0x0F, 0x4D, 0xC8, 0xA7, 0x81,
++	0x0E, 0xC9, 0x2D, 0xFE, 0xAF,
++	0x09, 0xC1, 0x85, 0x24, 0x7D,
++	0x0A, 0x2C, 0x75, 0x96, 0x78,
++	0x03, 0x09, 0x76, 0x5C, 0x01,
++	0x03, 0xD5, 0x44, 0xA4, 0xF9,
++	0x07, 0x03, 0x99, 0x27, 0xAE,
++	0x03, 0x43, 0xF8, 0x58, 0xAA,
++	0x00, 0x5C, 0x5F, 0xF0, 0x7B,
++	0x08, 0xE5, 0xE0, 0x29, 0xDE,
++	0x04, 0x79, 0x16, 0xD3, 0xB8,
++	0x0A, 0xB8, 0x99, 0x08, 0x04,
++	0x0A, 0x89, 0x2A, 0xB2, 0x5E,
++	0x0A, 0x91, 0x86, 0xB4, 0x24,
++	0x08, 0x58, 0x59, 0xEA, 0x67,
++	0x0A, 0x99, 0xA9, 0x15, 0x74,
++	0x04, 0xEB, 0x23, 0x31, 0xC6,
++	0x0D, 0xAC, 0x55, 0xC5, 0xAC,
++	0x0A, 0x81, 0x4A, 0xF4, 0x35,
++	0x07, 0x3A, 0x4F, 0x5A, 0xDE,
++	0x0C, 0xB0, 0xB4, 0x34, 0x0B,
++	0x0C, 0x3F, 0xE0, 0xF7, 0xC5,
++	0x0E, 0x82, 0x57, 0xB5, 0xF9,
++	0x0A, 0xE2, 0x44, 0xF3, 0x35,
++	0x00, 0x31, 0xD0, 0x08, 0x46,
++	0x0B, 0x17, 0x21, 0xB1, 0x77,
++	0x08, 0x86, 0xCE, 0x7B, 0x26,
++	0x0E, 0xE4, 0x14, 0xC0, 0x46,
++	0x0B, 0x8C, 0xE7, 0xE8, 0xF1,
++	0x06, 0x59, 0xE3, 0xEE, 0x83,
++	0x0B, 0x76, 0x0B, 0x5B, 0xCB,
++	0x02, 0x95, 0xE5, 0xDC, 0x0E,
++	0x04, 0x9E, 0xB3, 0x89, 0x0C,
++	0x01, 0x7B, 0x66, 0x87, 0x78,
++	0x0E, 0xC1, 0x2B, 0x8B, 0x40,
++	0x0C, 0x27, 0xC8, 0xF3, 0xE6,
++	0x05, 0x48, 0xE3, 0x6C, 0x39,
++	0x02, 0x20, 0x10, 0x8B, 0xBD,
++	0x00, 0x03, 0x73, 0xE9, 0x1F,
++	0x0A, 0xD3, 0xF6, 0x49, 0x6F,
++	0x00, 0xA8, 0x38, 0x0D, 0xE5,
++	0x03, 0xDD, 0x91, 0xE3, 0xEC,
++	0x0B, 0x44, 0xE9, 0x0A, 0x39,
++	0x08, 0x16, 0xA6, 0x2E, 0xC5,
++	0x0B, 0xCB, 0xB8, 0x1C, 0xE9,
++	0x0C, 0x77, 0x52, 0x19, 0xC2,
++	0x0F, 0x4D, 0xFA, 0xF0, 0x3F,
++	0x03, 0xDF, 0x03, 0x32, 0x09,
++	0x0E, 0xD1, 0xE4, 0xCD, 0x8A,
++	0x00, 0x6C, 0xB5, 0xC4, 0xC4,
++	0x01, 0x88, 0xF8, 0x4E, 0x55,
++	0x06, 0xF4, 0xDC, 0x8A, 0x15,
++	0x0E, 0x6E, 0xD2, 0xDB, 0x62,
++	0x09, 0x33, 0xAD, 0xCA, 0x3C,
++	0x06, 0xA2, 0x07, 0x55, 0x27,
++	0x06, 0x38, 0x09, 0x4D, 0x18,
++	0x07, 0x7E, 0xE2, 0x8A, 0x17,
++	0x07, 0x70, 0x39, 0xD6, 0x08,
++	0x02, 0x25, 0xB3, 0x99, 0xED,
++	0x0A, 0x1D, 0xE1, 0xC9, 0x8D,
++	0x0A, 0x2E, 0x64, 0x12, 0x1D,
++	0x07, 0xCF, 0x99, 0x15, 0xA3,
++	0x0C, 0xAB, 0x49, 0x86, 0xC9,
++	0x03, 0xB0, 0x7C, 0xAB, 0x0D,
++	0x01, 0x33, 0x14, 0x26, 0x8F,
++	0x09, 0x25, 0xBF, 0x30, 0x24,
++	0x00, 0x31, 0x94, 0x4F, 0xBD,
++	0x0F, 0x8D, 0x38, 0x4F, 0x1B,
++	0x04, 0x1A, 0xD9, 0xBD, 0x5E,
++	0x02, 0xA8, 0x94, 0xA2, 0xAE,
++	0x08, 0x7A, 0x24, 0xF8, 0x14,
++	0x08, 0x67, 0x09, 0xD9, 0x86,
++	0x00, 0x40, 0x27, 0x0B, 0x79,
++	0x00, 0xE8, 0x25, 0x3B, 0x76,
++	0x07, 0xB6, 0x8A, 0x4B, 0xDB,
++	0x0C, 0x90, 0xF3, 0x8D, 0x80,
++	0x0D, 0x39, 0x55, 0x9B, 0xDC,
++	0x0A, 0xE0, 0xEE, 0x99, 0x32,
++	0x03, 0xFF, 0xED, 0x40, 0x80,
++	0x03, 0xAD, 0x70, 0xF0, 0xC2,
++	0x07, 0x66, 0x5C, 0xBE, 0xF8,
++	0x0D, 0x37, 0xC0, 0xB5, 0xF5,
++	0x09, 0x29, 0x9B, 0xDD, 0x00,
++	0x0E, 0xC8, 0x2A, 0xA4, 0xD0,
++	0x0E, 0x17, 0xB6, 0x6E, 0x3D,
++	0x03, 0xFC, 0x1E, 0xFC, 0x79,
++	0x00, 0x4A, 0x72, 0x8F, 0x3E,
++	0x0D, 0x56, 0xCE, 0x26, 0xAC,
++	0x07, 0xA2, 0xE2, 0xB8, 0xC0,
++	0x02, 0xAC, 0x36, 0xA2, 0x6E,
++	0x00, 0xAD, 0x38, 0xE0, 0x5C,
++	0x04, 0x9A, 0x1D, 0x80, 0x06,
++	0x09, 0x27, 0xF9, 0x16, 0xFA,
++	0x02, 0x3C, 0xB9, 0xD0, 0xAB,
++	0x07, 0xC3, 0x2B, 0xEA, 0x63,
++	0x06, 0xBC, 0xBB, 0x85, 0x8E,
++	0x07, 0xD7, 0x51, 0x25, 0x1C,
++	0x0F, 0x6E, 0xD0, 0xEF, 0x0F,
++	0x09, 0x3D, 0x31, 0x73, 0x20,
++	0x0D, 0xEC, 0xDF, 0xFC, 0x98,
++	0x09, 0x1C, 0x6D, 0xD8, 0x46,
++	0x04, 0x02, 0x13, 0x80, 0x6F,
++	0x03, 0x6F, 0x4D, 0xC8, 0xA1,
++	0x06, 0x7E, 0xCA, 0xAD, 0xF7,
++	0x05, 0x33, 0x17, 0x8C, 0xA3,
++	0x01, 0x3A, 0x2E, 0x72, 0x0B,
++	0x08, 0xFB, 0xA0, 0x56, 0xD7,
++	0x02, 0xD7, 0xD1, 0xC0, 0x6F,
++	0x09, 0x77, 0x07, 0x1D, 0x2D,
++	0x0E, 0xA2, 0x47, 0xB8, 0x54,
++	0x09, 0xA1, 0xDA, 0x9F, 0xFA,
++	0x0B, 0xE2, 0xE6, 0xC1, 0xE3,
++	0x0A, 0x3C, 0xFB, 0xB1, 0x98,
++	0x03, 0xDA, 0xB8, 0x98, 0x88,
++	0x0E, 0xC3, 0x11, 0x4D, 0x1F,
++	0x0E, 0x9B, 0x91, 0x5E, 0x23,
++	0x0D, 0x92, 0x5B, 0xE2, 0x6A,
++	0x0E, 0x2B, 0x99, 0x56, 0x17,
++	0x0C, 0xF0, 0x4B, 0x0C, 0x71,
++	0x0E, 0x69, 0x6D, 0xBB, 0x85,
++	0x06, 0x02, 0x61, 0x4A, 0x72,
++	0x0E, 0x07, 0x3A, 0x59, 0x5F,
++	0x04, 0x86, 0x70, 0xAB, 0xF1,
++	0x03, 0xBC, 0x3F, 0xF6, 0x75,
++	0x05, 0xCC, 0x82, 0x75, 0x76,
++	0x07, 0x72, 0x52, 0xA4, 0x71,
++	0x0E, 0x71, 0x31, 0x1E, 0x41,
++	0x0F, 0x93, 0x75, 0x61, 0xBD,
++	0x0E, 0xA3, 0x65, 0x75, 0xFB,
++	0x04, 0xB7, 0xE4, 0xC8, 0x55,
++	0x00, 0x32, 0x8D, 0x3F, 0x68,
++	0x07, 0xD6, 0x59, 0xF3, 0x6E,
++	0x05, 0x73, 0xF6, 0x1B, 0xDF,
++	0x03, 0x2B, 0x15, 0xF5, 0x5C,
++	0x08, 0xDC, 0x3E, 0xAA, 0x09,
++	0x0A, 0x48, 0xDB, 0x46, 0x07,
++	0x0F, 0x57, 0x01, 0xEF, 0x0B,
++	0x0E, 0x2D, 0x67, 0x68, 0x73,
++	0x06, 0xED, 0xC8, 0xF5, 0x68,
++	0x02, 0x4B, 0xA0, 0x06, 0xCE,
++	0x07, 0x2A, 0xC3, 0x6C, 0xEC,
++	0x0C, 0x10, 0xB3, 0xFB, 0x89,
++	0x0F, 0xC9, 0xA9, 0xBE, 0x0E,
++	0x0F, 0x19, 0x86, 0x51, 0x67,
++	0x02, 0x32, 0xF7, 0xDD, 0x06,
++	0x0D, 0xEC, 0x16, 0xB0, 0xB7,
++	0x09, 0x2A, 0x27, 0xB8, 0x02,
++	0x09, 0x3D, 0x79, 0x10, 0x9A,
++	0x0B, 0x74, 0xE5, 0x02, 0xEC,
++	0x05, 0x80, 0x39, 0x17, 0x3A,
++	0x05, 0x52, 0xD1, 0xE7, 0xDA,
++	0x02, 0x39, 0x66, 0xD3, 0x84,
++	0x08, 0x72, 0x21, 0x18, 0x52,
++	0x0D, 0x86, 0xF0, 0xD8, 0xC1,
++	0x0C, 0x27, 0x0C, 0x92, 0x1F,
++	0x0A, 0xDD, 0xD0, 0x19, 0x1D,
++	0x0C, 0x17, 0x06, 0xC1, 0x19,
++	0x0F, 0x0D, 0x9E, 0x0D, 0xAD,
++	0x01, 0x2D, 0xBD, 0x54, 0xCA,
++	0x06, 0x12, 0x90, 0x3D, 0x98,
++	0x00, 0x2A, 0x26, 0xB4, 0x52,
++	0x09, 0x9A, 0x1D, 0xE5, 0xBF,
++	0x05, 0xBE, 0x2A, 0x60, 0x52,
++	0x0D, 0x23, 0x6F, 0x9B, 0x15,
++	0x02, 0x8C, 0x6B, 0x89, 0x88,
++	0x02, 0x42, 0x34, 0x98, 0xEB,
++	0x0D, 0xE9, 0xB9, 0x14, 0x2B,
++	0x0E, 0xD8, 0xE5, 0xBB, 0xF1,
++	0x0F, 0xE0, 0xD1, 0x95, 0xA9,
++	0x06, 0x6D, 0x4E, 0xB6, 0x4F,
++	0x06, 0xF2, 0xFE, 0xDB, 0x70,
++	0x00, 0xF9, 0x59, 0x14, 0x8F,
++	0x0C, 0xE0, 0x73, 0xA0, 0x75,
++	0x04, 0x48, 0x67, 0x0B, 0xDB,
++	0x05, 0x3B, 0x03, 0xFE, 0x0F,
++	0x0C, 0x5C, 0xC8, 0x25, 0x71,
++	0x0E, 0xDF, 0xFE, 0x2E, 0xC7,
++	0x00, 0x57, 0x13, 0x11, 0x00,
++	0x08, 0x60, 0xD3, 0x96, 0x05,
++	0x0B, 0x72, 0x20, 0x52, 0xD4,
++	0x0A, 0x4B, 0x7E, 0x4C, 0x9B,
++	0x08, 0xCB, 0x88, 0xD4, 0xBE,
++	0x07, 0x0D, 0x65, 0x9E, 0x3D,
++	0x0E, 0x35, 0xB3, 0x64, 0xF5,
++	0x0D, 0x50, 0x2D, 0x5E, 0x5D,
++	0x03, 0x67, 0xAD, 0xEF, 0xE8,
++	0x09, 0xDE, 0xD7, 0xB6, 0xA8,
++	0x04, 0x96, 0x3C, 0x1A, 0x38,
++	0x01, 0x12, 0x0A, 0x77, 0x4F,
++	0x0E, 0xFD, 0xF0, 0x8E, 0x36,
++	0x0E, 0x26, 0x22, 0x01, 0x08,
++	0x02, 0x72, 0xAC, 0x37, 0xA6,
++	0x06, 0x50, 0xAD, 0x39, 0x24,
++	0x0E, 0x34, 0x3A, 0x99, 0xC0,
++	0x06, 0xD0, 0x0D, 0xFD, 0x16,
++	0x01, 0xCB, 0x3C, 0x7D, 0xD0,
++	0x03, 0x6E, 0x41, 0x65, 0x2A,
++	0x08, 0xD4, 0x3E, 0xB7, 0x81,
++	0x04, 0x97, 0x74, 0x51, 0x01,
++	0x00, 0x2F, 0x6D, 0x50, 0xEC,
++	0x07, 0x7E, 0xBD, 0xF1, 0x33,
++	0x0A, 0x90, 0x48, 0x1E, 0x3C,
++	0x00, 0x29, 0xBE, 0x60, 0x1C,
++	0x04, 0xC5, 0xA2, 0x1C, 0x44,
++	0x0D, 0xD1, 0xCF, 0x40, 0x08,
++	0x01, 0x5A, 0x7E, 0xC4, 0x29,
++	0x09, 0x35, 0x33, 0x05, 0xC9,
++	0x08, 0xCF, 0x50, 0x28, 0x0E,
++	0x0D, 0xFB, 0x19, 0x2D, 0x92,
++	0x04, 0x30, 0x97, 0xD5, 0x80,
++	0x0F, 0x7D, 0x73, 0x83, 0x8D,
++	0x0E, 0x9E, 0x62, 0x43, 0xF8,
++	0x0E, 0xD9, 0xA1, 0xDE, 0x1F,
++	0x00, 0x7B, 0xE2, 0xE6, 0x41,
++	0x02, 0x5E, 0x96, 0xFF, 0x32,
++	0x09, 0xBB, 0x38, 0x38, 0x98,
++	0x01, 0xB6, 0x63, 0x09, 0x0A,
++	0x0A, 0xDA, 0x9C, 0x91, 0x52,
++	0x0D, 0xCD, 0x52, 0x5B, 0x32,
++	0x0A, 0x66, 0x05, 0x17, 0x0F,
++	0x07, 0xF4, 0x58, 0x6B, 0x66,
++	0x01, 0xF7, 0x41, 0x2B, 0x31,
++	0x09, 0xAF, 0xAA, 0x01, 0x59,
++	0x02, 0xEE, 0x07, 0x39, 0x0B,
++	0x05, 0xC7, 0xA5, 0x32, 0x29,
++	0x0B, 0x41, 0x9C, 0x6F, 0x34,
++	0x0D, 0xC1, 0xC7, 0x02, 0x57,
++	0x0C, 0xF9, 0x53, 0x62, 0xA4,
++	0x01, 0xB5, 0x71, 0x31, 0xE2,
++	0x08, 0x46, 0x13, 0x57, 0xE3,
++	0x0D, 0x37, 0x22, 0xD6, 0x2D,
++	0x0B, 0x24, 0xB7, 0x26, 0x56,
++	0x07, 0x82, 0x81, 0x09, 0x65,
++	0x08, 0xB1, 0xD6, 0x49, 0xE3,
++	0x0E, 0x83, 0x5B, 0x66, 0x0B,
++	0x04, 0xD1, 0xB1, 0x13, 0x94,
++	0x0C, 0x0E, 0x70, 0x9E, 0xBA,
++	0x09, 0x0C, 0xE5, 0x75, 0x2F,
++	0x07, 0x78, 0x7A, 0x42, 0xEA,
++	0x00, 0x1D, 0xBD, 0xA9, 0xAC,
++	0x03, 0xE6, 0xC9, 0xCE, 0x29,
++	0x01, 0x66, 0xDB, 0x26, 0x61,
++	0x0C, 0x27, 0x2D, 0x45, 0xB0,
++	0x0C, 0x45, 0x0F, 0xD5, 0x36,
++	0x09, 0x6F, 0xC9, 0xAA, 0xE2,
++	0x0C, 0x05, 0x9A, 0x5F, 0xD1,
++	0x03, 0x4C, 0x13, 0xC7, 0xDD,
++	0x0F, 0x35, 0x8C, 0x94, 0x3E,
++	0x03, 0x07, 0x2B, 0xCD, 0x38,
++	0x06, 0xED, 0x25, 0xF5, 0x1A,
++	0x09, 0xC2, 0xF1, 0x4D, 0x04,
++	0x00, 0xFF, 0x82, 0x5B, 0xDD,
++	0x02, 0x09, 0x4E, 0xDD, 0xED,
++	0x07, 0x8E, 0x8A, 0xC6, 0xD4,
++	0x0D, 0x47, 0x20, 0x23, 0x98,
++	0x07, 0x57, 0xE2, 0xF4, 0x1C,
++	0x0A, 0x15, 0xA6, 0xE8, 0x58,
++	0x05, 0x97, 0x48, 0x30, 0x1A,
++	0x0A, 0x34, 0xBF, 0xA2, 0xCD,
++	0x00, 0xE7, 0x6F, 0xBA, 0x3C,
++	0x04, 0xD8, 0xEC, 0xFF, 0xD4,
++	0x00, 0x53, 0x88, 0xF0, 0x79,
++	0x0B, 0x7A, 0x2A, 0x26, 0xB3,
++	0x05, 0xED, 0x9A, 0x13, 0xA8,
++	0x05, 0x03, 0xA1, 0xAE, 0x24,
++	0x0B, 0x9F, 0x83, 0xCD, 0x1B,
++	0x0F, 0x27, 0x92, 0x2B, 0x8B,
++	0x08, 0x80, 0x42, 0x3C, 0xAD,
++	0x0B, 0x0D, 0xEB, 0xB9, 0x14,
++	0x05, 0xCE, 0xE9, 0x25, 0xBF,
++	0x06, 0xA6, 0x60, 0x1F, 0x89,
++	0x05, 0x7F, 0x44, 0x4E, 0xBC,
++	0x07, 0x9F, 0xC0, 0x1A, 0x5B,
++	0x08, 0xF8, 0xDA, 0xA8, 0x94,
++	0x05, 0x2A, 0xC5, 0xF3, 0xA0,
++	0x0C, 0xD4, 0x88, 0x6B, 0x4B,
++	0x01, 0x30, 0x1F, 0x43, 0xBE,
++	0x07, 0xFC, 0xFC, 0xC8, 0x25,
++	0x0B, 0x47, 0x9B, 0x36, 0x2A,
++	0x07, 0x1B, 0x5B, 0x13, 0x11,
++	0x02, 0x84, 0x65, 0x3F, 0x16,
++	0x03, 0x53, 0xD6, 0x28, 0xD6,
++	0x0F, 0x53, 0xE9, 0x70, 0x04,
++	0x05, 0x41, 0x82, 0x24, 0xD2,
++	0x07, 0x81, 0x7D, 0x68, 0x5E,
++	0x0E, 0xE8, 0x37, 0x91, 0x22,
++	0x0F, 0xF1, 0x70, 0x29, 0x5A,
++	0x0D, 0xC0, 0xE5, 0x47, 0x2F,
++	0x00, 0x90, 0x4A, 0x17, 0x76,
++	0x00, 0xF7, 0x26, 0xFE, 0x9E,
++	0x03, 0x3D, 0x2C, 0xCA, 0x44,
++	0x06, 0xBC, 0x6D, 0x56, 0x0E,
++	0x0C, 0xAA, 0x0B, 0x22, 0x05,
++	0x01, 0xC2, 0xB2, 0xAC, 0x37,
++	0x06, 0xE4, 0x50, 0xA1, 0x0D,
++	0x04, 0x96, 0xFD, 0x16, 0x13,
++	0x00, 0xC6, 0x53, 0xA3, 0x77,
++	0x0A, 0x3A, 0xCB, 0xFC, 0x4E,
++	0x0C, 0x6B, 0x6A, 0xC1, 0x59,
++	0x02, 0xA0, 0xD2, 0xB2, 0xBB,
++	0x09, 0xCF, 0x13, 0xDB, 0xD1,
++	0x01, 0x9C, 0x2F, 0x62, 0x55,
++	0x0F, 0x0F, 0xF8, 0x39, 0xC3,
++	0x03, 0x20, 0x94, 0xE0, 0x9D,
++	0x00, 0xD8, 0xA8, 0xDC, 0x6E,
++	0x0C, 0x4C, 0x46, 0x0C, 0x58,
++	0x0C, 0xE5, 0xD8, 0xE3, 0xD0,
++	0x00, 0xA0, 0xDB, 0xFE, 0x89,
++	0x05, 0x79, 0x94, 0xB1, 0x81,
++	0x07, 0x27, 0xF7, 0x7E, 0x1E,
++	0x0D, 0x16, 0xD8, 0xF9, 0x20,
++	0x0C, 0xD9, 0xB4, 0xD7, 0xF5,
++	0x09, 0xA5, 0xB9, 0x77, 0xC3,
++	0x0D, 0x27, 0xAA, 0xA2, 0x43,
++	0x08, 0x5E, 0xD9, 0xA1, 0xDE,
++	0x07, 0xF0, 0xF9, 0xE2, 0x26,
++	0x0B, 0x2D, 0x90, 0xBC, 0xFB,
++	0x0F, 0xD3, 0x08, 0xDA, 0xB8,
++	0x00, 0x00, 0xA4, 0x2E, 0xC9,
++	0x0A, 0xB0, 0xDC, 0xBB, 0x98,
++	0x02, 0xB4, 0xFD, 0xB6, 0x08,
++	0x0A, 0xEA, 0xC6, 0x03, 0x93,
++	0x0F, 0x37, 0x14, 0x58, 0x6B,
++	0x0C, 0xF1, 0xF7, 0x72, 0xAE,
++	0x0B, 0x05, 0xAF, 0xEC, 0xDA,
++	0x0A, 0xF2, 0xEE, 0x00, 0xE0,
++	0x03, 0x42, 0xBB, 0x7A, 0x41,
++	0x0D, 0xB3, 0x43, 0xB2, 0x76,
++	0x04, 0xF7, 0xC4, 0x4A, 0x01,
++	0x0A, 0xB4, 0xB8, 0x73, 0xE2,
++	0x05, 0x2B, 0xF4, 0x7C, 0xB5,
++	0x0A, 0x0C, 0x01, 0x93, 0x97,
++	0x08, 0xBD, 0xF7, 0x20, 0x05,
++	0x03, 0xFF, 0x63, 0x37, 0xC4,
++	0x08, 0xCC, 0x05, 0xF2, 0x83,
++	0x0F, 0xE8, 0xB1, 0xD8, 0x44,
++	0x0A, 0xEE, 0x43, 0x57, 0x36,
++	0x03, 0xDD, 0x21, 0x04, 0xD5,
++	0x0F, 0xD8, 0x4A, 0xF4, 0x96,
++	0x00, 0x49, 0x0E, 0xE9, 0xFC,
++	0x0E, 0x07, 0xD8, 0x7E, 0x41,
++	0x04, 0x08, 0x7B, 0x84, 0xA7,
++	0x0A, 0xF3, 0xE7, 0xC3, 0xC8,
++	0x03, 0x6A, 0xE2, 0x62, 0x20,
++	0x01, 0x8C, 0xE7, 0x2A, 0xC3,
++	0x02, 0xEC, 0x05, 0x08, 0x62,
++	0x0C, 0x4D, 0x28, 0x49, 0xAD,
++	0x08, 0x0C, 0x65, 0x1C, 0xEE,
++	0x08, 0x63, 0x6C, 0xB3, 0x87,
++	0x05, 0x04, 0xB6, 0xE0, 0x16,
++	0x0E, 0xAA, 0x05, 0x37, 0x89,
++	0x08, 0x1C, 0xE9, 0x3E, 0x43,
++	0x02, 0x19, 0xC0, 0xF6, 0x89,
++	0x04, 0xF4, 0xC7, 0x83, 0xCF,
++	0x0E, 0xB2, 0xE9, 0x42, 0x11,
++	0x0E, 0x4F, 0xEA, 0x9D, 0xC6,
++	0x05, 0xC4, 0xC4, 0x40, 0x21,
++	0x08, 0x4E, 0x55, 0x82, 0x07,
++	0x06, 0x8E, 0x24, 0x27, 0xFC,
++	0x0E, 0xDF, 0x92, 0xD3, 0x01,
++	0x00, 0xC2, 0xB4, 0xB2, 0x62,
++	0x0F, 0x5B, 0x67, 0x83, 0xFA,
++	0x01, 0x6D, 0xD1, 0x6D, 0x7E,
++	0x0C, 0x8A, 0xF7, 0x99, 0x70,
++	0x01, 0x53, 0xDA, 0xEA, 0x64,
++	0x03, 0x85, 0xED, 0x9A, 0x59,
++	0x01, 0xFF, 0x07, 0xBD, 0x5D,
++	0x0F, 0x96, 0x5E, 0x2E, 0x4A,
++	0x05, 0x94, 0x13, 0x8D, 0xAB,
++	0x09, 0x88, 0x80, 0x76, 0x6D,
++	0x0C, 0xAB, 0x09, 0xD5, 0xEA,
++	0x06, 0x2B, 0x4B, 0xE9, 0xA5,
++	0x0D, 0x26, 0xA2, 0x20, 0xB1,
++	0x07, 0x69, 0xBF, 0x75, 0x0E,
++	0x01, 0xCE, 0xD3, 0x44, 0x9A,
++	0x08, 0xB1, 0x96, 0xCA, 0x28,
++	0x07, 0xAE, 0xE2, 0xC0, 0xF3,
++	0x07, 0xF4, 0x14, 0x48, 0xE7,
++	0x0A, 0xDA, 0xF4, 0x3B, 0xC3,
++	0x0F, 0x0E, 0xBC, 0x5C, 0xC8,
++	0x0C, 0xEA, 0xE7, 0x93, 0x36,
++	0x02, 0x45, 0x1B, 0x5B, 0x13,
++	0x01, 0x00, 0x84, 0x47, 0xBB,
++	0x0C, 0x1F, 0x82, 0xF2, 0x38,
++	0x0D, 0x1B, 0x71, 0xCF, 0xBD,
++	0x0D, 0x4C, 0xC0, 0x60, 0x1A,
++	0x02, 0xFE, 0x8B, 0x10, 0x60,
++	0x06, 0x3E, 0x68, 0x35, 0xB7,
++	0x08, 0x35, 0x55, 0x50, 0x29,
++	0x00, 0xDC, 0xF0, 0xE7, 0x49,
++	0x0B, 0xA8, 0x92, 0xE0, 0x0A,
++	0x0E, 0x69, 0xF7, 0x9B, 0xFC,
++	0x08, 0xF8, 0xB9, 0xB0, 0xCA,
++	0x00, 0x8F, 0x3E, 0x6C, 0xD4,
++	0x09, 0x36, 0x6E, 0x26, 0xA2,
++	0x00, 0x08, 0x02, 0x76, 0xAF,
++	0x06, 0x26, 0x04, 0x50, 0xA4,
++	0x0F, 0x64, 0x96, 0xFA, 0x10,
++	0x01, 0x82, 0xC6, 0x51, 0x65,
++	0x07, 0x12, 0x59, 0x4B, 0x3E,
++	0x09, 0xD0, 0x6B, 0x68, 0x41,
++	0x0F, 0xEA, 0xA0, 0x54, 0x7C,
++	0x0B, 0x00, 0x6E, 0x9D, 0x9E,
++	0x01, 0xA0, 0x3D, 0xAF, 0x6C,
++	0x08, 0xEF, 0x8E, 0x78, 0x7D,
++	0x08, 0x79, 0x22, 0x99, 0x2D,
++	0x04, 0x78, 0x84, 0xA9, 0x18,
++	0x06, 0xDF, 0xAE, 0xC8, 0x86,
++	0x01, 0x84, 0xE7, 0x58, 0x32,
++	0x05, 0xC0, 0x20, 0x57, 0xBE,
++	0x09, 0x2D, 0xF9, 0x35, 0x33,
++	0x08, 0x8E, 0xE3, 0x49, 0x7A,
++	0x06, 0x71, 0xFF, 0x78, 0xEB,
++	0x00, 0xD6, 0xD9, 0x82, 0xD7,
++	0x05, 0x40, 0xA9, 0x79, 0x77,
++	0x01, 0x9D, 0x21, 0x28, 0x22,
++	0x0A, 0x38, 0x98, 0x5B, 0x21,
++	0x0F, 0x1E, 0x35, 0xF7, 0x27,
++	0x06, 0x41, 0x2C, 0x5A, 0x07,
++	0x01, 0x33, 0x12, 0x38, 0x1A,
++	0x08, 0x7A, 0xA8, 0x04, 0xD2,
++	0x09, 0xCA, 0xB1, 0x58, 0x11,
++	0x01, 0x42, 0xB6, 0xF9, 0xD8,
++	0x01, 0xF6, 0x18, 0x66, 0x01,
++	0x09, 0x46, 0x97, 0xF8, 0x63,
++	0x05, 0xAD, 0xC1, 0xF7, 0x41,
++	0x04, 0x3B, 0xE5, 0xAF, 0x2A,
++	0x08, 0x48, 0x92, 0xE2, 0x47,
++	0x00, 0x4B, 0x2D, 0xC4, 0x8E,
++	0x00, 0xBD, 0xB3, 0x4F, 0xFE,
++	0x07, 0xE2, 0xF7, 0xD9, 0xCC,
++	0x08, 0x57, 0xDA, 0x79, 0xE3,
++	0x0A, 0xAC, 0xF1, 0xB8, 0xB1,
++	0x01, 0x10, 0x08, 0x4A, 0x97,
++	0x09, 0x61, 0xB6, 0xB7, 0x21,
++	0x0C, 0x69, 0x3B, 0x2A, 0xB7,
++	0x0D, 0xD5, 0x0C, 0x06, 0x72,
++	0x03, 0xAE, 0xD8, 0xB1, 0xD6,
++	0x09, 0xE3, 0xEC, 0xAD, 0x12,
++	0x06, 0x0B, 0x5E, 0xD1, 0x9F,
++	0x0D, 0x65, 0x7D, 0x8E, 0xF4,
++	0x06, 0x38, 0xA8, 0x0C, 0x61,
++	0x07, 0x66, 0x87, 0xF8, 0x71,
++	0x08, 0x6F, 0x7E, 0x9B, 0x84,
++	0x0D, 0x6C, 0x8E, 0xE6, 0xE5,
++	0x01, 0x63, 0x8E, 0xEC, 0xA2,
++	0x0A, 0x14, 0xF7, 0x27, 0x6A,
++	0x0A, 0xFA, 0x9A, 0x43, 0x4A,
++	0x09, 0xF2, 0x34, 0x6F, 0xD9,
++	0x09, 0x98, 0x08, 0x65, 0x1A,
++	0x05, 0xD5, 0x1E, 0xAC, 0xB2,
++	0x0E, 0x5D, 0xE6, 0xB0, 0xAC,
++	0x0C, 0xBA, 0xD7, 0x05, 0x3B,
++	0x0B, 0xB8, 0x18, 0xE9, 0x3D,
++	0x05, 0x12, 0x15, 0xC2, 0xF6,
++	0x0F, 0x0E, 0xF0, 0xF9, 0xC3,
++	0x07, 0x97, 0x92, 0x09, 0xCE,
++	0x01, 0x66, 0x6D, 0x8E, 0x0C,
++	0x0F, 0x55, 0x24, 0xC4, 0x40,
++	0x09, 0x1A, 0x4E, 0x59, 0x86,
++	0x04, 0xDC, 0x88, 0x33, 0xE5,
++	0x06, 0x96, 0xAB, 0x93, 0x43,
++	0x00, 0x18, 0xCA, 0x38, 0x7B,
++	0x02, 0xC7, 0x5B, 0x6A, 0x8A,
++	0x0A, 0x0D, 0x6B, 0xD6, 0xE7,
++	0x0D, 0x54, 0x0E, 0x57, 0x66,
++	0x00, 0x39, 0xD2, 0x7A, 0x19,
++	0x0C, 0x3B, 0x05, 0xE0, 0x5A,
++	0x03, 0x60, 0xCF, 0x07, 0xBE,
++	0x0E, 0x64, 0x10, 0xBD, 0xAA,
++	0x0F, 0x9B, 0x15, 0x3F, 0xDA,
++	0x02, 0x20, 0x68, 0xB0, 0xC8,
++	0x04, 0x9C, 0xAB, 0x0D, 0x69,
++	0x0D, 0x14, 0x2B, 0x4F, 0x59,
++	0x05, 0x3F, 0x86, 0xA8, 0x29,
++	0x00, 0x94, 0xA8, 0xFF, 0x45,
++	0x06, 0xB0, 0xCE, 0x93, 0x74,
++	0x0A, 0xDB, 0xB1, 0xCC, 0xB8,
++	0x08, 0x14, 0xAD, 0x08, 0x62,
++	0x09, 0xA0, 0x76, 0x54, 0x58,
++	0x07, 0x0B, 0xD9, 0x3A, 0xBF,
++	0x0B, 0x7C, 0x6E, 0xF0, 0x9C,
++	0x08, 0x25, 0x39, 0x41, 0x55,
++	0x0C, 0x2E, 0xEF, 0x1B, 0x5F,
++	0x03, 0x11, 0x00, 0x89, 0x24,
++	0x01, 0x46, 0x9B, 0xDE, 0xB2,
++	0x06, 0xD7, 0xAF, 0xB2, 0x4B,
++	0x06, 0xCD, 0xEC, 0xD0, 0xE3,
++	0x03, 0x51, 0x1C, 0x0B, 0x11,
++	0x0D, 0x1E, 0x9E, 0xC8, 0xB5,
++	0x0C, 0xE3, 0x57, 0x73, 0xE1,
++	0x09, 0x5E, 0x4D, 0xC2, 0x2A,
++	0x05, 0xD1, 0xA8, 0x90, 0xD7,
++	0x07, 0xB6, 0x60, 0x75, 0x4A,
++	0x0C, 0x1E, 0xF0, 0xB9, 0x90,
++	0x08, 0x76, 0x87, 0x32, 0x2C,
++	0x06, 0x8E, 0x3E, 0xA2, 0x66,
++	0x00, 0xA9, 0xB8, 0xC4, 0xF2,
++	0x0F, 0x1F, 0x66, 0xE2, 0xD0,
++	0x0C, 0x97, 0x84, 0x96, 0xFC,
++	0x0A, 0x31, 0x20, 0xD0, 0x13,
++	0x05, 0xFD, 0x16, 0x2C, 0x49,
++	0x0C, 0x7D, 0xD0, 0x7D, 0xAC,
++	0x01, 0x6B, 0xEA, 0x86, 0x10,
++	0x04, 0xB9, 0x81, 0xC2, 0x93,
++	0x0D, 0x55, 0xAD, 0x1C, 0x3F,
++	0x07, 0xD0, 0xEF, 0x0F, 0xF8,
++	0x01, 0xEE, 0x8C, 0xDC, 0xA5,
++	0x01, 0x1A, 0x1C, 0xD8, 0xAD,
++	0x06, 0xAD, 0x9C, 0x45, 0x75,
++	0x02, 0x11, 0x84, 0xF9, 0x1A,
++	0x03, 0x49, 0x28, 0xA1, 0x5E,
++	0x04, 0x09, 0x6D, 0xF0, 0x01,
++	0x03, 0x01, 0x8C, 0xBF, 0x09,
++	0x06, 0x2C, 0x12, 0x96, 0x71,
++	0x03, 0xED, 0x54, 0xD1, 0x82,
++	0x07, 0xD5, 0x40, 0x29, 0x33,
++	0x07, 0x03, 0x9D, 0xAB, 0xE4,
++	0x02, 0x43, 0x3A, 0x5A, 0xD3,
++	0x0D, 0xDC, 0x7F, 0xF0, 0x7F,
++	0x08, 0x26, 0x81, 0x20, 0xE6,
++	0x0C, 0xF9, 0xB1, 0x4E, 0x7A,
++	0x06, 0xBA, 0x78, 0x88, 0x00,
++	0x09, 0xC9, 0x8A, 0xB9, 0xE1,
++	0x0B, 0x91, 0x42, 0xA8, 0xBF,
++	0x0E, 0x5B, 0x98, 0xEA, 0x6F,
++	0x0B, 0x54, 0xC4, 0x9B, 0xF4,
++	0x08, 0xEB, 0x2C, 0x7D, 0xBD,
++	0x01, 0xAD, 0xBB, 0x89, 0xE5,
++	0x0A, 0x81, 0x48, 0xF6, 0xE4,
++	0x0C, 0x3A, 0x4F, 0x5D, 0x44,
++	0x06, 0x70, 0xBD, 0xBD, 0x0A,
++	0x0C, 0x3F, 0xE1, 0x77, 0xC5,
++	0x0C, 0x82, 0x52, 0xB4, 0x79,
++	0x03, 0x62, 0xA4, 0x71, 0xBF,
++	0x01, 0x31, 0x10, 0x06, 0x0F,
++	0x03, 0x95, 0x60, 0x3D, 0x37,
++	0x02, 0x85, 0x68, 0x7B, 0x24,
++	0x07, 0xE4, 0xD5, 0x4C, 0x06,
++	0x02, 0x8D, 0x2E, 0xE8, 0xB1,
++	0x06, 0x59, 0xE1, 0xEE, 0x89,
++	0x0B, 0x76, 0x0B, 0x52, 0x11,
++	0x08, 0x75, 0xFE, 0x55, 0x5C,
++	0x04, 0x9E, 0xBA, 0x99, 0x0E,
++	0x0A, 0x7B, 0x66, 0x87, 0x78,
++	0x07, 0x41, 0x4F, 0x8B, 0x99,
++	0x0D, 0x27, 0x88, 0xF3, 0xE6,
++	0x0B, 0xC9, 0xD3, 0x6A, 0xE2,
++	0x02, 0x20, 0x10, 0x92, 0x3A,
++	0x03, 0x42, 0x9A, 0x42, 0x54,
++	0x0C, 0xD3, 0xF6, 0x49, 0xEF,
++	0x0F, 0xA9, 0x98, 0x0C, 0xE5,
++	0x0A, 0x3F, 0x51, 0x63, 0xAC,
++	0x03, 0xA6, 0x5D, 0x06, 0xB6,
++	0x05, 0x14, 0xDA, 0xAA, 0xC5,
++	0x01, 0xCF, 0x08, 0x1C, 0xEB,
++	0x05, 0xD4, 0xB2, 0x1F, 0xC2,
++	0x0E, 0xC5, 0x8E, 0xF6, 0xFF,
++	0x0B, 0xD6, 0x97, 0x32, 0x89,
++	0x07, 0xDB, 0x87, 0xC0, 0x4A,
++	0x01, 0xC6, 0xD5, 0xC4, 0xC4,
++	0x00, 0x21, 0x18, 0x68, 0x57,
++	0x0C, 0xF0, 0x77, 0x8A, 0x11,
++	0x0C, 0xEC, 0x92, 0xDF, 0x93,
++	0x0A, 0xB0, 0xFA, 0xC6, 0x34,
++	0x07, 0x22, 0x67, 0x49, 0xE7,
++	0x01, 0x3B, 0x3D, 0x6D, 0xD8,
++	0x04, 0xFC, 0xB4, 0x06, 0x57,
++	0x0F, 0x72, 0x19, 0xD2, 0xFA,
++	0x00, 0x20, 0x84, 0x85, 0xEF,
++	0x02, 0x9D, 0x41, 0xFF, 0x87,
++	0x06, 0x2C, 0x04, 0x0E, 0x1D,
++	0x09, 0xCB, 0x2F, 0x95, 0x27,
++	0x0D, 0xAB, 0x8B, 0x88, 0x80,
++	0x09, 0x30, 0x9C, 0xA5, 0x10,
++	0x0B, 0xB9, 0x14, 0x27, 0x0F,
++	0x00, 0xA5, 0x5B, 0x2A, 0xE6,
++	0x00, 0x11, 0x14, 0x69, 0x7F,
++	0x05, 0xAC, 0xB2, 0xCF, 0x1F,
++	0x0E, 0x1E, 0x67, 0xB0, 0x58,
++	0x03, 0x29, 0x94, 0xAD, 0xAE,
++	0x0B, 0x73, 0xA4, 0xF9, 0xC5,
++	0x01, 0x65, 0x2F, 0xDB, 0xC5,
++	0x01, 0xC7, 0x40, 0x0F, 0x74,
++	0x04, 0x48, 0x85, 0x37, 0x07,
++	0x06, 0x34, 0x0E, 0x47, 0xEA,
++	0x0D, 0x17, 0xAE, 0x80, 0x86,
++	0x09, 0xB9, 0xF6, 0x17, 0x93,
++	0x0A, 0xAA, 0x72, 0x93, 0xF2,
++	0x02, 0x7E, 0x89, 0x4C, 0x31,
++	0x01, 0x28, 0xD6, 0xFA, 0xCB,
++	0x0D, 0x65, 0x9E, 0x3E, 0x31,
++	0x04, 0x9E, 0xA0, 0xB5, 0xF5,
++	0x0A, 0x2D, 0x9D, 0x5D, 0xC8,
++	0x0E, 0x49, 0x2B, 0xA8, 0x90,
++	0x05, 0x17, 0xB6, 0x68, 0x77,
++	0x0D, 0x3C, 0x1F, 0x71, 0x32,
++	0x00, 0x4A, 0x76, 0xAF, 0xBD,
++	0x0C, 0x54, 0x8E, 0x16, 0xEC,
++	0x06, 0x22, 0x01, 0x08, 0xC2,
++	0x02, 0xAC, 0x37, 0xA6, 0xE4,
++	0x0B, 0xAD, 0x3F, 0x64, 0x96,
++	0x0C, 0x9A, 0x9B, 0x80, 0xFE,
++	0x09, 0xA6, 0x7D, 0x18, 0xBA,
++	0x0B, 0x3C, 0x79, 0xD0, 0x6B,
++	0x0E, 0xC1, 0x6F, 0xEA, 0xA0,
++	0x00, 0xBC, 0xBB, 0x87, 0xCE,
++	0x03, 0xD7, 0xD1, 0x21, 0x9C,
++	0x0F, 0x6D, 0x50, 0xEF, 0x0F,
++	0x08, 0x3D, 0xF1, 0x73, 0x20,
++	0x06, 0xED, 0x1E, 0x70, 0x58,
++	0x09, 0x1C, 0x6D, 0x5A, 0x46,
++	0x05, 0xE0, 0x13, 0x84, 0xE5,
++	0x02, 0x6B, 0x80, 0xC8, 0xB1,
++	0x01, 0x7E, 0xC9, 0x2D, 0xF9,
++	0x09, 0x13, 0x01, 0x8C, 0x9B,
++	0x00, 0xFA, 0x2C, 0x75, 0x96,
++	0x01, 0x7B, 0x40, 0xDA, 0x9D,
++	0x08, 0xD2, 0xD7, 0xC0, 0x85,
++	0x05, 0x77, 0x03, 0x99, 0x11,
++	0x0E, 0xA2, 0x41, 0x34, 0x83,
++	0x00, 0x21, 0x3C, 0x15, 0xF0,
++	0x02, 0xE0, 0x82, 0x41, 0xE9,
++	0x03, 0x3D, 0x39, 0xBC, 0x12,
++	0x0A, 0xDA, 0xB8, 0x9C, 0xC8,
++	0x04, 0x23, 0x09, 0xCE, 0x2D,
++	0x0E, 0x7B, 0x31, 0x66, 0x36,
++	0x0D, 0x92, 0x5B, 0xF2, 0x6A,
++	0x0E, 0x80, 0xB9, 0x42, 0xD7,
++	0x06, 0x58, 0xEB, 0x28, 0xF1,
++	0x07, 0x41, 0xAD, 0xB6, 0x18,
++	0x0E, 0xAA, 0x4D, 0x4A, 0xF2,
++	0x0E, 0x07, 0x36, 0x4F, 0x5D,
++	0x04, 0x86, 0x70, 0xBD, 0xB3,
++	0x01, 0xBC, 0x3F, 0xE4, 0x77,
++	0x05, 0xCC, 0x82, 0x5F, 0x69,
++	0x08, 0xF3, 0xA6, 0xA4, 0x71,
++	0x05, 0x71, 0x35, 0x10, 0x08,
++	0x0F, 0x10, 0x55, 0x65, 0x3D,
++	0x0E, 0xA0, 0xC7, 0x6D, 0xBB,
++	0x0E, 0xB3, 0x3E, 0x54, 0xDC,
++	0x0F, 0x32, 0x4D, 0x2B, 0xA8,
++	0x08, 0x54, 0x19, 0xE1, 0x6E,
++	0x09, 0x5F, 0xAA, 0x8B, 0x4F,
++	0x0C, 0x02, 0x55, 0xE7, 0x5C,
++	0x0E, 0x74, 0x9E, 0xBA, 0x89,
++	0x0E, 0xE1, 0x7F, 0x62, 0x07,
++	0x08, 0x7F, 0xC1, 0xEF, 0x8B,
++	0x08, 0x64, 0x67, 0x68, 0xF3,
++	0x06, 0xC5, 0x48, 0xE3, 0x6A,
++	0x02, 0x62, 0x22, 0x14, 0x06,
++	0x0B, 0x2A, 0xC0, 0xBA, 0x5F,
++	0x05, 0x0A, 0xD3, 0xF6, 0xBB,
++	0x07, 0x49, 0x09, 0x94, 0x4C,
++	0x0D, 0x9B, 0xFF, 0xDC, 0x63,
++	0x0C, 0xB3, 0xC7, 0xDD, 0x06,
++	0x06, 0xEC, 0x16, 0xBA, 0xF7,
++	0x05, 0x2B, 0xCB, 0xB8, 0x1C,
++	0x0B, 0x3D, 0x79, 0x16, 0x99,
++	0x0A, 0x74, 0xED, 0x02, 0xF0,
++	0x0E, 0x63, 0x3F, 0x17, 0x32,
++	0x00, 0xCC, 0xB1, 0xEB, 0x4D,
++	0x00, 0x95, 0x24, 0x55, 0xD4,
++	0x04, 0x40, 0x21, 0x14, 0x93,
++	0x0D, 0x07, 0x56, 0xD0, 0x8A,
++	0x0D, 0x25, 0xCC, 0x9F, 0xDF,
++	0x09, 0x57, 0xD7, 0x98, 0xDA,
++	0x0C, 0x3F, 0x02, 0xC7, 0x59,
++	0x0E, 0x0D, 0x9A, 0x07, 0x6D,
++	0x02, 0x29, 0x8E, 0x54, 0x1A,
++	0x0E, 0x15, 0x50, 0x39, 0x12,
++	0x00, 0xEE, 0xCE, 0x33, 0x95,
++	0x05, 0x1A, 0xBD, 0xE1, 0x3F,
++	0x07, 0xBE, 0x2A, 0xE4, 0x12,
++	0x0D, 0xA3, 0xCB, 0x9B, 0x15,
++	0x03, 0x8D, 0xAF, 0x89, 0x88,
++	0x00, 0x42, 0x34, 0x9C, 0xAB,
++	0x0D, 0xE9, 0xBD, 0x14, 0x2B,
++	0x06, 0x59, 0xC7, 0xBD, 0xA6,
++	0x0F, 0x62, 0x51, 0x94, 0xA9,
++	0x05, 0x41, 0x7E, 0x32, 0xDF,
++	0x06, 0x75, 0xF8, 0xD6, 0x30,
++	0x0A, 0xFA, 0xAB, 0x94, 0xAF,
++	0x0E, 0xE0, 0x70, 0x20, 0x7F,
++	0x04, 0x48, 0x65, 0x0B, 0xD1,
++	0x0E, 0x3F, 0x3E, 0x7E, 0x0E,
++	0x0C, 0x5C, 0xCA, 0x21, 0x53,
++	0x07, 0x9F, 0x35, 0xAE, 0x2E,
++	0x0B, 0x57, 0x10, 0x91, 0x0A,
++	0x04, 0x61, 0x3B, 0x56, 0x11,
++	0x09, 0x76, 0xD5, 0xD6, 0x9E,
++	0x02, 0x4B, 0x7A, 0x4D, 0x4C,
++	0x00, 0x63, 0x2C, 0xD2, 0xFE,
++	0x02, 0x9D, 0x83, 0x9C, 0xBE,
++	0x08, 0x35, 0xB3, 0x60, 0xB5,
++	0x05, 0x50, 0x29, 0x5E, 0x5D,
++	0x09, 0xE5, 0x29, 0xEB, 0x68,
++	0x0A, 0xCA, 0xEF, 0x36, 0x78,
++	0x0E, 0x86, 0x1E, 0x13, 0x78,
++	0x09, 0x90, 0x49, 0xF6, 0x85,
++	0x0E, 0x6C, 0x56, 0x8A, 0xBC,
++	0x04, 0x22, 0xDF, 0x81, 0x09,
++	0x0B, 0xF2, 0x4E, 0x3D, 0xA6,
++	0x0D, 0xD1, 0x4D, 0x33, 0x64,
++	0x06, 0xFC, 0x99, 0x19, 0x8A,
++	0x06, 0x51, 0xA7, 0xFD, 0x1C,
++	0x03, 0xC9, 0x5C, 0x71, 0x90,
++	0x01, 0x6A, 0x3D, 0xEB, 0xE8,
++	0x09, 0xD2, 0x5C, 0xB7, 0xC1,
++	0x0E, 0x93, 0xD7, 0x51, 0x21,
++	0x0C, 0x2F, 0x6C, 0xD4, 0x07,
++	0x0F, 0xF8, 0x3D, 0xF5, 0x9A,
++	0x00, 0x94, 0xEF, 0x1E, 0x7C,
++	0x08, 0xA9, 0x1C, 0xED, 0x5C,
++	0x05, 0xC4, 0xE2, 0x31, 0x0E,
++	0x05, 0x58, 0x6F, 0x4D, 0xC8,
++	0x01, 0x5A, 0x7E, 0xCD, 0xF0,
++	0x09, 0x35, 0x33, 0x01, 0x8C,
++	0x01, 0x4B, 0xFA, 0x2A, 0x75,
++	0x06, 0x78, 0xF9, 0xA0, 0xD6,
++	0x0D, 0x82, 0x57, 0xD5, 0x40,
++	0x0E, 0x79, 0x77, 0x03, 0x9D,
++	0x07, 0xAE, 0xA0, 0x4E, 0x65,
++	0x0E, 0xD9, 0xA1, 0x5E, 0x15,
++	0x00, 0x7B, 0xE2, 0x66, 0x4B,
++	0x09, 0xDA, 0x3C, 0x79, 0xBB,
++	0x02, 0x38, 0xDA, 0x38, 0x92,
++	0x08, 0x04, 0x21, 0x04, 0x80,
++	0x00, 0xDE, 0x9B, 0xAC, 0x00,
++	0x04, 0xFD, 0x92, 0x66, 0xB0,
++	0x0A, 0x66, 0x03, 0x24, 0x04,
++	0x07, 0xF4, 0x58, 0xD6, 0x6E,
++	0x01, 0xF7, 0x41, 0x90, 0xF9,
++	0x05, 0xAF, 0xAA, 0xBC, 0x08,
++	0x02, 0xEE, 0x07, 0x07, 0x0D,
++	0x0D, 0x44, 0x86, 0x4D, 0xFF,
++	0x03, 0x43, 0xBC, 0x02, 0xA2,
++	0x07, 0xC5, 0xCC, 0xBF, 0x11,
++	0x04, 0x79, 0xF3, 0x5F, 0xE6,
++	0x01, 0xB5, 0x71, 0x0C, 0x52,
++	0x08, 0x46, 0x13, 0xA8, 0x23,
++	0x0D, 0x37, 0x22, 0x89, 0xB4,
++	0x0B, 0x24, 0xB7, 0xE4, 0xD4,
++	0x0C, 0x06, 0x32, 0x8D, 0xC7,
++	0x03, 0xB1, 0xD6, 0x59, 0x0A,
++	0x02, 0x83, 0x5F, 0x36, 0x08,
++	0x06, 0xD5, 0xE2, 0x9B, 0xF8,
++	0x05, 0x8F, 0x94, 0x9E, 0xFA,
++	0x01, 0x8C, 0x41, 0x75, 0x2E,
++	0x0F, 0xF1, 0xDF, 0xC1, 0x2F,
++	0x02, 0x99, 0xC4, 0xA7, 0x62,
++	0x09, 0x06, 0xC4, 0xC2, 0xC0,
++	0x0B, 0xE3, 0xA6, 0xAE, 0xD5,
++	0x0D, 0x26, 0xEE, 0x65, 0x70,
++	0x0F, 0x44, 0xCA, 0xC7, 0xBE,
++	0x08, 0x6E, 0x09, 0x3D, 0x60,
++	0x0D, 0x64, 0xDA, 0x4F, 0xD1,
++	0x0B, 0xAC, 0x33, 0xE5, 0x5D,
++	0x06, 0xB6, 0xEC, 0x18, 0xA3,
++	0x01, 0x80, 0x31, 0xC5, 0x31,
++	0x07, 0x6C, 0x1D, 0xFB, 0xD6,
++	0x01, 0x42, 0x56, 0xCB, 0x0E,
++	0x00, 0xFF, 0x83, 0xF1, 0xD2,
++	0x0A, 0x09, 0xCE, 0xF7, 0x67,
++	0x0D, 0x8A, 0x91, 0xC8, 0xC8,
++	0x0F, 0x41, 0x5A, 0x2F, 0x91,
++	0x05, 0xD0, 0xA6, 0x74, 0xDC,
++	0x03, 0x15, 0x67, 0xEA, 0x92,
++	0x04, 0x93, 0x53, 0x30, 0x18,
++	0x0A, 0x34, 0xBD, 0xA2, 0xC7,
++	0x00, 0xC7, 0x6B, 0x3C, 0x0D,
++	0x0D, 0xD8, 0x29, 0xFD, 0x54,
++	0x0A, 0x57, 0x93, 0xF2, 0xBA,
++	0x02, 0x32, 0x6E, 0x24, 0x33,
++	0x05, 0xA4, 0x1E, 0x1F, 0x62,
++	0x0D, 0x4E, 0x3D, 0xA8, 0xA4,
++	0x02, 0xD4, 0x20, 0x4F, 0xD1,
++	0x05, 0x6A, 0x0E, 0x2D, 0x43,
++	0x08, 0x80, 0x43, 0xB0, 0xD6,
++	0x0B, 0x0D, 0xE9, 0xB9, 0x14,
++	0x03, 0x2F, 0x5B, 0x23, 0xB5,
++	0x0D, 0xA6, 0x60, 0x31, 0x94,
++	0x00, 0xFF, 0xA5, 0x8E, 0xB2,
++	0x05, 0xDF, 0x70, 0x10, 0x98,
++	0x03, 0xDB, 0x1E, 0x88, 0x94,
++	0x0C, 0xAF, 0x00, 0x45, 0xA4,
++	0x04, 0x55, 0xA8, 0x61, 0x09,
++	0x0B, 0x35, 0xDB, 0xC3, 0xFE,
++	0x04, 0x7C, 0x5C, 0xC8, 0x25,
++	0x02, 0x47, 0x5F, 0x38, 0x62,
++	0x0E, 0x9B, 0xB7, 0x1D, 0xD1,
++	0x0A, 0x81, 0x05, 0x39, 0x76,
++	0x07, 0xD3, 0x62, 0x28, 0x55,
++	0x06, 0xB2, 0x8B, 0x70, 0x50,
++	0x05, 0xC1, 0xA7, 0x28, 0x92,
++	0x0C, 0x8B, 0x1D, 0x63, 0x9E,
++	0x0C, 0xE8, 0x31, 0xB1, 0x20,
++	0x07, 0xF5, 0xD4, 0xAF, 0x1E,
++	0x0C, 0xC2, 0xE3, 0xCD, 0x75,
++	0x09, 0x11, 0x4A, 0x97, 0xB6,
++	0x08, 0x6F, 0x00, 0x7E, 0x9D,
++	0x08, 0xA0, 0x14, 0x4A, 0x76,
++	0x0D, 0x77, 0xE8, 0xD2, 0x04,
++	0x04, 0xE7, 0xA2, 0xA2, 0x41,
++	0x08, 0x5B, 0xF6, 0x2A, 0xB4,
++	0x06, 0xFC, 0xD7, 0x2B, 0xFC,
++	0x04, 0x8F, 0x78, 0x9A, 0x99,
++	0x02, 0x8F, 0xD0, 0xA3, 0xB7,
++	0x06, 0x73, 0x4F, 0xBC, 0x7D,
++	0x01, 0x72, 0xEA, 0x41, 0x6B,
++	0x0A, 0xA0, 0x56, 0x3C, 0xBB,
++	0x01, 0x86, 0x14, 0x55, 0xD2,
++	0x01, 0xD5, 0xAB, 0x6C, 0xD0,
++	0x0D, 0x46, 0x7B, 0x3B, 0x3B,
++	0x03, 0x69, 0x11, 0x6B, 0x94,
++	0x0E, 0x11, 0x2D, 0x9C, 0x2D,
++	0x0D, 0x07, 0x80, 0x82, 0x11,
++	0x04, 0xED, 0xDF, 0xEF, 0x4D,
++	0x08, 0xE8, 0xDE, 0x7E, 0xC9,
++	0x0F, 0xB0, 0xB4, 0x35, 0x4B,
++	0x0C, 0xEA, 0xCB, 0xFA, 0x2C,
++	0x04, 0x1F, 0xF8, 0xFB, 0xA0,
++	0x0E, 0xDF, 0xC2, 0xD5, 0x55,
++	0x0A, 0xA0, 0x4E, 0x77, 0x07,
++	0x05, 0x27, 0x2E, 0x20, 0xC3,
++	0x01, 0x6F, 0x59, 0xA7, 0xDE,
++	0x05, 0xF5, 0x43, 0x62, 0xE7,
++	0x03, 0x29, 0xDA, 0x3A, 0xF9,
++	0x09, 0x52, 0xB8, 0x58, 0x38,
++	0x09, 0xB9, 0x84, 0x23, 0x09,
++	0x0B, 0x33, 0x3E, 0x9D, 0x52,
++	0x0A, 0xB6, 0x9D, 0x90, 0xDB,
++	0x08, 0x6F, 0x5D, 0x83, 0x1D,
++	0x0E, 0x97, 0x73, 0xDA, 0x6B,
++	0x05, 0x40, 0x77, 0x47, 0xAD,
++	0x01, 0x00, 0x92, 0xAA, 0x80,
++	0x08, 0xF2, 0xEA, 0x01, 0x3A,
++	0x07, 0x5D, 0xC7, 0x04, 0xF0,
++	0x0C, 0x02, 0xC3, 0xBC, 0x3F,
++	0x00, 0xF7, 0xC1, 0x4C, 0xC8,
++	0x01, 0xB4, 0x7D, 0x75, 0xE8,
++	0x06, 0x71, 0xB5, 0x77, 0xFB,
++	0x01, 0x78, 0x86, 0x13, 0x95,
++	0x00, 0x4D, 0xD7, 0x22, 0x85,
++	0x0F, 0xFB, 0x24, 0xB3, 0x64,
++	0x08, 0xDC, 0x06, 0x32, 0xBF,
++	0x0F, 0xE8, 0x31, 0xD2, 0x86,
++	0x0F, 0xCA, 0x83, 0x5B, 0x6F,
++	0x09, 0x5F, 0x51, 0x06, 0x95,
++	0x05, 0xDC, 0x0E, 0x74, 0x9E,
++	0x0A, 0x0B, 0x08, 0x61, 0x7B,
++	0x0E, 0x02, 0x54, 0x7F, 0x01,
++	0x07, 0x1F, 0x3D, 0x04, 0x67,
++	0x00, 0xF6, 0xE2, 0xC5, 0x88,
++	0x0B, 0x4E, 0x62, 0x62, 0xE0,
++	0x08, 0x1C, 0x87, 0x2E, 0x83,
++	0x03, 0x6E, 0x81, 0x06, 0x53,
++	0x0E, 0x40, 0xAB, 0x4D, 0x9A,
++	0x01, 0x85, 0xA1, 0x1E, 0x2B,
++	0x01, 0x63, 0x28, 0x37, 0xDC,
++	0x0D, 0x3F, 0x3E, 0xE0, 0x8C,
++	0x0E, 0xE3, 0x8D, 0xAB, 0xCB,
++	0x08, 0x35, 0x6D, 0x3F, 0xC0,
++	0x02, 0x18, 0x45, 0x76, 0xCD,
++	0x0E, 0xF1, 0x7B, 0x83, 0xDF,
++	0x05, 0x7B, 0x8D, 0x4E, 0x9B,
++	0x07, 0xE4, 0x0E, 0x91, 0xC6,
++	0x07, 0xC5, 0x40, 0xCD, 0x61,
++	0x0A, 0x77, 0xD1, 0x8B, 0xB4,
++	0x0C, 0x0A, 0xBD, 0x27, 0xEC,
++	0x02, 0x66, 0x3B, 0x53, 0x30,
++	0x0A, 0x03, 0x9C, 0xB9, 0xA2,
++	0x07, 0xF0, 0xCF, 0x0D, 0x0F,
++	0x0D, 0x6D, 0x5C, 0x2D, 0x7D,
++	0x04, 0x8B, 0xF3, 0x97, 0x70,
++	0x09, 0x53, 0xDD, 0x6A, 0x24,
++	0x01, 0x4C, 0x48, 0x9C, 0x17,
++	0x03, 0x56, 0xA3, 0xB8, 0x2E,
++	0x04, 0x93, 0x39, 0x23, 0xCF,
++	0x0B, 0xAC, 0x87, 0x8D, 0xAB,
++	0x08, 0x88, 0x48, 0xC2, 0x30,
++	0x0D, 0x92, 0xC5, 0xE8, 0x08,
++	0x07, 0x62, 0x87, 0xDF, 0x65,
++	0x0E, 0x0F, 0x6E, 0xE2, 0x84,
++	0x04, 0xE9, 0xDB, 0x41, 0x55,
++	0x03, 0xCE, 0xDB, 0x78, 0x80,
++	0x0A, 0xB1, 0x9D, 0x7A, 0xA8,
++	0x07, 0xE6, 0xE9, 0xE0, 0x39,
++	0x05, 0xDC, 0x11, 0x4E, 0x2D,
++	0x08, 0xDA, 0xF0, 0xB6, 0x83,
++	0x0D, 0x36, 0xB8, 0x51, 0x88,
++	0x04, 0xBB, 0xAF, 0x1F, 0x36,
++	0x0B, 0xFE, 0xF3, 0x57, 0x13,
++	0x02, 0xC9, 0x6C, 0x67, 0xB9,
++	0x07, 0xB2, 0x3B, 0xF2, 0x28,
++	0x07, 0x9F, 0x76, 0x4B, 0x7E,
++	0x0C, 0xCD, 0x24, 0x63, 0x28,
++	0x03, 0x7F, 0x6C, 0x9D, 0x65,
++	0x0D, 0xF7, 0x01, 0x33, 0x3D,
++	0x03, 0x1C, 0x15, 0x56, 0xA9,
++	0x0F, 0xDC, 0x20, 0xE7, 0x49,
++	0x0A, 0x11, 0x70, 0xCE, 0x17,
++	0x06, 0x68, 0x77, 0x87, 0xFC,
++	0x0E, 0xF8, 0xB9, 0x90, 0x4A,
++	0x04, 0x8F, 0x3E, 0x6A, 0x94,
++	0x0E, 0x36, 0xA2, 0x2A, 0x7D,
++	0x00, 0x88, 0x22, 0x73, 0x1E,
++	0x07, 0xA6, 0xE8, 0x5C, 0x72,
++	0x0F, 0x64, 0x9A, 0xF0, 0xC5,
++	0x01, 0x81, 0x66, 0xD7, 0x6F,
++	0x05, 0x94, 0x1A, 0xCD, 0xFC,
++	0x0D, 0xD0, 0x67, 0x62, 0x1E,
++	0x0B, 0xEA, 0xAC, 0x5E, 0x23,
++	0x0B, 0x81, 0xC2, 0x9E, 0xC8,
++	0x01, 0x21, 0x90, 0x23, 0xF3,
++	0x00, 0xEF, 0x07, 0xF5, 0x22,
++	0x0A, 0x73, 0x20, 0x94, 0xED,
++	0x02, 0x7C, 0xDE, 0x69, 0x1F,
++	0x04, 0x5D, 0x8C, 0x44, 0x42,
++	0x01, 0x84, 0xE5, 0x58, 0x6F,
++	0x0D, 0xC8, 0xA1, 0x5E, 0xF6,
++	0x09, 0x2D, 0xF9, 0xB5, 0x39,
++	0x0A, 0x8C, 0xA3, 0x4B, 0xFA,
++	0x04, 0x75, 0x1E, 0x7E, 0xFB,
++	0x0A, 0xD3, 0xB4, 0x02, 0xC7,
++	0x0D, 0x40, 0x2D, 0x79, 0x77,
++	0x03, 0x9D, 0x2B, 0xAE, 0xA2,
++	0x08, 0x38, 0x5E, 0xD9, 0xA1,
++	0x02, 0x1F, 0x8B, 0x7B, 0xFC,
++	0x06, 0x41, 0x29, 0xD6, 0x7F,
++	0x09, 0xB1, 0x52, 0x3A, 0x59,
++	0x00, 0x18, 0x2C, 0x04, 0xE3,
++	0x00, 0xC8, 0xB0, 0xD2, 0x9B,
++	0x0B, 0x47, 0xDA, 0xFD, 0x9A,
++	0x07, 0xEE, 0x6A, 0x66, 0x14,
++	0x01, 0x6E, 0x17, 0xF2, 0x58,
++	0x03, 0xAD, 0x51, 0xF7, 0x81,
++	0x01, 0xAD, 0x05, 0xAF, 0xBD,
++	0x0D, 0x42, 0xF2, 0xEE, 0x36,
++	0x03, 0x4D, 0x59, 0x48, 0xC6,
++	0x0A, 0xB8, 0xC1, 0xC3, 0xAC,
++	0x07, 0x4A, 0xD7, 0xC9, 0xCC,
++	0x0A, 0x03, 0x34, 0x7F, 0xF3,
++	0x0B, 0xA6, 0x71, 0xB9, 0x31,
++	0x0B, 0x15, 0x78, 0x46, 0x17,
++	0x0F, 0x64, 0xCB, 0x37, 0x23,
++	0x09, 0x76, 0x04, 0xD8, 0x86,
++	0x0D, 0xD6, 0xCC, 0x0A, 0x72,
++	0x07, 0x2A, 0x9E, 0xB1, 0xD2,
++	0x01, 0x4A, 0x4E, 0x8F, 0x5B,
++	0x0E, 0x1B, 0xDF, 0x53, 0x02,
++	0x0C, 0xE7, 0xDC, 0x02, 0x34,
++	0x04, 0xBF, 0xFD, 0x0C, 0xE9,
++	0x0B, 0x66, 0x87, 0x7E, 0x75,
++	0x09, 0xEF, 0x0F, 0x99, 0xC4,
++	0x0D, 0xA8, 0xF2, 0x6C, 0x37,
++	0x0C, 0xE3, 0x6A, 0xE6, 0x62,
++	0x08, 0x10, 0x08, 0x27, 0xEA,
++	0x03, 0x7B, 0xEE, 0x41, 0x5D,
++	0x03, 0xF6, 0x49, 0x6B, 0x90,
++	0x0D, 0x98, 0x0C, 0x61, 0x1A,
++	0x07, 0xF9, 0xEB, 0xAC, 0x73,
++	0x07, 0xF4, 0x8A, 0xB6, 0xA6,
++	0x0D, 0xBE, 0xAA, 0x05, 0x5A,
++	0x0B, 0xB8, 0x1C, 0xE7, 0x39,
++	0x05, 0x12, 0x19, 0xDC, 0xB3,
++	0x05, 0x0E, 0x70, 0xD2, 0x43,
++	0x07, 0x15, 0x32, 0x05, 0x4E,
++	0x09, 0x62, 0x6D, 0x87, 0x51,
++	0x06, 0xD5, 0xC4, 0xC0, 0x7A,
++	0x01, 0x18, 0x4E, 0x51, 0xFD,
++	0x04, 0xDC, 0x8A, 0x05, 0xA5,
++	0x0C, 0x92, 0xDF, 0xB3, 0x51,
++	0x09, 0x90, 0x2A, 0x39, 0x7F,
++	0x0B, 0x0D, 0x39, 0x6B, 0x8F,
++	0x06, 0x13, 0x6D, 0xD8, 0x1C,
++	0x03, 0xD5, 0x3A, 0x57, 0x97,
++	0x00, 0x39, 0xD2, 0x64, 0x79,
++	0x04, 0x33, 0x85, 0xA3, 0x4E,
++	0x0B, 0xE1, 0xFF, 0x17, 0x3E,
++	0x08, 0x64, 0x12, 0xCD, 0x23,
++	0x09, 0x1B, 0xB5, 0x13, 0x0D,
++	0x0D, 0x08, 0x28, 0x80, 0xC2,
++	0x00, 0x9C, 0x29, 0x0D, 0xE0,
++	0x09, 0x15, 0xAB, 0x4F, 0xD9,
++	0x0C, 0xBD, 0x26, 0xA0, 0x20,
++	0x0B, 0x91, 0xE1, 0x7F, 0x4D,
++	0x06, 0xB2, 0x4F, 0x19, 0x34,
++	0x0A, 0xDB, 0xB0, 0x5A, 0xFA,
++	0x08, 0x14, 0xAF, 0x3A, 0xEB,
++	0x0A, 0xA4, 0x35, 0x95, 0x9E,
++	0x01, 0x0B, 0xDB, 0xA4, 0xB1,
++	0x05, 0xFE, 0x0F, 0xCC, 0xD6,
++	0x0E, 0xE5, 0x9B, 0x47, 0x1F,
++	0x00, 0xEB, 0xE7, 0x1B, 0xD7,
++	0x03, 0x51, 0x80, 0x84, 0x61,
++	0x09, 0x17, 0x9B, 0xD3, 0x72,
++	0x01, 0x54, 0xDF, 0xBE, 0x0B,
++	0x0E, 0x4D, 0x4C, 0xC6, 0x29,
++	0x0C, 0xD2, 0xFD, 0x8D, 0x1D,
++	0x09, 0x9E, 0x3E, 0xEC, 0x36,
++	0x07, 0x60, 0x35, 0xF1, 0xCC,
++	0x02, 0xDB, 0x3A, 0xC0, 0xE7,
++	0x01, 0xAA, 0x28, 0x80, 0x8E,
++	0x07, 0xB6, 0x68, 0xC3, 0x44,
++	0x08, 0x1E, 0xF8, 0xA9, 0x10,
++	0x0E, 0x76, 0x8C, 0xBE, 0xEC,
++	0x01, 0xCE, 0xF6, 0xAE, 0xA6,
++	0x07, 0x40, 0xCA, 0xC2, 0xF2,
++	0x0D, 0xF7, 0x46, 0xEA, 0x84,
++	0x0C, 0xFD, 0x04, 0xC0, 0xE7,
++	0x0A, 0x99, 0x80, 0xE1, 0xCB,
++	0x05, 0xFD, 0x16, 0x37, 0x57,
++	0x06, 0xBD, 0xD9, 0xE0, 0x47,
++	0x09, 0xAB, 0x4A, 0xA1, 0xD2,
++	0x0C, 0xBB, 0x81, 0xC8, 0x88,
++	0x07, 0x51, 0x21, 0x9B, 0xF5,
++	0x0C, 0xD0, 0xEF, 0x19, 0xBA,
++	0x07, 0x31, 0x7A, 0xAB, 0xBA,
++	0x05, 0xDE, 0xDC, 0xD9, 0x29,
++	0x05, 0xED, 0xBC, 0x4C, 0x04,
++	0x0B, 0x93, 0xE4, 0xE9, 0x58,
++	0x0F, 0x4D, 0xC8, 0x87, 0x18,
++	0x04, 0xCC, 0xAC, 0x79, 0x25,
++	0x03, 0x01, 0x8C, 0x83, 0x4B,
++	0x0A, 0x2C, 0x75, 0x86, 0x7A,
++	0x0B, 0xA0, 0xD6, 0xFD, 0x80,
++	0x0C, 0xD5, 0x40, 0xA5, 0x79,
++	0x0F, 0xCB, 0x3D, 0x2B, 0xAE,
++	0x0B, 0x42, 0x98, 0x50, 0xC4,
++	0x01, 0xDE, 0x1F, 0xFD, 0xFE,
++	0x0A, 0x6F, 0xE1, 0x29, 0x1A,
++	0x04, 0xF9, 0x31, 0x5F, 0xF8,
++	0x02, 0xBA, 0x98, 0x8C, 0x44,
++	0x0B, 0x08, 0x4A, 0xBE, 0x9E,
++	0x0B, 0x91, 0x42, 0xB0, 0x45,
++	0x09, 0xDE, 0x43, 0x6E, 0x62,
++	0x08, 0x9C, 0xF7, 0x99, 0xB0,
++	0x01, 0x3B, 0xC8, 0xF1, 0x37,
++	0x08, 0xAD, 0x7B, 0x08, 0x2B,
++	0x0A, 0x81, 0x4A, 0xF2, 0x1D,
++	0x09, 0xBB, 0x7F, 0x5D, 0x44,
++	0x0E, 0xF0, 0x1D, 0xBD, 0x5E,
++	0x0C, 0x3F, 0xE0, 0xFB, 0x1C,
++	0x04, 0x82, 0xD3, 0xB4, 0x79,
++	0x09, 0xA2, 0xAD, 0x7A, 0xFC,
++	0x03, 0x18, 0x94, 0x18, 0xC6,
++	0x03, 0xBC, 0xE1, 0xBD, 0x37,
++	0x02, 0xAC, 0xE9, 0xF7, 0x35,
++	0x0E, 0xE7, 0x94, 0xC8, 0x82,
++	0x0B, 0x0F, 0x4F, 0xE4, 0xB1,
++	0x06, 0x59, 0xE3, 0xF8, 0x81,
++	0x01, 0x73, 0xA9, 0x5F, 0x45,
++	0x0E, 0x95, 0xE1, 0x5C, 0x0D,
++	0x0C, 0x1F, 0x1A, 0x89, 0x4C,
++	0x08, 0xF8, 0x06, 0x84, 0x7D,
++	0x0F, 0xC1, 0xEF, 0x8F, 0xC4,
++	0x04, 0xA7, 0x68, 0xFE, 0x62,
++	0x05, 0x48, 0xE3, 0x6A, 0x31,
++	0x08, 0xE0, 0x16, 0x07, 0x7A,
++	0x0A, 0xC3, 0x7A, 0x2E, 0x45,
++	0x02, 0xD3, 0xF2, 0x59, 0x6F,
++	0x09, 0xA9, 0x9C, 0x21, 0xE1,
++	0x08, 0x5F, 0xD5, 0x63, 0x2C,
++	0x01, 0xC7, 0xDD, 0x06, 0x36,
++	0x0C, 0x76, 0x3E, 0x8C, 0x07,
++	0x0B, 0xAA, 0x38, 0x1C, 0x3A,
++	0x0D, 0x75, 0x12, 0x19, 0xC2,
++	0x06, 0xCD, 0x0E, 0xD4, 0x3B,
++	0x03, 0xDF, 0x17, 0x14, 0x0B,
++	0x05, 0xD1, 0xE7, 0xCD, 0x8A,
++	0x0B, 0x26, 0xDD, 0x4F, 0xAC,
++	0x00, 0x21, 0x18, 0x4E, 0x55,
++	0x06, 0xF4, 0xDC, 0xAA, 0x15,
++	0x07, 0xEC, 0x92, 0xCF, 0x11,
++	0x03, 0x30, 0x18, 0xDA, 0x36,
++	0x0F, 0xA2, 0xC7, 0x49, 0x65,
++	0x0F, 0xBA, 0x0D, 0x4D, 0xDA,
++	0x06, 0x7D, 0x54, 0x0A, 0x57,
++	0x0E, 0x72, 0x19, 0xD0, 0xFA,
++	0x00, 0x21, 0x84, 0x85, 0xE5,
++	0x0A, 0x1D, 0xE5, 0xFF, 0x07,
++	0x0E, 0x2E, 0x68, 0x12, 0x9D,
++	0x01, 0xCF, 0x9B, 0x13, 0xA3,
++	0x04, 0xAB, 0x49, 0x8A, 0x00,
++	0x03, 0x31, 0x5C, 0xAB, 0x0D,
++	0x02, 0xB9, 0x14, 0x2B, 0x4F,
++	0x09, 0x25, 0xBF, 0x06, 0xA6,
++	0x00, 0x31, 0x94, 0x79, 0x7F,
++	0x05, 0x8E, 0xB0, 0xDF, 0x1F,
++	0x04, 0x1A, 0xDA, 0xA0, 0xD0,
++	0x0A, 0xA8, 0x15, 0xBF, 0xA4,
++	0x00, 0x73, 0xA5, 0xE5, 0x5E,
++	0x08, 0x67, 0x0A, 0xCB, 0xBE,
++	0x0B, 0xC3, 0xFF, 0x1F, 0xF6,
++	0x0C, 0xC8, 0x24, 0x2B, 0xCD,
++	0x0F, 0x36, 0x2B, 0x57, 0x91,
++	0x07, 0x13, 0x10, 0x10, 0x0E,
++	0x01, 0x39, 0x57, 0x0B, 0x59,
++	0x02, 0x28, 0x57, 0x8F, 0x38,
++	0x0B, 0x7E, 0x4C, 0x4C, 0x4A,
++	0x03, 0x28, 0xD3, 0xFE, 0x01,
++	0x0D, 0x65, 0x9C, 0x1E, 0x62,
++	0x0E, 0xB7, 0x60, 0xB5, 0xF5,
++	0x0C, 0x09, 0x5E, 0x5D, 0xC3,
++	0x0E, 0x49, 0x29, 0xA8, 0xD0,
++	0x06, 0x97, 0x16, 0x68, 0x77,
++	0x0D, 0x3C, 0x18, 0x73, 0x37,
++	0x08, 0xCB, 0xD6, 0x83, 0x3E,
++	0x04, 0x56, 0xCE, 0x34, 0x2E,
++	0x0C, 0x27, 0xC4, 0x88, 0xC6,
++	0x08, 0xA9, 0xF0, 0xA6, 0xE5,
++	0x09, 0xAD, 0xFF, 0x66, 0x2C,
++	0x0C, 0x9A, 0x99, 0x84, 0xBD,
++	0x01, 0xA5, 0xFD, 0x16, 0x3A,
++	0x0B, 0x3C, 0x7C, 0xD0, 0x6B,
++	0x0E, 0xC1, 0x69, 0xEA, 0xA0,
++	0x09, 0xBC, 0xBB, 0x81, 0xCE,
++	0x0F, 0xF7, 0x51, 0x21, 0x9F,
++	0x06, 0x6C, 0x12, 0xEF, 0x4F,
++	0x00, 0xBD, 0x51, 0x73, 0x20,
++	0x0E, 0x2D, 0x18, 0xF7, 0x46,
++	0x01, 0x9D, 0xCD, 0x50, 0x4C,
++	0x0C, 0x00, 0x51, 0x86, 0x65,
++	0x02, 0x6A, 0x81, 0x48, 0xA5,
++	0x00, 0x7B, 0x06, 0x2D, 0xF8,
++	0x0C, 0x31, 0x21, 0x82, 0x63,
++	0x01, 0xFF, 0xE3, 0x75, 0xB6,
++	0x01, 0xFB, 0x60, 0xD4, 0x5D,
++	0x02, 0xD7, 0xD5, 0x44, 0xDC,
++	0x09, 0x77, 0x03, 0x9D, 0x27,
++	0x0E, 0xA2, 0x42, 0x38, 0x5E,
++	0x09, 0xA1, 0xDC, 0x1F, 0xF0,
++	0x00, 0xE2, 0xE6, 0x41, 0x29,
++	0x06, 0x1C, 0xF9, 0xB1, 0x51,
++	0x01, 0xDA, 0x7A, 0x98, 0xC8,
++	0x0C, 0xA3, 0xA9, 0x4A, 0xB0,
++	0x04, 0x5B, 0x97, 0xC9, 0x18,
++	0x05, 0x13, 0xFB, 0xFE, 0x6A,
++	0x0E, 0x01, 0x59, 0x44, 0x17,
++	0x0E, 0x5D, 0x3F, 0xAC, 0xF5,
++	0x0D, 0x44, 0x7B, 0xBB, 0x04,
++	0x06, 0xAA, 0x41, 0x48, 0x48,
++	0x0E, 0x07, 0x3A, 0x4B, 0x26,
++	0x04, 0x86, 0x70, 0xBD, 0xB3,
++	0x03, 0xBC, 0x3F, 0x60, 0xF7,
++	0x05, 0xCC, 0x80, 0x53, 0xB4,
++	0x02, 0xF3, 0x62, 0xA4, 0x71,
++	0x09, 0x51, 0x31, 0x10, 0x0B,
++	0x0F, 0x13, 0x57, 0x61, 0xFD,
++	0x0F, 0xA2, 0x25, 0x69, 0xFB,
++	0x0E, 0x77, 0xE2, 0x5F, 0x76,
++	0x0E, 0xB3, 0x2D, 0x23, 0xE8,
++	0x09, 0xD4, 0x19, 0xE1, 0x6E,
++	0x09, 0x5E, 0xAD, 0x8B, 0x5B,
++	0x0F, 0x07, 0x48, 0xE5, 0xDD,
++	0x07, 0x74, 0x5E, 0xB8, 0x33,
++	0x0C, 0xE1, 0x7B, 0x62, 0xFC,
++	0x08, 0x7F, 0xC1, 0xEF, 0x8B,
++	0x09, 0x04, 0xA7, 0xE8, 0xF3,
++	0x06, 0xC5, 0x4A, 0xE3, 0x6A,
++	0x09, 0x62, 0x20, 0x10, 0x8C,
++	0x07, 0x2A, 0xC1, 0x7A, 0x6E,
++	0x0F, 0xCA, 0xD5, 0x7D, 0x8B,
++	0x07, 0x49, 0x09, 0x1A, 0x8C,
++	0x0E, 0x9F, 0xEA, 0xD1, 0x63,
++	0x0C, 0xB3, 0xC7, 0x5B, 0x8C,
++	0x06, 0xEC, 0x16, 0xBE, 0xAA,
++	0x05, 0x2B, 0xC9, 0xB8, 0x1C,
++	0x02, 0x3D, 0x75, 0x12, 0x19,
++	0x0E, 0xD4, 0xCD, 0x0E, 0xC1,
++	0x0F, 0x83, 0xDD, 0x17, 0x32,
++	0x09, 0x4E, 0xD1, 0x6B, 0x87,
++	0x0A, 0x91, 0xC6, 0x59, 0x8E,
++	0x04, 0x40, 0x23, 0x18, 0x44,
++	0x0F, 0x66, 0xF5, 0x57, 0x41,
++	0x05, 0xA7, 0xEC, 0x82, 0xDD,
++	0x09, 0xB3, 0x31, 0x93, 0x07,
++	0x04, 0xBF, 0xA2, 0xD7, 0x5B,
++	0x0D, 0x6F, 0xA1, 0x86, 0xA2,
++	0x08, 0x2D, 0x7D, 0x44, 0x08,
++	0x0D, 0x77, 0x6B, 0xB2, 0x03,
++	0x0A, 0xEA, 0x24, 0x23, 0x87,
++	0x06, 0x9A, 0x1D, 0xE1, 0xFF,
++	0x0B, 0xBE, 0x2C, 0x64, 0x1C,
++	0x0D, 0xA3, 0xD9, 0x9B, 0x15,
++	0x09, 0x6D, 0xAA, 0x02, 0x5E,
++	0x00, 0x42, 0x34, 0x9C, 0xB4,
++	0x07, 0x29, 0xBA, 0x1F, 0xF3,
++	0x0F, 0xD9, 0x25, 0x3F, 0x2C,
++	0x06, 0x60, 0x32, 0x14, 0x69,
++	0x0F, 0x45, 0x8C, 0xB2, 0xCF,
++	0x05, 0x94, 0x01, 0x50, 0x6C,
++	0x0A, 0xFA, 0xA8, 0x04, 0xAD,
++	0x05, 0xE0, 0x73, 0xA4, 0xF5,
++	0x08, 0x48, 0x66, 0x4B, 0xD5,
++	0x0C, 0x3B, 0x55, 0xF2, 0x0F,
++	0x00, 0x60, 0xC8, 0x25, 0x0A,
++	0x0B, 0x99, 0x36, 0x2A, 0x75,
++	0x07, 0x55, 0x13, 0x11, 0x33,
++	0x08, 0x43, 0x39, 0x56, 0x18,
++	0x0B, 0x73, 0xA8, 0x56, 0x5F,
++	0x02, 0x4B, 0x7E, 0xCD, 0x06,
++	0x00, 0x63, 0x28, 0x56, 0xF4,
++	0x0B, 0x1D, 0x65, 0x12, 0x74,
++	0x08, 0x35, 0xB7, 0xEC, 0xFF,
++	0x05, 0x50, 0x29, 0xD2, 0x17,
++	0x00, 0xE7, 0x49, 0x67, 0xE2,
++	0x00, 0xCE, 0x17, 0x3A, 0xE2,
++	0x07, 0x87, 0xFC, 0x92, 0x72,
++	0x09, 0x90, 0x4A, 0xFA, 0xC5,
++	0x0E, 0x6C, 0x54, 0x02, 0xFC,
++	0x0E, 0x26, 0x20, 0x01, 0x02,
++	0x08, 0x92, 0xB7, 0xBC, 0x57,
++	0x04, 0x50, 0xAD, 0x2F, 0x66,
++	0x0D, 0xFC, 0x9A, 0x99, 0x80,
++	0x0A, 0x73, 0xA5, 0xFD, 0x27,
++	0x0A, 0xCB, 0x3E, 0x7D, 0xD0,
++	0x0B, 0x6E, 0xC1, 0xEB, 0xE0,
++	0x00, 0x52, 0xBC, 0x37, 0xCB,
++	0x0E, 0x93, 0xD7, 0xDD, 0x6B,
++	0x06, 0xCF, 0x77, 0x5B, 0x16,
++	0x0F, 0xF8, 0x3D, 0x71, 0x79,
++	0x08, 0x94, 0x6F, 0x1E, 0xBC,
++	0x02, 0x49, 0x07, 0xE6, 0xA0,
++	0x0C, 0x44, 0x02, 0x01, 0x86,
++	0x0F, 0xB8, 0x74, 0xC6, 0x36,
++	0x01, 0x5A, 0x7E, 0xDF, 0x2F,
++	0x03, 0xD5, 0x28, 0x8D, 0x8C,
++	0x03, 0x4B, 0xFA, 0x3C, 0x77,
++	0x0D, 0x78, 0xFB, 0xA0, 0xD6,
++	0x01, 0x9D, 0x28, 0x29, 0x43,
++	0x09, 0x5B, 0x77, 0x03, 0x9E,
++	0x07, 0xAE, 0xA0, 0x43, 0x38,
++	0x0E, 0xD9, 0xA1, 0x5E, 0x55,
++	0x00, 0x7B, 0xE2, 0x66, 0x4B,
++	0x09, 0xDA, 0x3C, 0x79, 0xBB,
++	0x02, 0x38, 0xD8, 0xB8, 0xD2,
++	0x02, 0xE4, 0x38, 0x85, 0xC0,
++	0x00, 0xDE, 0x9B, 0x81, 0x40,
++	0x0E, 0x1D, 0x89, 0xD7, 0xFE,
++	0x0A, 0x66, 0x03, 0x09, 0x44,
++	0x0C, 0xF4, 0x58, 0xEB, 0x2C,
++	0x09, 0xF7, 0xC5, 0xAD, 0x7B,
++	0x0F, 0xA9, 0x85, 0x81, 0x6A,
++	0x02, 0xEE, 0x03, 0x17, 0x4A,
++	0x0D, 0x44, 0x8A, 0x70, 0xBD,
++	0x0B, 0x43, 0x38, 0x3F, 0x20,
++	0x0F, 0xC7, 0xC8, 0x82, 0xA7,
++	0x04, 0x79, 0xF3, 0x62, 0xA4,
++	0x01, 0xB5, 0x7D, 0x35, 0x25,
++	0x00, 0x46, 0x97, 0x95, 0xA1,
++	0x05, 0x35, 0x26, 0x85, 0xA9,
++	0x0B, 0x24, 0xB7, 0xE4, 0xD4,
++	0x0C, 0x06, 0x3E, 0x89, 0x19,
++	0x00, 0xB1, 0x52, 0x59, 0x23,
++	0x06, 0x81, 0x5F, 0x76, 0xCB,
++	0x0F, 0x55, 0x02, 0x95, 0xE5,
++	0x0C, 0x0E, 0x78, 0x9A, 0x82,
++	0x01, 0x0C, 0x65, 0x7B, 0xA6,
++	0x0F, 0x7A, 0x7B, 0xC1, 0x2F,
++	0x0B, 0x99, 0x04, 0xA7, 0x68,
++	0x03, 0xE6, 0xC1, 0x5C, 0xDA,
++	0x00, 0x02, 0x78, 0x2C, 0x3B,
++	0x0E, 0x27, 0x2A, 0xC3, 0xFA,
++	0x0C, 0x45, 0x0A, 0xE3, 0x76,
++	0x09, 0x0F, 0x49, 0xA9, 0x98,
++	0x0C, 0x85, 0xBA, 0x5F, 0xD1,
++	0x03, 0xAC, 0xB3, 0xC7, 0xDD,
++	0x06, 0xB6, 0xEC, 0x00, 0xBC,
++	0x0A, 0x05, 0x2B, 0xDD, 0xFA,
++	0x0C, 0xE9, 0x3D, 0x65, 0x12,
++	0x09, 0xC2, 0xF6, 0xCD, 0x0E,
++	0x00, 0xFF, 0x83, 0xEF, 0x17,
++	0x02, 0x09, 0x4A, 0xC1, 0xE7,
++	0x07, 0x6A, 0x8B, 0x4A, 0xE2,
++	0x06, 0xC4, 0x40, 0x21, 0x98,
++	0x0C, 0x55, 0x86, 0xC4, 0x5C,
++	0x0A, 0x75, 0x27, 0xEC, 0x92,
++	0x0F, 0x73, 0xF3, 0x30, 0x18,
++	0x0A, 0x34, 0xBF, 0xA2, 0xC7,
++	0x09, 0x67, 0x8F, 0xAC, 0x0F,
++	0x0D, 0xD8, 0x2D, 0x6B, 0x16,
++	0x0A, 0x57, 0x97, 0x60, 0x39,
++	0x02, 0x7A, 0xEA, 0x24, 0x33,
++	0x05, 0xED, 0x9A, 0x2D, 0xE1,
++	0x0F, 0x07, 0xBA, 0x3E, 0x64,
++	0x08, 0x7D, 0xB8, 0xC3, 0xD8,
++	0x07, 0x23, 0x8D, 0xAB, 0x09,
++	0x0A, 0x80, 0x42, 0x00, 0x1C,
++	0x0B, 0x6D, 0x69, 0xB9, 0x14,
++	0x0B, 0xAF, 0x79, 0x25, 0xBF,
++	0x06, 0xA6, 0x60, 0x31, 0x94,
++	0x09, 0x7F, 0x45, 0x98, 0xB0,
++	0x0F, 0x1F, 0x74, 0x0C, 0x99,
++	0x00, 0x5A, 0xFA, 0xB8, 0x14,
++	0x0F, 0x2E, 0xE0, 0x73, 0xA4,
++	0x05, 0xD4, 0x48, 0x67, 0x0B,
++	0x0B, 0x34, 0x3B, 0xF3, 0xFE,
++	0x0F, 0x7C, 0x58, 0xD8, 0x25,
++	0x01, 0xA7, 0x83, 0x3A, 0x7A,
++	0x05, 0x1B, 0x57, 0x13, 0x91,
++	0x02, 0x84, 0x61, 0x09, 0xD6,
++	0x0B, 0xB3, 0xF2, 0x28, 0x56,
++	0x0F, 0x52, 0xEB, 0x7E, 0x4D,
++	0x0C, 0xC0, 0x63, 0x28, 0xD2,
++	0x0E, 0x8B, 0x1D, 0x73, 0x9C,
++	0x0E, 0xE8, 0x35, 0xA1, 0x22,
++	0x05, 0xF5, 0x50, 0x39, 0x5E,
++	0x0D, 0xC0, 0xE7, 0x49, 0xEB,
++	0x08, 0x90, 0xCE, 0x27, 0xB6,
++	0x08, 0x77, 0x83, 0xEC, 0x1E,
++	0x02, 0x59, 0x8C, 0xC6, 0x2A,
++	0x0D, 0x3E, 0x6C, 0x54, 0x0E,
++	0x04, 0xAE, 0x26, 0x12, 0x81,
++	0x08, 0xA2, 0xF2, 0xAC, 0x37,
++	0x06, 0x04, 0xF0, 0xAD, 0x3F,
++	0x04, 0x96, 0xFC, 0x9A, 0x99,
++	0x00, 0xC6, 0x51, 0xB3, 0xFF,
++	0x06, 0x3A, 0xCB, 0x2A, 0x3F,
++	0x00, 0x6B, 0x6E, 0xD1, 0x6B,
++	0x0A, 0xA0, 0x52, 0xBC, 0xBB,
++	0x01, 0xCE, 0x93, 0xF7, 0x51,
++	0x0A, 0x9C, 0x2F, 0x6C, 0xD0,
++	0x07, 0x0F, 0x7A, 0x30, 0xB1,
++	0x09, 0x26, 0xA0, 0x6D, 0x3E,
++	0x0C, 0xD8, 0xAD, 0x1C, 0x6D,
++	0x0C, 0x4C, 0x44, 0x02, 0x11,
++	0x06, 0xE5, 0x58, 0x61, 0x4D,
++	0x08, 0xA1, 0xDA, 0x7E, 0xC9,
++	0x0D, 0xF8, 0xB5, 0x33, 0x01,
++	0x0C, 0xA3, 0x4B, 0xFA, 0x2C,
++	0x05, 0x96, 0x78, 0xFF, 0xAA,
++	0x06, 0xDD, 0x82, 0xD3, 0xE7,
++	0x00, 0xA5, 0x7B, 0x77, 0x03,
++	0x06, 0x27, 0xAE, 0xA2, 0x43,
++	0x01, 0x5E, 0x19, 0xA1, 0xDE,
++	0x07, 0x70, 0xDB, 0xE2, 0xE6,
++	0x0B, 0xE9, 0xC3, 0x30, 0x96,
++	0x00, 0x53, 0xFD, 0xDA, 0xB8,
++	0x08, 0x09, 0xA0, 0x23, 0x09,
++	0x09, 0xB1, 0x1B, 0x9D, 0x9B,
++	0x00, 0x35, 0x5D, 0x94, 0x5B,
++	0x03, 0x6B, 0xA6, 0x03, 0x19,
++	0x06, 0x16, 0x54, 0x58, 0xEB,
++	0x07, 0xF1, 0xF7, 0x41, 0xAD,
++	0x07, 0x05, 0xA4, 0x2A, 0x92,
++	0x06, 0xCD, 0x1A, 0xC7, 0x2E,
++	0x07, 0x5D, 0xC4, 0x86, 0x70,
++	0x07, 0x73, 0x54, 0xB0, 0x45,
++	0x02, 0xFE, 0x41, 0x8C, 0x02,
++	0x01, 0xBD, 0xFD, 0xA3, 0xE2,
++	0x06, 0x78, 0x31, 0x47, 0x71,
++	0x02, 0x01, 0xC6, 0x15, 0x15,
++	0x01, 0xB4, 0xB7, 0x64, 0xC7,
++	0x09, 0xF2, 0xA4, 0xA1, 0x66,
++	0x0F, 0xCC, 0x06, 0x32, 0x8D,
++	0x03, 0xE8, 0xB2, 0x16, 0x68,
++	0x0A, 0xEE, 0x43, 0x5B, 0xB6,
++	0x02, 0x59, 0x95, 0x0E, 0xD5,
++	0x0F, 0xDA, 0x5C, 0xF4, 0xBE,
++	0x03, 0x8B, 0x4C, 0xED, 0x7B,
++	0x0C, 0x81, 0x3C, 0x7F, 0x81,
++	0x07, 0x8B, 0x99, 0x0C, 0x95,
++	0x02, 0xF5, 0xB4, 0x45, 0x68,
++	0x0A, 0x68, 0xA2, 0x6E, 0x20,
++	0x0A, 0x8A, 0x61, 0x2A, 0x83,
++	0x02, 0x6E, 0x45, 0x02, 0xA1,
++	0x0C, 0x4F, 0x3D, 0x49, 0x89,
++	0x01, 0x0E, 0x25, 0x16, 0x5F,
++	0x0B, 0x65, 0xE4, 0xB3, 0x87,
++	0x05, 0x06, 0xB6, 0xE4, 0xA4,
++	0x04, 0xAC, 0x57, 0xAB, 0xEB,
++	0x01, 0x1E, 0xA9, 0x31, 0x75,
++	0x08, 0x1F, 0x88, 0xF6, 0x8D,
++	0x06, 0xF0, 0xFF, 0x8B, 0x2D,
++	0x0D, 0x34, 0x5B, 0xCE, 0xF1,
++	0x0E, 0xCF, 0xCA, 0x9D, 0xC6,
++	0x0F, 0xC2, 0x88, 0x40, 0x61,
++	0x00, 0x4E, 0x55, 0x8F, 0xC6,
++	0x06, 0x8C, 0x47, 0x27, 0xCC,
++	0x0B, 0xDD, 0xD3, 0x5F, 0x30,
++	0x02, 0xCC, 0x7A, 0xBF, 0xE2,
++	0x0F, 0x59, 0x67, 0x86, 0xC8,
++	0x07, 0x6B, 0x8A, 0xAD, 0x5D,
++	0x0D, 0x08, 0x17, 0x9B, 0x70,
++	0x03, 0xD4, 0x2A, 0xEA, 0x64,
++	0x0B, 0x85, 0xED, 0x93, 0xAF,
++	0x0B, 0xF9, 0x55, 0x3E, 0x0E,
++	0x0D, 0x10, 0xDD, 0xAF, 0xCF,
++	0x01, 0x13, 0x71, 0x8D, 0xEB,
++	0x01, 0x88, 0x80, 0x4B, 0xC2,
++	0x06, 0xAD, 0x5F, 0x69, 0x99,
++	0x0C, 0x2B, 0x4F, 0xD9, 0x17,
++	0x0F, 0x26, 0xA6, 0x60, 0x31,
++	0x0F, 0x69, 0x7F, 0x45, 0x8E,
++	0x0B, 0xCD, 0x5F, 0x78, 0x1A,
++	0x01, 0xB6, 0x0F, 0x7A, 0xE8,
++	0x0C, 0xAF, 0x2E, 0xEC, 0xD3,
++	0x0E, 0xF3, 0xB7, 0x48, 0x47,
++	0x02, 0xD9, 0x74, 0x37, 0xC3,
++	0x04, 0x09, 0x2B, 0xDC, 0x88,
++	0x0D, 0x3B, 0x47, 0x93, 0x97,
++	0x00, 0x41, 0x78, 0x57, 0x33,
++	0x08, 0x02, 0xC4, 0x6D, 0x39,
++	0x0C, 0x1D, 0x8A, 0xF2, 0x68,
++	0x0E, 0x9F, 0xB2, 0x47, 0xDC,
++	0x07, 0x4A, 0xA3, 0x63, 0x08,
++	0x0B, 0xFC, 0xCB, 0x11, 0x65,
++	0x04, 0x38, 0xB3, 0xB5, 0xF7,
++	0x08, 0xB5, 0xF5, 0x5C, 0x8A,
++	0x04, 0x5B, 0xA3, 0xE7, 0x69,
++	0x02, 0xAA, 0xD0, 0xC2, 0x17,
++	0x0C, 0x6E, 0x2A, 0x07, 0xBC,
++	0x06, 0xF8, 0xB9, 0x9C, 0xEE,
++	0x0C, 0x89, 0x5D, 0x6C, 0x74,
++	0x07, 0x34, 0xEE, 0x2A, 0x22,
++	0x0B, 0x0E, 0x9D, 0xF2, 0xEC,
++	0x0F, 0xA6, 0xE4, 0x5C, 0x08,
++	0x05, 0x62, 0xF5, 0xFC, 0xBA,
++	0x00, 0x82, 0x86, 0x5D, 0xA5,
++	0x07, 0x10, 0x5B, 0x4B, 0x7C,
++	0x05, 0xD0, 0x6B, 0x62, 0x67,
++	0x01, 0xEC, 0xC3, 0x52, 0x9C,
++	0x02, 0x83, 0x8E, 0x9F, 0xD7,
++	0x0B, 0x27, 0xFF, 0x2F, 0x2C,
++	0x08, 0xEF, 0x0F, 0xF4, 0x9A,
++	0x01, 0x73, 0x20, 0x94, 0xED,
++	0x05, 0x7C, 0xD8, 0xA9, 0x1C,
++	0x04, 0xDC, 0xAC, 0x44, 0xC2,
++	0x0B, 0x82, 0x83, 0x58, 0x2F,
++	0x05, 0xC8, 0xA1, 0x5E, 0x58,
++	0x03, 0x2B, 0x84, 0xB5, 0x32,
++	0x08, 0x0E, 0xC3, 0x47, 0xFA,
++	0x06, 0x73, 0xFE, 0x78, 0xBB,
++	0x08, 0xD6, 0xDD, 0x86, 0xF7,
++	0x0F, 0x46, 0xD8, 0xF9, 0x76,
++	0x0A, 0x1F, 0x47, 0xA2, 0xA2,
++	0x09, 0x3E, 0x34, 0xD9, 0xE1,
++	0x06, 0x1F, 0xF0, 0x7F, 0xC3,
++	0x0C, 0x47, 0x54, 0x5A, 0x3D,
++	0x00, 0x33, 0x32, 0x34, 0xDA,
++	0x02, 0x9E, 0xE4, 0x04, 0x63,
++	0x01, 0xCA, 0xB0, 0xDA, 0xB9,
++	0x0B, 0x44, 0xC9, 0x7D, 0x93,
++	0x02, 0x70, 0x0A, 0x6A, 0x03,
++	0x03, 0x40, 0xF9, 0xF4, 0x18,
++	0x03, 0x2C, 0xF1, 0xF3, 0x62,
++	0x07, 0xBD, 0x78, 0x2F, 0xAB,
++	0x08, 0xC8, 0x92, 0xE2, 0x07,
++	0x00, 0x49, 0x2D, 0x44, 0xC6,
++	0x08, 0xBD, 0xB3, 0x47, 0x98,
++	0x05, 0xE6, 0x8A, 0x45, 0xCD,
++	0x0B, 0xD1, 0xD4, 0x75, 0xF3,
++	0x08, 0xA2, 0x03, 0xB5, 0x31,
++	0x09, 0x10, 0x08, 0x42, 0x36,
++	0x0F, 0x67, 0xC0, 0xB7, 0x23,
++	0x0C, 0xEB, 0x9B, 0x28, 0xB7,
++	0x0E, 0xD2, 0xB8, 0x06, 0x72,
++	0x05, 0x2F, 0xE8, 0xB5, 0xF0,
++	0x03, 0xE5, 0x93, 0x03, 0x5A,
++	0x0F, 0x89, 0x3F, 0x59, 0x02,
++	0x0F, 0xE3, 0xAA, 0x0E, 0x34,
++	0x06, 0xBA, 0x89, 0x08, 0xC6,
++	0x01, 0x60, 0xFA, 0xF8, 0x7E,
++	0x08, 0x6D, 0xEB, 0x95, 0x04,
++	0x0D, 0x6E, 0x8B, 0x66, 0x85,
++	0x00, 0xE3, 0x6A, 0xE6, 0x44,
++	0x08, 0x10, 0x8C, 0x23, 0x0D,
++	0x09, 0x7C, 0x13, 0xC5, 0x0B,
++	0x0A, 0x74, 0x29, 0x63, 0xC9,
++	0x03, 0x9E, 0x77, 0x65, 0x5A,
++	0x07, 0xD1, 0x63, 0xA8, 0x93,
++	0x0F, 0xDD, 0x06, 0xB2, 0xCA,
++	0x0C, 0xB8, 0xD7, 0x85, 0x2A,
++	0x02, 0x3A, 0x7C, 0xE5, 0x3D,
++	0x0F, 0x14, 0x64, 0x42, 0xB6,
++	0x05, 0x0E, 0xF0, 0xFB, 0xA2,
++	0x07, 0x17, 0x32, 0x0D, 0x69,
++	0x0B, 0xE1, 0xB0, 0x0A, 0x90,
++	0x06, 0xD5, 0xC4, 0xC4, 0x40,
++	0x0A, 0x18, 0x4E, 0x55, 0x86,
++	0x0D, 0x5C, 0x6A, 0x15, 0x67,
++	0x06, 0x94, 0x5F, 0x13, 0x13,
++	0x08, 0x18, 0xCA, 0x30, 0x9F,
++	0x08, 0xC1, 0xC1, 0x67, 0x8E,
++	0x03, 0x8F, 0x0D, 0xD4, 0x2D,
++	0x07, 0x52, 0x88, 0xD7, 0xD7,
++	0x08, 0x39, 0xD2, 0x7E, 0xCA,
++	0x0E, 0x35, 0x1D, 0xED, 0x9B,
++	0x04, 0x63, 0x9F, 0x0B, 0xBE,
++	0x04, 0x62, 0x96, 0x1D, 0xE3,
++	0x07, 0x9B, 0x15, 0x27, 0xAC,
++	0x01, 0x8F, 0x10, 0x80, 0x43,
++	0x09, 0x1E, 0xCB, 0x01, 0xE9,
++	0x03, 0x12, 0xAD, 0xCF, 0x99,
++	0x0D, 0xBF, 0x26, 0xA2, 0x42,
++	0x0B, 0x92, 0xF1, 0x7F, 0x44,
++	0x07, 0x30, 0xAF, 0x13, 0x74,
++	0x00, 0xDD, 0x38, 0xDA, 0xBA,
++	0x00, 0x14, 0xAF, 0x2A, 0xC3,
++	0x09, 0xA2, 0x6D, 0xD4, 0x49,
++	0x0E, 0x89, 0xBB, 0x38, 0x3B,
++	0x09, 0xF8, 0x85, 0xFC, 0x1C,
++	0x00, 0x25, 0x3B, 0x43, 0xBB,
++	0x0C, 0x2C, 0xDF, 0x1B, 0x56,
++	0x0A, 0x93, 0x60, 0x88, 0x61,
++	0x03, 0x50, 0x97, 0x53, 0x32,
++	0x00, 0x56, 0x9F, 0xB6, 0x6E,
++	0x04, 0x4B, 0xD4, 0xC0, 0x62,
++	0x01, 0x50, 0x9E, 0x87, 0x1D,
++	0x0F, 0x98, 0xB0, 0x68, 0x75,
++	0x0F, 0x60, 0xB5, 0xF1, 0x76,
++	0x03, 0x58, 0xC5, 0xC0, 0xE6,
++	0x00, 0x69, 0xC8, 0x9C, 0xCE,
++	0x0D, 0xB0, 0xF8, 0xF7, 0xC7,
++	0x04, 0x1E, 0xF8, 0xBD, 0xB7,
++	0x00, 0x70, 0x17, 0x3E, 0x6D,
++	0x0D, 0x0C, 0x56, 0xA2, 0x26,
++	0x08, 0x07, 0x9B, 0xC2, 0x32,
++	0x04, 0x37, 0xA6, 0xE0, 0x76,
++	0x05, 0x3F, 0x64, 0x92, 0xDB,
++	0x00, 0x9F, 0x18, 0xC6, 0x50,
++	0x0C, 0x7F, 0x76, 0x36, 0xCB,
++	0x06, 0x7B, 0x45, 0xEB, 0x2E,
++	0x09, 0x6B, 0xEA, 0xA4, 0x72,
++	0x04, 0xBB, 0x81, 0xCA, 0xB5,
++	0x0D, 0x57, 0xB9, 0x9C, 0x2E,
++	0x05, 0x52, 0x8F, 0x03, 0xF8,
++	0x07, 0xF7, 0xEB, 0x20, 0xD4,
++	0x05, 0x1E, 0x7C, 0xDC, 0x88,
++	0x04, 0x6D, 0x5C, 0x48, 0x63,
++	0x08, 0x17, 0x1C, 0xE5, 0x59,
++	0x0F, 0x4D, 0xC8, 0xA1, 0x5A,
++	0x05, 0xC9, 0x2D, 0xF9, 0x35,
++	0x03, 0x01, 0x8C, 0xA3, 0x4B,
++	0x01, 0xA9, 0x0E, 0x16, 0x78,
++	0x0B, 0xA0, 0xD6, 0xD3, 0xC6,
++	0x0C, 0x57, 0x31, 0xA6, 0x7C,
++	0x0B, 0x03, 0x9D, 0x67, 0xA0,
++	0x0E, 0x43, 0x38, 0x1E, 0xE1,
++	0x0D, 0xDE, 0x1C, 0x70, 0x41,
++	0x0E, 0xE6, 0x41, 0x29, 0xE1,
++	0x04, 0xF9, 0x31, 0x5E, 0x38,
++	0x01, 0x3A, 0x83, 0x08, 0x04,
++	0x08, 0x09, 0xCA, 0xB0, 0xDE,
++	0x0B, 0x91, 0x42, 0xB4, 0xFD,
++	0x09, 0xDE, 0x69, 0xEA, 0x66,
++	0x03, 0x19, 0x46, 0x99, 0x71,
++	0x08, 0xEB, 0x2C, 0xFF, 0x3E,
++	0x0A, 0x28, 0x02, 0x05, 0xAF,
++	0x0A, 0x81, 0x4A, 0xFC, 0x27,
++	0x0C, 0xBF, 0x91, 0xDD, 0x44,
++	0x0A, 0x70, 0xBB, 0x33, 0x7A,
++	0x05, 0xBF, 0x00, 0xF9, 0x05,
++	0x04, 0x83, 0xB3, 0xB8, 0x79,
++	0x0A, 0xE3, 0x44, 0x7F, 0xF5,
++	0x01, 0x31, 0x10, 0x0C, 0x4F,
++	0x03, 0x95, 0x61, 0xB9, 0x0E,
++	0x09, 0x00, 0xA8, 0x7B, 0x24,
++	0x0F, 0x2C, 0x74, 0xC2, 0xC6,
++	0x0A, 0x0C, 0x8F, 0xE6, 0xF1,
++	0x06, 0x59, 0xE3, 0xEE, 0x83,
++	0x0B, 0x76, 0x09, 0x5B, 0x1C,
++	0x02, 0x95, 0xE6, 0xDC, 0x0E,
++	0x04, 0x9E, 0xB8, 0x89, 0x0C,
++	0x0A, 0xFE, 0xAE, 0x09, 0x31,
++	0x04, 0xC1, 0xEF, 0x8B, 0x99,
++	0x04, 0xA7, 0x68, 0xF3, 0xE6,
++	0x0D, 0x48, 0xE1, 0x6A, 0xE2,
++	0x0A, 0x50, 0x90, 0x82, 0xE7,
++	0x0A, 0xC3, 0x7A, 0xE0, 0xCF,
++	0x0A, 0xD3, 0xF6, 0xCD, 0x65,
++	0x09, 0xA9, 0x9A, 0x0C, 0x6F,
++	0x0A, 0x5F, 0xD3, 0x6E, 0xA5,
++	0x0F, 0xC5, 0xDD, 0x06, 0x8F,
++	0x04, 0x16, 0x3C, 0xA8, 0x85,
++	0x01, 0xCD, 0x0B, 0x9C, 0xC9,
++	0x0D, 0x75, 0x10, 0x14, 0x8B,
++	0x06, 0xCD, 0x0F, 0x70, 0xFF,
++	0x03, 0xDF, 0x17, 0x32, 0x09,
++	0x06, 0xD1, 0x63, 0xCF, 0x0A,
++	0x09, 0xC7, 0x55, 0xC8, 0xC4,
++	0x08, 0xA3, 0x16, 0x4E, 0x95,
++	0x0C, 0xF2, 0x68, 0x8A, 0x55,
++	0x07, 0xEC, 0x90, 0xD1, 0x9A,
++	0x03, 0x30, 0x1A, 0xC4, 0xFE,
++	0x05, 0xA4, 0x73, 0x59, 0x66,
++	0x07, 0xBA, 0x8D, 0x6D, 0xD8,
++	0x0D, 0x7D, 0x56, 0x07, 0x1E,
++	0x07, 0x70, 0x38, 0x52, 0x7A,
++	0x0A, 0x24, 0x31, 0x81, 0xE7,
++	0x01, 0x1D, 0xE1, 0xFF, 0x07,
++	0x06, 0x2E, 0x64, 0x12, 0x9D,
++	0x03, 0xCF, 0x99, 0x18, 0x2A,
++	0x0D, 0xAB, 0x89, 0x88, 0x80,
++	0x0B, 0x30, 0x5E, 0xA9, 0x8D,
++	0x03, 0xBF, 0xCB, 0x2B, 0x6F,
++	0x05, 0x25, 0xBF, 0xA6, 0x92,
++	0x08, 0x31, 0x14, 0x67, 0x3F,
++	0x0D, 0x8C, 0xB2, 0xC1, 0xDF,
++	0x0D, 0x1B, 0x5B, 0xBD, 0x5A,
++	0x03, 0xAA, 0x14, 0xA2, 0x2E,
++	0x00, 0x73, 0xA6, 0xF8, 0x5D,
++	0x04, 0x67, 0x08, 0x1B, 0x00,
++	0x02, 0x43, 0x1E, 0x02, 0x7C,
++	0x05, 0x4A, 0x47, 0x39, 0xC7,
++	0x05, 0x30, 0xC8, 0xC7, 0x3B,
++	0x07, 0x13, 0x11, 0x0D, 0xCD,
++	0x09, 0x49, 0xD4, 0x15, 0x13,
++	0x02, 0x28, 0x56, 0x11, 0x38,
++	0x0B, 0x7E, 0x4D, 0xC8, 0xCA,
++	0x03, 0x28, 0xD2, 0x70, 0xC1,
++	0x0D, 0x65, 0x9E, 0x3E, 0xE8,
++	0x0C, 0xB7, 0xA0, 0xB7, 0x75,
++	0x09, 0x28, 0x9E, 0x51, 0xC0,
++	0x07, 0x49, 0xEB, 0xA8, 0x90,
++	0x0E, 0x17, 0xB6, 0x6C, 0xFD,
++	0x0F, 0xFC, 0x1E, 0xF8, 0xB9,
++	0x09, 0xCA, 0x94, 0x8D, 0xBE,
++	0x06, 0x52, 0x6C, 0xB6, 0xAC,
++	0x0F, 0xA0, 0x61, 0x08, 0x02,
++	0x0A, 0xAC, 0x37, 0xA6, 0xE4,
++	0x08, 0xAD, 0x3F, 0x60, 0x62,
++	0x06, 0x9C, 0x7B, 0x00, 0xD6,
++	0x08, 0xA5, 0x3F, 0x1B, 0xBA,
++	0x02, 0x3D, 0xBD, 0xDE, 0xAB,
++	0x06, 0xC1, 0x6B, 0xEA, 0xA0,
++	0x0A, 0xBC, 0xBB, 0x85, 0x47,
++	0x0A, 0xD7, 0x91, 0x2D, 0x9C,
++	0x06, 0x6D, 0x10, 0xED, 0x8F,
++	0x00, 0x3D, 0xF1, 0x73, 0x20,
++	0x0C, 0xED, 0x1C, 0x78, 0x52,
++	0x02, 0x99, 0xBD, 0xD1, 0xC5,
++	0x0D, 0x82, 0xF1, 0x89, 0xE5,
++	0x02, 0x69, 0xAF, 0x48, 0xE1,
++	0x0A, 0x7E, 0xCB, 0x20, 0xB0,
++	0x05, 0x33, 0x00, 0x0C, 0xA3,
++	0x0B, 0xFA, 0x2C, 0x75, 0x96,
++	0x00, 0xFB, 0xA0, 0xD6, 0xD7,
++	0x0B, 0xD7, 0x15, 0x4D, 0x2C,
++	0x00, 0xF7, 0xE3, 0x91, 0x27,
++	0x07, 0x23, 0xA3, 0x3A, 0xDE,
++	0x01, 0xA1, 0xDE, 0x1F, 0xF0,
++	0x03, 0xE2, 0xE4, 0x45, 0xE3,
++	0x06, 0x3C, 0xFA, 0x71, 0x66,
++	0x01, 0x58, 0xD8, 0x95, 0x88,
++	0x0E, 0x25, 0xEB, 0x4A, 0xB8,
++	0x02, 0x9B, 0x92, 0xC2, 0x80,
++	0x04, 0x93, 0x9B, 0xFF, 0x6A,
++	0x0E, 0x03, 0x19, 0x46, 0x97,
++	0x0C, 0x58, 0xE9, 0x28, 0x78,
++	0x0F, 0x41, 0xAD, 0x3F, 0xB1,
++	0x07, 0xAA, 0x82, 0xC8, 0x78,
++	0x0E, 0x07, 0x38, 0x41, 0x97,
++	0x0C, 0x86, 0x72, 0xB0, 0xBA,
++	0x0B, 0xBC, 0xBF, 0x60, 0xF7,
++	0x0D, 0x4C, 0x22, 0x51, 0x34,
++	0x03, 0xF5, 0xBC, 0xA4, 0x51,
++	0x0C, 0x71, 0xF1, 0x12, 0x88,
++	0x0C, 0x15, 0x4B, 0x61, 0x9D,
++	0x0E, 0x20, 0xA5, 0x6B, 0x7B,
++	0x0E, 0xB1, 0x3F, 0x54, 0xEC,
++	0x0F, 0xB0, 0xCD, 0x23, 0xE8,
++	0x0B, 0xD0, 0x82, 0x63, 0xCE,
++	0x0A, 0xDA, 0xB6, 0x07, 0x5F,
++	0x0F, 0x04, 0x4E, 0x65, 0xFC,
++	0x04, 0x72, 0x40, 0xBA, 0x88,
++	0x04, 0xE1, 0x7B, 0x68, 0x8E,
++	0x00, 0x7F, 0xC1, 0xED, 0x01,
++	0x01, 0x04, 0xA7, 0x65, 0x7A,
++	0x0A, 0xC5, 0x4B, 0x23, 0x5E,
++	0x0A, 0x62, 0x20, 0x1D, 0x86,
++	0x0F, 0x2A, 0xC1, 0x7A, 0x6E,
++	0x0F, 0x0C, 0x31, 0x76, 0x48,
++	0x07, 0xC9, 0xA9, 0x95, 0x85,
++	0x0F, 0xDA, 0x57, 0xDC, 0xA2,
++	0x0C, 0xB3, 0xC5, 0xDD, 0x06,
++	0x06, 0xEC, 0x14, 0xBE, 0xA0,
++	0x05, 0x2B, 0xC9, 0xB5, 0x55,
++	0x09, 0x3D, 0x74, 0x92, 0x19,
++	0x02, 0xF6, 0xCF, 0x0E, 0xFA,
++	0x07, 0x83, 0xDF, 0x17, 0x32,
++	0x02, 0x4E, 0xD1, 0xE7, 0xCD,
++	0x03, 0x11, 0x22, 0xD5, 0x04,
++	0x0E, 0x46, 0xC4, 0x98, 0x0E,
++	0x0C, 0x86, 0x34, 0xD8, 0x8A,
++	0x0F, 0xA1, 0x16, 0x12, 0xDE,
++	0x0F, 0x53, 0x31, 0x58, 0xF3,
++	0x0D, 0x3D, 0x82, 0xC9, 0x19,
++	0x0D, 0x89, 0x53, 0x0D, 0x7D,
++	0x04, 0x2D, 0x7B, 0xD4, 0x33,
++	0x0E, 0x97, 0xB0, 0x37, 0x92,
++	0x03, 0xE8, 0x64, 0x37, 0x85,
++	0x07, 0x9C, 0xE7, 0x61, 0xFE,
++	0x0B, 0xBE, 0x2C, 0x24, 0x2B,
++	0x04, 0x21, 0xEF, 0x95, 0x55,
++	0x09, 0x8B, 0x40, 0x09, 0x8C,
++	0x09, 0x42, 0xF0, 0x98, 0xAB,
++	0x07, 0xEF, 0x43, 0x94, 0x2A,
++	0x03, 0xD9, 0x27, 0xFF, 0x1F,
++	0x0F, 0xE2, 0x31, 0x9A, 0x29,
++	0x05, 0x43, 0x61, 0xB2, 0xCB,
++	0x03, 0x74, 0x1F, 0xDB, 0x89,
++	0x03, 0xFA, 0x68, 0x1A, 0xEF,
++	0x07, 0xE2, 0x33, 0xA0, 0xB5,
++	0x0E, 0x4E, 0x9D, 0x8B, 0xDA,
++	0x08, 0x3B, 0xC2, 0xBE, 0x36,
++	0x05, 0xDE, 0xC8, 0x2B, 0x7B,
++	0x0D, 0x99, 0xC2, 0x2A, 0x57,
++	0x07, 0x57, 0x12, 0xD1, 0x39,
++	0x0D, 0xE3, 0x19, 0x58, 0x5B,
++	0x09, 0x74, 0xDC, 0x56, 0x97,
++	0x0E, 0x4B, 0x7A, 0xCD, 0x75,
++	0x09, 0x63, 0xE8, 0xDC, 0xBE,
++	0x02, 0x1C, 0xA5, 0x9A, 0x7E,
++	0x02, 0x33, 0x4D, 0xE0, 0xB4,
++	0x09, 0x50, 0x28, 0x1E, 0x64,
++	0x09, 0x65, 0x49, 0xE5, 0xE8,
++	0x0A, 0xC8, 0xEE, 0xB6, 0x78,
++	0x0B, 0x87, 0xFD, 0xDE, 0xC1,
++	0x00, 0x12, 0x6A, 0x78, 0xCF,
++	0x04, 0x6A, 0xAD, 0x8E, 0x32,
++	0x02, 0x26, 0x23, 0x81, 0x31,
++	0x0B, 0x72, 0x6C, 0x33, 0xE6,
++	0x0D, 0x52, 0xED, 0x31, 0x24,
++	0x0C, 0xFA, 0x60, 0x19, 0x81,
++	0x0A, 0x52, 0x1E, 0x7D, 0x2F,
++	0x0A, 0xCB, 0x3C, 0x73, 0xAB,
++	0x01, 0x68, 0x3E, 0xEB, 0xEB,
++	0x09, 0xD3, 0x7C, 0xBB, 0x41,
++	0x02, 0xAB, 0xD7, 0x51, 0x36,
++	0x00, 0x10, 0x90, 0xD0, 0xD6,
++	0x0F, 0xF8, 0x3D, 0xF5, 0xAE,
++	0x09, 0x14, 0x0D, 0x10, 0x3C,
++	0x01, 0x2F, 0xFC, 0x6D, 0x9C,
++	0x0C, 0x44, 0x02, 0x11, 0x84,
++	0x0C, 0xF0, 0x8F, 0x49, 0x08,
++	0x01, 0x5A, 0x7E, 0xC9, 0x2D,
++	0x09, 0x35, 0x33, 0x05, 0x77,
++	0x03, 0x4B, 0xFA, 0x2C, 0x75,
++	0x0D, 0x78, 0xFB, 0xA0, 0xD6,
++	0x01, 0x82, 0xD6, 0x95, 0x79,
++	0x0C, 0xFB, 0x77, 0x0D, 0xDD,
++	0x0D, 0xA9, 0xAA, 0x43, 0x3C,
++	0x02, 0xD9, 0xA3, 0x9E, 0x26,
++	0x09, 0xF9, 0xE2, 0xE8, 0x01,
++	0x03, 0xDD, 0x34, 0xF9, 0xA1,
++	0x0E, 0x38, 0xD8, 0xF8, 0xA1,
++	0x01, 0x86, 0x03, 0x07, 0x8A,
++	0x0A, 0xD9, 0x9C, 0x91, 0x4A,
++	0x08, 0xFD, 0x93, 0x1B, 0xCB,
++	0x03, 0xE4, 0x43, 0x17, 0x06,
++	0x0D, 0xF3, 0x5F, 0xEB, 0x2E,
++	0x0B, 0xF0, 0x49, 0xAD, 0xBA,
++	0x0C, 0xAF, 0x6A, 0x85, 0x4A,
++	0x08, 0xE9, 0x34, 0x3A, 0x4E,
++	0x01, 0x44, 0x87, 0x30, 0x84,
++	0x0A, 0xC1, 0xFC, 0x31, 0xA0,
++	0x0D, 0xC2, 0xDC, 0x82, 0x57,
++	0x08, 0x79, 0xF1, 0x22, 0x9D,
++	0x08, 0x37, 0x31, 0x3F, 0x50,
++	0x02, 0x41, 0x03, 0x95, 0x71,
++	0x01, 0x37, 0x20, 0xC5, 0x50,
++	0x02, 0xA6, 0xB7, 0xEA, 0x94,
++	0x06, 0x01, 0x3C, 0x0D, 0x27,
++	0x04, 0xB1, 0xD7, 0x19, 0xDA,
++	0x07, 0x01, 0x7B, 0x78, 0x4B,
++	0x05, 0x52, 0x0C, 0x15, 0xE7,
++	0x06, 0x09, 0x64, 0x9E, 0xBB,
++	0x05, 0x0C, 0xE3, 0xFB, 0x5F,
++	0x0E, 0x79, 0xBF, 0xCF, 0xAF,
++	0x01, 0x9E, 0x37, 0xA7, 0x69,
++	0x0F, 0xE6, 0xC4, 0x08, 0xDA,
++	0x03, 0x60, 0x42, 0x2E, 0x50,
++	0x06, 0x20, 0x32, 0xC3, 0x7E,
++	0x02, 0x45, 0x08, 0x93, 0xCF,
++	0x00, 0xED, 0xE9, 0xA7, 0xD8,
++	0x06, 0x62, 0x02, 0x5F, 0xC1,
++	0x0F, 0xAC, 0xB2, 0x87, 0xE4,
++	0x0F, 0x34, 0xEC, 0x18, 0xFE,
++	0x00, 0x02, 0x3D, 0x4B, 0xBA,
++	0x00, 0xE9, 0x3F, 0x35, 0x2B,
++	0x00, 0x40, 0xB6, 0xC3, 0x4E,
++	0x0A, 0xF8, 0x95, 0x5F, 0x1F,
++	0x08, 0x0E, 0x56, 0xD1, 0xE6,
++	0x01, 0x8A, 0x95, 0x46, 0xEC,
++	0x0D, 0xC5, 0xE0, 0x2F, 0x58,
++	0x04, 0x52, 0xB5, 0xF4, 0xDD,
++	0x06, 0x15, 0xA6, 0xAC, 0xAB,
++	0x06, 0x11, 0x53, 0x3E, 0x58,
++	0x00, 0x33, 0x9F, 0x22, 0xC3,
++	0x05, 0x67, 0x8D, 0xFA, 0x34,
++	0x04, 0x5A, 0x2D, 0x73, 0x14,
++	0x00, 0x50, 0xB7, 0xF0, 0x29,
++	0x0E, 0x7A, 0xEB, 0x64, 0x0A,
++	0x0C, 0x6F, 0xBA, 0x13, 0xA1,
++	0x05, 0x00, 0xA0, 0xAE, 0x66,
++	0x0E, 0x9D, 0xA1, 0x8F, 0xA2,
++	0x0C, 0xA1, 0xCD, 0xA5, 0xC9,
++	0x02, 0x87, 0x5C, 0xB0, 0x94,
++	0x01, 0x0A, 0xC9, 0x39, 0x15,
++	0x07, 0x4F, 0xDF, 0xA5, 0x86,
++	0x0F, 0xA6, 0xA0, 0x3F, 0xD4,
++	0x00, 0x7D, 0x05, 0x8A, 0xB2,
++	0x05, 0x18, 0x47, 0x1A, 0xDA,
++	0x0C, 0x5A, 0xFB, 0xE8, 0x2D,
++	0x06, 0xAC, 0xC0, 0x7D, 0xE4,
++	0x0F, 0xD3, 0x61, 0x67, 0x0F,
++	0x07, 0x34, 0x39, 0x83, 0xC7,
++	0x06, 0xFE, 0x7C, 0xC6, 0x65,
++	0x01, 0x40, 0xB6, 0x36, 0x3A,
++	0x0B, 0x1B, 0x55, 0x53, 0x28,
++	0x09, 0x06, 0x61, 0x37, 0x16,
++	0x01, 0xD4, 0x55, 0x28, 0x5E,
++	0x03, 0xB2, 0x4A, 0x3E, 0x74,
++	0x05, 0x42, 0x23, 0x26, 0x92,
++	0x04, 0x8C, 0x3A, 0x65, 0x9C,
++	0x04, 0xEF, 0x1C, 0xB7, 0x61,
++	0x09, 0xF5, 0x54, 0xA9, 0x67,
++	0x04, 0xC0, 0x27, 0x47, 0xAB,
++	0x01, 0x92, 0x8E, 0x13, 0xF6,
++	0x02, 0x70, 0xB4, 0xFC, 0x1F,
++	0x04, 0xB9, 0x91, 0x0A, 0x4F,
++	0x06, 0xBC, 0x2C, 0x5A, 0xCE,
++	0x0C, 0xA9, 0x17, 0xA2, 0x05,
++	0x04, 0xC2, 0x70, 0xEC, 0x0E,
++	0x0F, 0x66, 0x10, 0xA3, 0x7F,
++	0x0E, 0x91, 0xCD, 0x1A, 0x89,
++	0x0C, 0xC6, 0x50, 0xE5, 0xC4,
++	0x0F, 0xB8, 0xCB, 0x32, 0x3D,
++	0x0A, 0x6C, 0x41, 0x41, 0x69,
++	0x06, 0xA0, 0x50, 0xFC, 0x82,
++	0x08, 0x4C, 0xB3, 0xD9, 0x11,
++	0x0B, 0x9B, 0x00, 0xEC, 0xD8,
++	0x05, 0x08, 0xC9, 0xBD, 0xF0,
++	0x0F, 0x20, 0x96, 0x6D, 0x27,
++	0x05, 0x58, 0x49, 0x12, 0x2D,
++	0x05, 0x4E, 0x24, 0x06, 0x91,
++	0x0E, 0xE2, 0x6B, 0x6F, 0x4C,
++	0x04, 0xA2, 0xE1, 0xFE, 0xF0,
++	0x0D, 0xF9, 0x35, 0x3D, 0x7A,
++	0x06, 0xA4, 0x70, 0xFA, 0x2D,
++	0x09, 0x96, 0x7E, 0x3B, 0x99,
++	0x0F, 0x5F, 0xC6, 0xD9, 0x95,
++	0x0A, 0xA2, 0x4F, 0x77, 0x01,
++	0x01, 0x24, 0x15, 0x22, 0x7A,
++	0x08, 0x5E, 0xD9, 0xAF, 0xA5,
++	0x05, 0xF7, 0x40, 0xE2, 0xE7,
++	0x08, 0xA8, 0x1A, 0x3C, 0x39,
++	0x0D, 0x6A, 0x38, 0xDA, 0xAF,
++	0x04, 0xB7, 0xF8, 0x23, 0x30,
++	0x0A, 0xB0, 0xDE, 0x9F, 0x4C,
++	0x0B, 0x34, 0x1D, 0x9C, 0x1B,
++	0x0B, 0xEC, 0x86, 0x03, 0xD9,
++	0x06, 0x97, 0xF4, 0x58, 0xEB,
++	0x05, 0x59, 0x17, 0x45, 0x6D,
++	0x0B, 0x05, 0xAF, 0xAA, 0x81,
++	0x0A, 0xF2, 0xEE, 0x03, 0xC1,
++	0x0F, 0x5D, 0x44, 0x86, 0x70,
++	0x06, 0xB3, 0x43, 0xBC, 0x3F,
++	0x0C, 0xF7, 0xC7, 0xCC, 0xBB,
++	0x0B, 0xB4, 0x7B, 0xF3, 0x62,
++	0x0C, 0x71, 0xB5, 0x71, 0x31,
++	0x09, 0x08, 0x86, 0x11, 0x15,
++	0x08, 0x3F, 0x77, 0x2C, 0xC5,
++	0x03, 0xFC, 0x60, 0xB7, 0xF4,
++	0x08, 0xF4, 0x06, 0x32, 0x9A,
++	0x06, 0xE9, 0x71, 0xD6, 0x99,
++	0x0F, 0xD1, 0x7F, 0x5B, 0x4F,
++	0x0B, 0x5F, 0x55, 0x06, 0x08,
++	0x0C, 0xDC, 0xCE, 0x7A, 0xDE,
++	0x03, 0x8F, 0xCC, 0xE1, 0xBB,
++	0x06, 0x87, 0x78, 0x7F, 0xC1,
++	0x06, 0xA3, 0x59, 0x00, 0x27,
++	0x08, 0xF3, 0xE6, 0xCB, 0x41,
++	0x03, 0x6A, 0xE2, 0x66, 0xAA,
++	0x00, 0x8C, 0x25, 0x2A, 0xC3,
++	0x01, 0x6E, 0x45, 0x0A, 0xD3,
++	0x0E, 0x49, 0x6D, 0xC9, 0xA9,
++	0x00, 0x0C, 0x64, 0x9A, 0x5F,
++	0x09, 0x63, 0xAC, 0xB3, 0xC7,
++	0x05, 0x86, 0x15, 0x6E, 0x96,
++	0x0E, 0xAA, 0x05, 0xAB, 0xCB,
++	0x08, 0x1C, 0xEA, 0x3F, 0xFF,
++	0x02, 0x19, 0xC2, 0x76, 0xCD,
++	0x0E, 0xF0, 0xFC, 0x81, 0x55,
++	0x07, 0x32, 0x09, 0xCE, 0xD1,
++	0x07, 0xCD, 0x89, 0x13, 0x4C,
++	0x05, 0xC4, 0xC6, 0x44, 0x2B,
++	0x03, 0x4E, 0x55, 0x86, 0xF4,
++	0x04, 0x8A, 0x95, 0xA9, 0x2C,
++	0x09, 0x58, 0xD6, 0x53, 0x30,
++	0x00, 0xCA, 0x36, 0xBF, 0xA2,
++	0x0F, 0x59, 0xE6, 0x81, 0xFA,
++	0x05, 0x6D, 0xDA, 0x2D, 0x7D,
++	0x0F, 0x8D, 0x12, 0x93, 0x0B,
++	0x01, 0xD2, 0x7A, 0xEE, 0x5D,
++	0x08, 0x85, 0xED, 0x9A, 0x1D,
++	0x01, 0xFF, 0x01, 0xBE, 0xEA,
++	0x04, 0x12, 0x9D, 0xA3, 0xCF,
++	0x0B, 0x15, 0x27, 0x8D, 0x6F,
++	0x09, 0x88, 0x80, 0x42, 0x30,
++	0x0C, 0xAB, 0x0D, 0x69, 0x33,
++	0x04, 0x2B, 0x4F, 0xD9, 0x25,
++	0x0F, 0x26, 0xA2, 0xE0, 0xBB,
++	0x04, 0x69, 0x7F, 0x65, 0x4B,
++	0x02, 0xCF, 0x1F, 0x74, 0xDF,
++	0x0B, 0xB0, 0x5A, 0xFA, 0xA8,
++	0x04, 0xAF, 0x2E, 0xE0, 0x73,
++	0x04, 0xF5, 0xD4, 0xC8, 0xED,
++	0x0B, 0xDB, 0x36, 0x1B, 0x49,
++	0x05, 0x0F, 0x7C, 0x5C, 0xC8,
++	0x0D, 0x3B, 0x47, 0x9F, 0x36,
++	0x06, 0x46, 0x5F, 0x57, 0x0E,
++	0x0B, 0xC0, 0x96, 0xEF, 0x96,
++	0x0E, 0x1B, 0xD7, 0x72, 0xE8,
++	0x0A, 0x9E, 0x0A, 0x8B, 0x63,
++	0x07, 0x8C, 0xC9, 0x6D, 0x9A,
++	0x0A, 0xFE, 0x8F, 0x1D, 0xA5,
++	0x02, 0x3F, 0x2A, 0x75, 0xAA,
++	0x0A, 0x75, 0xFC, 0x5E, 0x9C,
++	0x06, 0x5D, 0xC4, 0xE7, 0x89,
++	0x07, 0xA8, 0xB5, 0x8E, 0x0A,
++	0x0C, 0xA8, 0x61, 0x09, 0x44,
++	0x06, 0xF8, 0xBD, 0x90, 0x8A,
++	0x0A, 0x8F, 0x4E, 0x2C, 0x49,
++	0x04, 0xF6, 0xB8, 0xA8, 0x99,
++	0x09, 0x08, 0xC6, 0x72, 0x6C,
++	0x0B, 0xA6, 0x66, 0x50, 0xB0,
++	0x05, 0xA4, 0x80, 0x72, 0x24,
++	0x01, 0x80, 0xC2, 0x51, 0x65,
++	0x01, 0x16, 0xA3, 0xCB, 0x21,
++	0x07, 0x10, 0x7D, 0xE0, 0x00,
++	0x03, 0xEA, 0xA4, 0x52, 0x7C,
++	0x00, 0x81, 0xCE, 0x93, 0xD7,
++};
++
++static u8 ak7755_cram_aec[]= {
++	0xB4, 0x00, 0x00,    // CRAM Write Command  
++	0x7F, 0xFF, 0xF0,
++	0x7F, 0xF6, 0x20,
++	0x7F, 0xD8, 0x80,
++	0x7F, 0xA7, 0x30,
++	0x7F, 0x62, 0x30,
++	0x7F, 0x09, 0x90,
++	0x7E, 0x9D, 0x50,
++	0x7E, 0x1D, 0x90,
++	0x7D, 0x8A, 0x60,
++	0x7C, 0xE3, 0xD0,
++	0x7C, 0x2A, 0x00,
++	0x7B, 0x5D, 0x00,
++	0x7A, 0x7D, 0x00,
++	0x79, 0x8A, 0x20,
++	0x78, 0x84, 0x80,
++	0x77, 0x6C, 0x50,
++	0x76, 0x41, 0xB0,
++	0x75, 0x04, 0xD0,
++	0x73, 0xB5, 0xF0,
++	0x72, 0x55, 0x30,
++	0x70, 0xE2, 0xD0,
++	0x6F, 0x5F, 0x00,
++	0x6D, 0xCA, 0x10,
++	0x6C, 0x24, 0x30,
++	0x6A, 0x6D, 0xA0,
++	0x68, 0xA6, 0xA0,
++	0x66, 0xCF, 0x80,
++	0x64, 0xE8, 0x90,
++	0x62, 0xF2, 0x00,
++	0x60, 0xEC, 0x40,
++	0x5E, 0xD7, 0x80,
++	0x5C, 0xB4, 0x20,
++	0x5A, 0x82, 0x80,
++	0x58, 0x42, 0xE0,
++	0x55, 0xF5, 0xA0,
++	0x53, 0x9B, 0x30,
++	0x51, 0x33, 0xD0,
++	0x4E, 0xBF, 0xF0,
++	0x4C, 0x3F, 0xE0,
++	0x49, 0xB4, 0x10,
++	0x47, 0x1C, 0xF0,
++	0x44, 0x7A, 0xD0,
++	0x41, 0xCE, 0x20,
++	0x3F, 0x17, 0x50,
++	0x3C, 0x56, 0xC0,
++	0x39, 0x8C, 0xE0,
++	0x36, 0xBA, 0x20,
++	0x33, 0xDE, 0xF0,
++	0x30, 0xFB, 0xC0,
++	0x2E, 0x11, 0x10,
++	0x2B, 0x1F, 0x30,
++	0x28, 0x26, 0xC0,
++	0x25, 0x28, 0x10,
++	0x22, 0x23, 0xA0,
++	0x1F, 0x1A, 0x00,
++	0x1C, 0x0B, 0x80,
++	0x18, 0xF8, 0xC0,
++	0x15, 0xE2, 0x10,
++	0x12, 0xC8, 0x10,
++	0x0F, 0xAB, 0x20,
++	0x0C, 0x8B, 0xD0,
++	0x09, 0x6A, 0x90,
++	0x06, 0x47, 0xE0,
++	0x03, 0x24, 0x30,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x14, 0x00,
++	0xF0, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0x87, 0x50,
++	0xFE, 0x8C, 0x50,
++	0xFD, 0xE9, 0x70,
++	0x00, 0x00, 0x00,
++	0x06, 0xD8, 0xD0,
++	0x11, 0x8D, 0x30,
++	0x1B, 0xAE, 0x90,
++	0x1F, 0xDC, 0xD0,
++	0x1B, 0xAE, 0x90,
++	0x11, 0x8D, 0x30,
++	0x06, 0xD8, 0xD0,
++	0x00, 0x00, 0x00,
++	0xFD, 0xE9, 0x70,
++	0xFE, 0x8C, 0x50,
++	0xFF, 0x87, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x18, 0x00,
++	0x07, 0x87, 0x80,
++	0x78, 0x78, 0x80,
++	0x00, 0x19, 0x00,
++	0x45, 0xD9, 0xB0,
++	0x3A, 0x26, 0x50,
++	0x00, 0x1A, 0x00,
++	0x05, 0x4A, 0x20,
++	0x7A, 0xB5, 0xE0,
++	0x00, 0x1D, 0x00,
++	0x52, 0xF8, 0x20,
++	0x2D, 0x07, 0xE0,
++	0x00, 0x20, 0x00,
++	0x43, 0xC3, 0xC0,
++	0x3C, 0x3C, 0x40,
++	0x00, 0x24, 0x00,
++	0x72, 0xE1, 0xA0,
++	0x0D, 0x1E, 0x60,
++	0x00, 0x28, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x2B, 0x00,
++	0x0D, 0x1E, 0x60,
++	0x72, 0xE1, 0xA0,
++	0x00, 0x2F, 0x00,
++	0x3C, 0x3C, 0x40,
++	0x43, 0xC3, 0xC0,
++	0x00, 0x32, 0x00,
++	0x2D, 0x07, 0xE0,
++	0x52, 0xF8, 0x20,
++	0x00, 0x35, 0x00,
++	0x7A, 0xB5, 0xE0,
++	0x05, 0x4A, 0x20,
++	0x00, 0x36, 0x00,
++	0x3A, 0x26, 0x50,
++	0x45, 0xD9, 0xB0,
++	0x00, 0x37, 0x00,
++	0x78, 0x78, 0x80,
++	0x07, 0x87, 0x80,
++	0x20, 0x00, 0x00,
++	0x06, 0x66, 0x60,
++	0x00, 0x00, 0x00,
++	0x00, 0x0A, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0xC2, 0x00,
++	0x00, 0x00, 0x10,
++	0x01, 0x50, 0x20,
++	0x03, 0x00, 0x30,
++	0x04, 0x50, 0x40,
++	0x06, 0x00, 0x50,
++	0x07, 0x50, 0x60,
++	0x09, 0x00, 0x70,
++	0x10, 0x50, 0x80,
++	0x12, 0x00, 0x90,
++	0x13, 0x50, 0xA0,
++	0x15, 0x00, 0xB0,
++	0x16, 0x50, 0xC0,
++	0x18, 0x00, 0xD0,
++	0x19, 0x50, 0xE0,
++	0x21, 0x00, 0xF0,
++	0x22, 0x51, 0x00,
++	0x24, 0x01, 0x10,
++	0x25, 0x51, 0x20,
++	0x27, 0x01, 0x30,
++	0x28, 0x51, 0x40,
++	0x30, 0x01, 0x50,
++	0x31, 0x51, 0x60,
++	0x33, 0x01, 0x70,
++	0x34, 0x51, 0x80,
++	0x36, 0x01, 0x90,
++	0x01, 0x50, 0x20,
++	0x03, 0x00, 0x30,
++	0x00, 0x00, 0x00,
++	0x00, 0x10, 0x00,
++	0x00, 0x20, 0x00,
++	0x00, 0x40, 0x00,
++	0x00, 0x60, 0x00,
++	0x00, 0x7F, 0x00,
++	0x00, 0x00, 0x00,
++	0x02, 0x87, 0xA0,
++	0x00, 0xCC, 0xD0,
++	0x00, 0x40, 0xC0,
++	0x00, 0x14, 0x80,
++	0x00, 0xCC, 0xD0,
++	0x00, 0x00, 0x00,
++	0x00, 0x07, 0x40,
++	0x00, 0x1C, 0x20,
++	0x00, 0x29, 0xE0,
++	0x00, 0x06, 0x20,
++	0xFF, 0xB7, 0x40,
++	0xFF, 0x96, 0x70,
++	0xFF, 0xDC, 0x30,
++	0x00, 0x29, 0x10,
++	0x00, 0x00, 0x80,
++	0xFF, 0xA9, 0xB0,
++	0xFF, 0xD3, 0x90,
++	0x00, 0x4E, 0xA0,
++	0x00, 0x34, 0xB0,
++	0xFF, 0x99, 0x10,
++	0xFF, 0xA4, 0x60,
++	0x00, 0x6C, 0xF0,
++	0x00, 0x7D, 0xA0,
++	0xFF, 0x85, 0xC0,
++	0xFF, 0x50, 0x20,
++	0x00, 0x7E, 0x50,
++	0x00, 0xE7, 0xD0,
++	0xFF, 0x7F, 0xF0,
++	0xFE, 0xD3, 0x60,
++	0x00, 0x78, 0xE0,
++	0x01, 0x7B, 0xF0,
++	0xFF, 0x96, 0xC0,
++	0xFE, 0x27, 0x10,
++	0x00, 0x4D, 0x20,
++	0x02, 0x44, 0x30,
++	0xFF, 0xDD, 0xD0,
++	0xFD, 0x3F, 0x70,
++	0xFF, 0xE3, 0xD0,
++	0x03, 0x51, 0x40,
++	0x00, 0x73, 0x80,
++	0xFC, 0x04, 0x30,
++	0xFF, 0x13, 0xD0,
++	0x04, 0xC9, 0x20,
++	0x01, 0x93, 0x50,
++	0xFA, 0x37, 0x10,
++	0xFD, 0x80, 0x50,
++	0x07, 0x18, 0xF0,
++	0x03, 0xDC, 0xF0,
++	0xF7, 0x08, 0x60,
++	0xF9, 0xF4, 0x10,
++	0x0C, 0x00, 0x30,
++	0x0A, 0x1A, 0x30,
++	0xED, 0xCD, 0x40,
++	0xEB, 0x8C, 0x30,
++	0x28, 0x40, 0xF0,
++	0x70, 0x4E, 0x60,
++	0x70, 0x4E, 0x60,
++	0x28, 0x40, 0xF0,
++	0xEB, 0x8C, 0x30,
++	0xED, 0xCD, 0x40,
++	0x0A, 0x1A, 0x30,
++	0x0C, 0x00, 0x30,
++	0xF9, 0xF4, 0x10,
++	0xF7, 0x08, 0x60,
++	0x03, 0xDC, 0xF0,
++	0x07, 0x18, 0xF0,
++	0xFD, 0x80, 0x50,
++	0xFA, 0x37, 0x10,
++	0x01, 0x93, 0x50,
++	0x04, 0xC9, 0x20,
++	0xFF, 0x13, 0xD0,
++	0xFC, 0x04, 0x30,
++	0x00, 0x73, 0x80,
++	0x03, 0x51, 0x40,
++	0xFF, 0xE3, 0xD0,
++	0xFD, 0x3F, 0x70,
++	0xFF, 0xDD, 0xD0,
++	0x02, 0x44, 0x30,
++	0x00, 0x4D, 0x20,
++	0xFE, 0x27, 0x10,
++	0xFF, 0x96, 0xC0,
++	0x01, 0x7B, 0xF0,
++	0x00, 0x78, 0xE0,
++	0xFE, 0xD3, 0x60,
++	0xFF, 0x7F, 0xF0,
++	0x00, 0xE7, 0xD0,
++	0x00, 0x7E, 0x50,
++	0xFF, 0x50, 0x20,
++	0xFF, 0x85, 0xC0,
++	0x00, 0x7D, 0xA0,
++	0x00, 0x6C, 0xF0,
++	0xFF, 0xA4, 0x60,
++	0xFF, 0x99, 0x10,
++	0x00, 0x34, 0xB0,
++	0x00, 0x4E, 0xA0,
++	0xFF, 0xD3, 0x90,
++	0xFF, 0xA9, 0xB0,
++	0x00, 0x00, 0x80,
++	0x00, 0x29, 0x10,
++	0xFF, 0xDC, 0x30,
++	0xFF, 0x96, 0x70,
++	0xFF, 0xB7, 0x40,
++	0x00, 0x06, 0x20,
++	0x00, 0x29, 0xE0,
++	0x00, 0x1C, 0x20,
++	0x00, 0x07, 0x40,
++	0x00, 0x00, 0x00,
++	0xFF, 0xFD, 0x60,
++	0xFF, 0xF9, 0x60,
++	0xFF, 0xFD, 0x40,
++	0x00, 0x0A, 0x90,
++	0x00, 0x0C, 0x80,
++	0xFF, 0xF8, 0x00,
++	0xFF, 0xEF, 0x60,
++	0x00, 0x0D, 0xB0,
++	0x00, 0x1F, 0xE0,
++	0xFF, 0xF3, 0x50,
++	0xFF, 0xD0, 0xC0,
++	0x00, 0x0E, 0x40,
++	0x00, 0x48, 0x10,
++	0xFF, 0xF5, 0x80,
++	0xFF, 0x9A, 0x50,
++	0x00, 0x05, 0x20,
++	0x00, 0x8D, 0x90,
++	0x00, 0x06, 0xB0,
++	0xFF, 0x41, 0xD0,
++	0xFF, 0xE7, 0xB0,
++	0x00, 0xFB, 0x20,
++	0x00, 0x33, 0x80,
++	0xFE, 0xBB, 0x40,
++	0xFF, 0xA6, 0x60,
++	0x01, 0x9E, 0x30,
++	0x00, 0x8E, 0xD0,
++	0xFD, 0xF6, 0x70,
++	0xFF, 0x29, 0x50,
++	0x02, 0x8B, 0x40,
++	0x01, 0x37, 0x70,
++	0xFC, 0xD7, 0x60,
++	0xFE, 0x46, 0xE0,
++	0x03, 0xEB, 0x30,
++	0x02, 0x69, 0x50,
++	0xFB, 0x1D, 0x40,
++	0xFC, 0xA1, 0x60,
++	0x06, 0x2D, 0x70,
++	0x04, 0xC5, 0x00,
++	0xF7, 0xF6, 0x20,
++	0xF9, 0x02, 0x40,
++	0x0B, 0x14, 0x00,
++	0x0B, 0x17, 0xC0,
++	0xEE, 0xB1, 0x80,
++	0xEA, 0x7B, 0x10,
++	0x27, 0x7C, 0x40,
++	0x71, 0xE1, 0xE0,
++	0x71, 0xE1, 0xE0,
++	0x27, 0x7C, 0x40,
++	0xEA, 0x7B, 0x10,
++	0xEE, 0xB1, 0x80,
++	0x0B, 0x17, 0xC0,
++	0x0B, 0x14, 0x00,
++	0xF9, 0x02, 0x40,
++	0xF7, 0xF6, 0x20,
++	0x04, 0xC5, 0x00,
++	0x06, 0x2D, 0x70,
++	0xFC, 0xA1, 0x60,
++	0xFB, 0x1D, 0x40,
++	0x02, 0x69, 0x50,
++	0x03, 0xEB, 0x30,
++	0xFE, 0x46, 0xE0,
++	0xFC, 0xD7, 0x60,
++	0x01, 0x37, 0x70,
++	0x02, 0x8B, 0x40,
++	0xFF, 0x29, 0x50,
++	0xFD, 0xF6, 0x70,
++	0x00, 0x8E, 0xD0,
++	0x01, 0x9E, 0x30,
++	0xFF, 0xA6, 0x60,
++	0xFE, 0xBB, 0x40,
++	0x00, 0x33, 0x80,
++	0x00, 0xFB, 0x20,
++	0xFF, 0xE7, 0xB0,
++	0xFF, 0x41, 0xD0,
++	0x00, 0x06, 0xB0,
++	0x00, 0x8D, 0x90,
++	0x00, 0x05, 0x20,
++	0xFF, 0x9A, 0x50,
++	0xFF, 0xF5, 0x80,
++	0x00, 0x48, 0x10,
++	0x00, 0x0E, 0x40,
++	0xFF, 0xD0, 0xC0,
++	0xFF, 0xF3, 0x50,
++	0x00, 0x1F, 0xE0,
++	0x00, 0x0D, 0xB0,
++	0xFF, 0xEF, 0x60,
++	0xFF, 0xF8, 0x00,
++	0x00, 0x0C, 0x80,
++	0x00, 0x0A, 0x90,
++	0xFF, 0xFD, 0x40,
++	0xFF, 0xF9, 0x60,
++	0xFF, 0xFD, 0x60,
++	0x00, 0x00, 0x00,
++	0x00, 0x14, 0x00,
++	0xF0, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0x87, 0x50,
++	0xFE, 0x8C, 0x50,
++	0xFD, 0xE9, 0x70,
++	0x00, 0x00, 0x00,
++	0x06, 0xD8, 0xD0,
++	0x11, 0x8D, 0x30,
++	0x1B, 0xAE, 0x90,
++	0x1F, 0xDC, 0xD0,
++	0x1B, 0xAE, 0x90,
++	0x11, 0x8D, 0x30,
++	0x06, 0xD8, 0xD0,
++	0x00, 0x00, 0x00,
++	0xFD, 0xE9, 0x70,
++	0xFE, 0x8C, 0x50,
++	0xFF, 0x87, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x18, 0x00,
++	0x07, 0x87, 0x80,
++	0x78, 0x78, 0x80,
++	0x00, 0x19, 0x00,
++	0x45, 0xD9, 0xB0,
++	0x3A, 0x26, 0x50,
++	0x00, 0x1A, 0x00,
++	0x05, 0x4A, 0x20,
++	0x7A, 0xB5, 0xE0,
++	0x00, 0x1D, 0x00,
++	0x52, 0xF8, 0x20,
++	0x2D, 0x07, 0xE0,
++	0x00, 0x20, 0x00,
++	0x43, 0xC3, 0xC0,
++	0x3C, 0x3C, 0x40,
++	0x00, 0x24, 0x00,
++	0x72, 0xE1, 0xA0,
++	0x0D, 0x1E, 0x60,
++	0x00, 0x28, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x2B, 0x00,
++	0x0D, 0x1E, 0x60,
++	0x72, 0xE1, 0xA0,
++	0x00, 0x2F, 0x00,
++	0x3C, 0x3C, 0x40,
++	0x43, 0xC3, 0xC0,
++	0x00, 0x32, 0x00,
++	0x2D, 0x07, 0xE0,
++	0x52, 0xF8, 0x20,
++	0x00, 0x35, 0x00,
++	0x7A, 0xB5, 0xE0,
++	0x05, 0x4A, 0x20,
++	0x00, 0x36, 0x00,
++	0x3A, 0x26, 0x50,
++	0x45, 0xD9, 0xB0,
++	0x00, 0x37, 0x00,
++	0x78, 0x78, 0x80,
++	0x07, 0x87, 0x80,
++	0x20, 0x00, 0x00,
++	0x06, 0x66, 0x60,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0xC8, 0x00, 0x00,
++	0xEB, 0xD8, 0x60,
++	0x42, 0xCD, 0xA0,
++	0xA2, 0x68, 0x10,
++	0x62, 0xB9, 0xF0,
++	0x0C, 0x35, 0x90,
++	0x00, 0x00, 0x00,
++	0x00, 0x14, 0x00,
++	0xF0, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0x87, 0x50,
++	0xFE, 0x8C, 0x50,
++	0xFD, 0xE9, 0x70,
++	0x00, 0x00, 0x00,
++	0x06, 0xD8, 0xD0,
++	0x11, 0x8D, 0x30,
++	0x1B, 0xAE, 0x90,
++	0x1F, 0xDC, 0xD0,
++	0x1B, 0xAE, 0x90,
++	0x11, 0x8D, 0x30,
++	0x06, 0xD8, 0xD0,
++	0x00, 0x00, 0x00,
++	0xFD, 0xE9, 0x70,
++	0xFE, 0x8C, 0x50,
++	0xFF, 0x87, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x18, 0x00,
++	0x07, 0x87, 0x80,
++	0x78, 0x78, 0x80,
++	0x00, 0x19, 0x00,
++	0x6A, 0x3E, 0xF0,
++	0x15, 0xC1, 0x10,
++	0x00, 0x1F, 0x00,
++	0x51, 0x95, 0xE0,
++	0x2E, 0x6A, 0x20,
++	0x00, 0x22, 0x00,
++	0x13, 0x41, 0x00,
++	0x6C, 0xBF, 0x00,
++	0x00, 0x26, 0x00,
++	0x27, 0xFE, 0xD0,
++	0x58, 0x01, 0x30,
++	0x00, 0x2A, 0x00,
++	0x31, 0x49, 0xC0,
++	0x4E, 0xB6, 0x40,
++	0x00, 0x2E, 0x00,
++	0x51, 0x64, 0x10,
++	0x2E, 0x9B, 0xF0,
++	0x00, 0x31, 0x00,
++	0x29, 0x02, 0x10,
++	0x56, 0xFD, 0xF0,
++	0x00, 0x33, 0x00,
++	0x3B, 0x6D, 0x40,
++	0x44, 0x92, 0xC0,
++	0x00, 0x35, 0x00,
++	0x7A, 0xB5, 0xE0,
++	0x05, 0x4A, 0x20,
++	0x00, 0x36, 0x00,
++	0x6C, 0xB7, 0x00,
++	0x13, 0x49, 0x00,
++	0x00, 0x36, 0x00,
++	0x15, 0xC1, 0x10,
++	0x6A, 0x3E, 0xF0,
++	0x00, 0x37, 0x00,
++	0x78, 0x78, 0x80,
++	0x07, 0x87, 0x80,
++	0x20, 0x00, 0x00,
++	0x06, 0x66, 0x60,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x02, 0x33, 0x00,
++	0x01, 0x50, 0x10,
++	0x00, 0x00, 0x20,
++	0x01, 0x50, 0x30,
++	0x03, 0x00, 0x40,
++	0x04, 0x50, 0x50,
++	0x06, 0x00, 0x60,
++	0x07, 0x50, 0x70,
++	0x09, 0x00, 0x80,
++	0x10, 0x50, 0x90,
++	0x12, 0x00, 0xA0,
++	0x13, 0x50, 0xB0,
++	0x15, 0x00, 0xC0,
++	0x16, 0x50, 0xD0,
++	0x18, 0x00, 0xD0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x14, 0x00,
++	0xF0, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0x87, 0x50,
++	0xFE, 0x8C, 0x50,
++	0xFD, 0xE9, 0x70,
++	0x00, 0x00, 0x00,
++	0x06, 0xD8, 0xD0,
++	0x11, 0x8D, 0x30,
++	0x1B, 0xAE, 0x90,
++	0x1F, 0xDC, 0xD0,
++	0x1B, 0xAE, 0x90,
++	0x11, 0x8D, 0x30,
++	0x06, 0xD8, 0xD0,
++	0x00, 0x00, 0x00,
++	0xFD, 0xE9, 0x70,
++	0xFE, 0x8C, 0x50,
++	0xFF, 0x87, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x18, 0x00,
++	0x07, 0x87, 0x80,
++	0x78, 0x78, 0x80,
++	0x00, 0x19, 0x00,
++	0x45, 0xD9, 0xB0,
++	0x3A, 0x26, 0x50,
++	0x00, 0x1A, 0x00,
++	0x05, 0x4A, 0x20,
++	0x7A, 0xB5, 0xE0,
++	0x00, 0x1D, 0x00,
++	0x52, 0xF8, 0x20,
++	0x2D, 0x07, 0xE0,
++	0x00, 0x20, 0x00,
++	0x43, 0xC3, 0xC0,
++	0x3C, 0x3C, 0x40,
++	0x00, 0x24, 0x00,
++	0x72, 0xE1, 0xA0,
++	0x0D, 0x1E, 0x60,
++	0x00, 0x28, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x2B, 0x00,
++	0x0D, 0x1E, 0x60,
++	0x72, 0xE1, 0xA0,
++	0x00, 0x2F, 0x00,
++	0x3C, 0x3C, 0x40,
++	0x43, 0xC3, 0xC0,
++	0x00, 0x32, 0x00,
++	0x2D, 0x07, 0xE0,
++	0x52, 0xF8, 0x20,
++	0x00, 0x35, 0x00,
++	0x7A, 0xB5, 0xE0,
++	0x05, 0x4A, 0x20,
++	0x00, 0x36, 0x00,
++	0x3A, 0x26, 0x50,
++	0x45, 0xD9, 0xB0,
++	0x00, 0x37, 0x00,
++	0x78, 0x78, 0x80,
++	0x07, 0x87, 0x80,
++	0x20, 0x00, 0x00,
++	0x06, 0x66, 0x60,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0xC9, 0x10,
++	0x02, 0x5B, 0x20,
++	0x03, 0xED, 0x20,
++	0x05, 0x7F, 0x00,
++	0x07, 0x10, 0xA0,
++	0x08, 0xA2, 0x00,
++	0x0A, 0x33, 0x10,
++	0x0B, 0xC3, 0xB0,
++	0x0D, 0x53, 0xE0,
++	0x0E, 0xE3, 0x80,
++	0x10, 0x72, 0xA0,
++	0x12, 0x01, 0x10,
++	0x13, 0x8E, 0xE0,
++	0x15, 0x1B, 0xE0,
++	0x16, 0xA8, 0x10,
++	0x18, 0x33, 0x60,
++	0x19, 0xBD, 0xD0,
++	0x1B, 0x47, 0x30,
++	0x1C, 0xCF, 0x90,
++	0x1E, 0x56, 0xD0,
++	0x1F, 0xDC, 0xE0,
++	0x21, 0x61, 0xB0,
++	0x22, 0xE5, 0x40,
++	0x24, 0x67, 0x70,
++	0x25, 0xE8, 0x40,
++	0x27, 0x67, 0xA0,
++	0x28, 0xE5, 0x70,
++	0x2A, 0x61, 0xB0,
++	0x2B, 0xDC, 0x50,
++	0x2D, 0x55, 0x40,
++	0x2E, 0xCC, 0x70,
++	0x30, 0x41, 0xC0,
++	0x31, 0xB5, 0x50,
++	0x33, 0x26, 0xE0,
++	0x34, 0x96, 0x80,
++	0x36, 0x04, 0x20,
++	0x37, 0x6F, 0xA0,
++	0x38, 0xD9, 0x00,
++	0x3A, 0x40, 0x30,
++	0x3B, 0xA5, 0x20,
++	0x3D, 0x07, 0xC0,
++	0x3E, 0x68, 0x10,
++	0x3F, 0xC5, 0xF0,
++	0x41, 0x21, 0x60,
++	0x42, 0x7A, 0x40,
++	0x43, 0xD0, 0xA0,
++	0x45, 0x24, 0x50,
++	0x46, 0x75, 0x70,
++	0x47, 0xC3, 0xC0,
++	0x49, 0x0F, 0x50,
++	0x4A, 0x58, 0x20,
++	0x4B, 0x9E, 0x00,
++	0x4C, 0xE1, 0x00,
++	0x4E, 0x21, 0x00,
++	0x4F, 0x5E, 0x10,
++	0x50, 0x98, 0x00,
++	0x51, 0xCE, 0xD0,
++	0x53, 0x02, 0x80,
++	0x54, 0x33, 0x00,
++	0x55, 0x60, 0x40,
++	0x56, 0x8A, 0x30,
++	0x57, 0xB0, 0xD0,
++	0x58, 0xD4, 0x10,
++	0x59, 0xF3, 0xE0,
++	0x5B, 0x10, 0x30,
++	0x5C, 0x29, 0x10,
++	0x5D, 0x3E, 0x50,
++	0x5E, 0x50, 0x00,
++	0x5F, 0x5E, 0x10,
++	0x60, 0x68, 0x70,
++	0x61, 0x6F, 0x10,
++	0x62, 0x72, 0x00,
++	0x63, 0x71, 0x10,
++	0x64, 0x6C, 0x60,
++	0x65, 0x63, 0xC0,
++	0x66, 0x57, 0x40,
++	0x67, 0x46, 0xC0,
++	0x68, 0x32, 0x50,
++	0x69, 0x19, 0xE0,
++	0x69, 0xFD, 0x60,
++	0x6A, 0xDC, 0xD0,
++	0x6B, 0xB8, 0x10,
++	0x6C, 0x8F, 0x30,
++	0x6D, 0x62, 0x20,
++	0x6E, 0x30, 0xE0,
++	0x6E, 0xFB, 0x60,
++	0x6F, 0xC1, 0x90,
++	0x70, 0x83, 0x80,
++	0x71, 0x41, 0x10,
++	0x71, 0xFA, 0x40,
++	0x72, 0xAF, 0x00,
++	0x73, 0x5F, 0x60,
++	0x74, 0x0B, 0x50,
++	0x74, 0xB2, 0xD0,
++	0x75, 0x55, 0xC0,
++	0x75, 0xF4, 0x30,
++	0x76, 0x8E, 0x10,
++	0x77, 0x23, 0x60,
++	0x77, 0xB4, 0x10,
++	0x78, 0x40, 0x30,
++	0x78, 0xC7, 0xB0,
++	0x79, 0x4A, 0x80,
++	0x79, 0xC8, 0xA0,
++	0x7A, 0x42, 0x10,
++	0x7A, 0xB6, 0xD0,
++	0x7B, 0x26, 0xD0,
++	0x7B, 0x92, 0x10,
++	0x7B, 0xF8, 0x90,
++	0x7C, 0x5A, 0x40,
++	0x7C, 0xB7, 0x20,
++	0x7D, 0x0F, 0x40,
++	0x7D, 0x62, 0x90,
++	0x7D, 0xB1, 0x00,
++	0x7D, 0xFA, 0xA0,
++	0x7E, 0x3F, 0x50,
++	0x7E, 0x7F, 0x40,
++	0x7E, 0xBA, 0x40,
++	0x7E, 0xF0, 0x60,
++	0x7F, 0x21, 0x90,
++	0x7F, 0x4D, 0xE0,
++	0x7F, 0x75, 0x50,
++	0x7F, 0x97, 0xD0,
++	0x7F, 0xB5, 0x60,
++	0x7F, 0xCE, 0x10,
++	0x7F, 0xE1, 0xC0,
++	0x7F, 0xF0, 0x90,
++	0x7F, 0xFA, 0x70,
++	0x7F, 0xFF, 0x60,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x03, 0x00,
++	0x03, 0x46, 0xE0,
++	0x00, 0xBE, 0x00,
++	0x02, 0x0C, 0x50,
++	0x20, 0x00, 0x00,
++	0x14, 0x00, 0x00,
++	0x00, 0x0C, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x00, 0x51, 0xF0,
++	0x04, 0x00, 0x00,
++	0x00, 0x41, 0x90,
++	0x01, 0x47, 0xB0,
++	0x7E, 0xB8, 0x50,
++	0x7B, 0xC0, 0x00,
++	0x38, 0x00, 0x00,
++	0x0C, 0xCC, 0xD0,
++	0x01, 0x47, 0xB0,
++	0x06, 0x66, 0x60,
++	0x06, 0x66, 0x60,
++	0xF5, 0xFF, 0xF0,
++	0x20, 0x00, 0x00,
++	0x00, 0x28, 0xF0,
++	0x00, 0x28, 0x00,
++	0x01, 0x47, 0xB0,
++	0x0F, 0x5C, 0x30,
++	0x00, 0x51, 0xF0,
++	0xF7, 0x45, 0xD0,
++	0x00, 0x00, 0x00,
++	0x00, 0x28, 0xF0,
++	0x00, 0x16, 0x00,
++	0x01, 0x47, 0xB0,
++	0x0C, 0xCC, 0xD0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x28, 0xF0,
++	0x00, 0x42, 0x00,
++	0x2B, 0x85, 0x20,
++	0x14, 0x7A, 0xE0,
++	0x0C, 0xCC, 0xD0,
++	0x08, 0xF5, 0xC0,
++	0x05, 0x1E, 0xC0,
++	0x02, 0x8F, 0x60,
++	0x08, 0x00, 0x00,
++	0x00, 0x90, 0x00,
++	0x00, 0x00, 0x00,
++	0xC8, 0x00, 0x00,
++	0x5A, 0x9D, 0xF0,
++	0x06, 0x66, 0x00,
++	0x13, 0x33, 0x00,
++	0x13, 0x33, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x0D, 0x1B, 0x40,
++	0x1A, 0x36, 0x80,
++	0xC9, 0xD2, 0x70,
++	0x75, 0x5B, 0xE0,
++	0x0D, 0x1B, 0x40,
++	0x0D, 0x1B, 0x40,
++	0x1A, 0x36, 0x80,
++	0xC9, 0xD2, 0x70,
++	0x75, 0x5B, 0xE0,
++	0x0D, 0x1B, 0x40,
++	0x3C, 0x8A, 0xE0,
++	0x86, 0xEA, 0x40,
++	0xC6, 0xBA, 0x60,
++	0x78, 0xE5, 0xF0,
++	0x3C, 0x8A, 0xE0,
++	0x18, 0xFE, 0x60,
++	0x0C, 0x7F, 0x30,
++	0xEA, 0xAA, 0xB0,
++	0x3C, 0x57, 0x00,
++	0x18, 0xFE, 0x60,
++	0x00, 0x80, 0x00,
++	0x02, 0x80, 0x00,
++	0x01, 0x40, 0x00,
++	0x00, 0x00, 0x00,
++	0x12, 0xC8, 0x10,
++	0x11, 0x0F, 0x70,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x80, 0x01, 0x00,
++	0x11, 0x88, 0x20,
++	0x80, 0x00, 0x00,
++	0x7F, 0xFD, 0x00,
++	0x5C, 0xEF, 0xE0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x80, 0x01, 0x00,
++	0x11, 0x88, 0x20,
++	0x80, 0x00, 0x00,
++	0x7F, 0xFD, 0x00,
++	0x5C, 0xEF, 0xE0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x80, 0x01, 0x00,
++	0x11, 0x88, 0x20,
++	0x80, 0x00, 0x00,
++	0x7F, 0xFD, 0x00,
++	0x5C, 0xEF, 0xE0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x80, 0x01, 0x00,
++	0x11, 0x88, 0x20,
++	0x80, 0x00, 0x00,
++	0x7F, 0xFD, 0x00,
++	0x5C, 0xEF, 0xE0,
++	0x7F, 0xFE, 0x00,
++	0x6E, 0x77, 0xF0,
++	0x03, 0x04, 0x10,
++	0x7D, 0x0D, 0xB0,
++	0x03, 0x04, 0x10,
++	0x7D, 0x0D, 0xB0,
++	0x03, 0x04, 0x10,
++	0x7D, 0x0D, 0xB0,
++	0x03, 0x04, 0x10,
++	0x7D, 0x0D, 0xB0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x06, 0x00,
++	0xFE, 0x80, 0x00,
++	0x0A, 0x80, 0x00,
++	0xDD, 0x00, 0x00,
++	0x68, 0xFF, 0x80,
++	0x34, 0x7F, 0x00,
++	0xFC, 0x80, 0x80,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x3F, 0xF0,
++	0x08, 0x5F, 0xB0,
++	0xEA, 0x91, 0x40,
++	0xF7, 0xA0, 0x50,
++	0x55, 0x2E, 0xD0,
++	0x00, 0x00, 0x00,
++	0x00, 0x51, 0x20,
++	0xF8, 0x3B, 0xA0,
++	0x19, 0x90, 0xF0,
++	0x5C, 0x00, 0x00,
++	0x19, 0x90, 0xF0,
++	0xF8, 0x3B, 0xA0,
++	0x00, 0x51, 0x20,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0xFF, 0xFE, 0x40,
++	0x00, 0x00, 0x00,
++	0x00, 0x0A, 0x30,
++	0x00, 0x00, 0x00,
++	0xFF, 0xE5, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x34, 0x70,
++	0x00, 0x00, 0x00,
++	0xFF, 0xA6, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x8A, 0x40,
++	0x00, 0x00, 0x00,
++	0xFF, 0x35, 0xA0,
++	0x00, 0x00, 0x00,
++	0x01, 0x1C, 0x90,
++	0x00, 0x00, 0x00,
++	0xFE, 0x7A, 0x70,
++	0x00, 0x00, 0x00,
++	0x02, 0x0D, 0x20,
++	0x00, 0x00, 0x00,
++	0xFD, 0x3F, 0x80,
++	0x00, 0x00, 0x00,
++	0x03, 0xB9, 0x20,
++	0x00, 0x00, 0x00,
++	0xFA, 0xD2, 0x20,
++	0x00, 0x00, 0x00,
++	0x07, 0xAE, 0xA0,
++	0x00, 0x00, 0x00,
++	0xF2, 0xB3, 0xD0,
++	0x00, 0x00, 0x00,
++	0x28, 0xA6, 0x10,
++	0x40, 0x00, 0x00,
++	0x28, 0xA6, 0x10,
++	0x00, 0x00, 0x00,
++	0xF2, 0xB3, 0xD0,
++	0x00, 0x00, 0x00,
++	0x07, 0xAE, 0xA0,
++	0x00, 0x00, 0x00,
++	0xFA, 0xD2, 0x20,
++	0x00, 0x00, 0x00,
++	0x03, 0xB9, 0x20,
++	0x00, 0x00, 0x00,
++	0xFD, 0x3F, 0x80,
++	0x00, 0x00, 0x00,
++	0x02, 0x0D, 0x20,
++	0x00, 0x00, 0x00,
++	0xFE, 0x7A, 0x70,
++	0x00, 0x00, 0x00,
++	0x01, 0x1C, 0x90,
++	0x00, 0x00, 0x00,
++	0xFF, 0x35, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x8A, 0x40,
++	0x00, 0x00, 0x00,
++	0xFF, 0xA6, 0xF0,
++	0x00, 0x00, 0x00,
++	0x00, 0x34, 0x70,
++	0x00, 0x00, 0x00,
++	0xFF, 0xE5, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x0A, 0x30,
++	0x00, 0x00, 0x00,
++	0xFF, 0xFE, 0x40,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x07, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x04, 0xFF, 0x00,
++	0x08, 0x40, 0x00,
++	0x0B, 0x40, 0x00,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x02, 0x10, 0x00,
++	0x00, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x9E, 0xDD, 0xA0,
++	0x0C, 0x67, 0x50,
++	0x40, 0x00, 0x00,
++	0x00, 0x10, 0x60,
++	0x7F, 0xEF, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x12, 0x00,
++	0x00, 0x10, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x05, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0xB5, 0x00,
++	0x00, 0xCB, 0x00,
++	0x00, 0x40, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x07, 0xED, 0x00,
++	0x00, 0x80, 0x00,
++	0x08, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0xB1, 0x00,
++	0x01, 0x02, 0x00,
++	0x05, 0x7F, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x51, 0x00,
++	0x01, 0xDF, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0xF0, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x7E, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x01, 0x4A, 0xA0,
++	0x06, 0x57, 0xF0,
++	0x06, 0x57, 0xF0,
++	0x00, 0x04, 0x00,
++	0x7F, 0xF0, 0x00,
++	0x00, 0x10, 0x00,
++	0x1D, 0x9A, 0x50,
++	0xF9, 0xA8, 0x10,
++	0x00, 0x56, 0x00,
++	0x01, 0xE0, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0xF0, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x7E, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x01, 0x4A, 0xA0,
++	0x06, 0x57, 0xF0,
++	0x06, 0x57, 0xF0,
++	0x00, 0x04, 0x00,
++	0x7F, 0xF0, 0x00,
++	0x00, 0x10, 0x00,
++	0x1D, 0x9A, 0x50,
++	0xF9, 0xA8, 0x10,
++	0x40, 0x3B, 0x00,
++	0x3F, 0xFC, 0x30,
++	0x10, 0x00, 0x00,
++	0x7F, 0xFF, 0xF0,
++	0x01, 0x00, 0x00,
++	0x3A, 0xE2, 0x60,
++	0x8A, 0x3B, 0x40,
++	0xC9, 0xD2, 0x70,
++	0x75, 0x5B, 0xE0,
++	0x3A, 0xE2, 0x60,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x7F, 0xC0, 0x00,
++	0x00, 0x40, 0x00,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x08, 0x00, 0x00,
++	0x40, 0x00, 0x30,
++	0x20, 0x00, 0x00,
++	0x7F, 0xC0, 0x00,
++	0x00, 0x40, 0x00,
++	0x05, 0xA3, 0x00,
++	0x00, 0x14, 0xE0,
++	0x00, 0x50, 0x00,
++	0x0A, 0x06, 0x10,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x20, 0x00, 0x00,
++	0x60, 0x00, 0x00,
++	0x5A, 0x9D, 0xF0,
++	0x03, 0x2B, 0xF0,
++	0x3C, 0x6B, 0x80,
++	0x3F, 0xA1, 0xF0,
++	0x40, 0x01, 0xE0,
++	0x02, 0x00, 0x00,
++	0x0A, 0x06, 0x10,
++	0x3F, 0xFF, 0x10,
++	0x40, 0x5E, 0x90,
++	0x50, 0xC3, 0x30,
++	0x00, 0x50, 0x00,
++	0x03, 0xFD, 0x90,
++	0x7C, 0x00, 0x00,
++	0x04, 0x00, 0x00,
++	0x20, 0x00, 0x00,
++	0x60, 0x00, 0x00,
++	0x20, 0x26, 0xF0,
++	0x03, 0x2B, 0xF0,
++	0x3C, 0x6B, 0x80,
++	0x3F, 0xA1, 0xF0,
++	0x40, 0x01, 0xE0,
++	0x02, 0x00, 0x00,
++	0x03, 0xFD, 0x90,
++	0x3F, 0xFF, 0x10,
++	0x40, 0x5E, 0x90,
++	0x50, 0xC3, 0x30,
++	0x00, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x09, 0x00,
++	0x00, 0x07, 0x00, /* 0x00, 0x08, 0x00, 0x08=Right, 0x07=Left */
++	0x00, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x35, 0x3B, 0xA4,
++	0x87, 0x08, 0xCA,
++	0xDB, 0x3A, 0xA2,
++	0x54, 0x6B, 0xA7,
++	0x4C, 0x10, 0x6B,
++	0x35, 0x3B, 0xA4,
++	0x87, 0x08, 0xCA,
++	0xDB, 0x3A, 0xA2,
++	0x54, 0x6B, 0xA7,
++	0x4C, 0x10, 0x6B,
++	0x3E, 0x1D, 0xB7,
++	0x83, 0xC4, 0x91,
++	0xC3, 0xA8, 0xF6,
++	0x7C, 0x1F, 0xD5,
++	0x3E, 0x1D, 0xB7,
++	0x25, 0xE3, 0x8C,
++	0xA9, 0x24, 0x30,
++	0xCF, 0x83, 0x1F,
++	0x6E, 0x64, 0xB3,
++	0x39, 0x0A, 0x41,
++	0x3A, 0xD6, 0xA1,
++	0x8A, 0x52, 0xBE,
++	0xC9, 0xE9, 0xF9,
++	0x75, 0x44, 0x7D,
++	0x3A, 0xD6, 0xA1,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x0E, 0x7D, 0xA0,
++	0x0E, 0x7D, 0xA0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0x06, 0x00,
++	0x33, 0x33, 0x30,
++	0x01, 0x47, 0xB0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x01, 0xEB, 0x80,
++	0x14, 0x00, 0x00,
++	0xC0, 0x00, 0x00,
++	0x10, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x19, 0x99, 0xA0,
++	0x00, 0x00, 0x00,
++	0x74, 0x7A, 0xE0,
++	0x40, 0x00, 0x00,
++	0x05, 0x1E, 0xC0,
++	0x02, 0x8F, 0x60,
++	0x05, 0x1E, 0xC0,
++	0x02, 0x8F, 0x60,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x00, 0x08, 0x00,
++	0x00, 0x10, 0x00,
++	0x00, 0x28, 0x00,
++	0x00, 0x40, 0x00,
++	0x00, 0x58, 0x00,
++	0x00, 0x7F, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0x06, 0x00,
++	0x33, 0x33, 0x30,
++	0x01, 0x47, 0xB0,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x01, 0xEB, 0x80,
++	0x14, 0x00, 0x00,
++	0xC0, 0x00, 0x00,
++	0x10, 0x00, 0x00,
++	0x02, 0x00, 0x00,
++	0x19, 0x99, 0xA0,
++	0x00, 0x00, 0x00,
++	0x74, 0x7A, 0xE0,
++	0x40, 0x00, 0x00,
++	0x05, 0x1E, 0xC0,
++	0x02, 0x8F, 0x60,
++	0x05, 0x1E, 0xC0,
++	0x02, 0x8F, 0x60,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x1C, 0xA7, 0xD0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x40, 0x26, 0xE0,
++	0x00, 0x08, 0x00,
++	0x00, 0x10, 0x00,
++	0x00, 0x28, 0x00,
++	0x00, 0x40, 0x00,
++	0x00, 0x58, 0x00,
++	0x00, 0x7F, 0x00,
++	0x00, 0x00, 0x00,
++	0x0B, 0xFF, 0x00,
++	0x02, 0x80, 0x00,
++	0xB0, 0x00, 0x00,
++	0x00, 0x84, 0x00,
++	0x7F, 0xFF, 0x00,
++	0xF0, 0x00, 0x00,
++	0x40, 0x00, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x3C, 0x00,
++	0x16, 0x98, 0x00,
++	0x00, 0x46, 0x00,
++	0x16, 0x98, 0x00,
++	0x00, 0x46, 0x00,
++	0x16, 0x98, 0x00,
++	0x00, 0x0A, 0x00,
++	0x16, 0x98, 0x00,
++	0x50, 0xC8, 0x00,
++	0x20, 0x0F, 0x00,
++	0x50, 0xC8, 0x00,
++	0x20, 0x0F, 0x00,
++	0x30, 0x1E, 0x00,
++	0x20, 0x00, 0x00,
++	0x50, 0xC8, 0x00,
++	0x20, 0x0A, 0x00,
++	0x30, 0x3C, 0x00,
++	0x16, 0x8C, 0x00,
++	0x06, 0x18, 0x00,
++	0x16, 0x98, 0x00,
++	0x00, 0x06, 0x00,
++	0x16, 0xC0, 0x00,
++	0x00, 0x3C, 0x00,
++	0x17, 0x58, 0x00,
++	0x00, 0x64, 0x00,
++	0x1F, 0x58, 0x00,
++	0x00, 0x50, 0x00,
++	0x17, 0x58, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x08, 0x00,
++	0x00, 0x02, 0x10,
++	0x07, 0xEB, 0x80,
++	0x04, 0x02, 0x70,
++	0x03, 0xE8, 0x00,
++	0x00, 0x01, 0x00,
++	0x14, 0x49, 0x61,
++	0x00, 0x00, 0x00,
++	0x00, 0x80, 0x00,
++	0x00, 0xA1, 0x24,
++	0x00, 0xCA, 0xDE,
++	0x00, 0xFF, 0x65,
++	0x01, 0x41, 0x85,
++	0x01, 0x94, 0xC6,
++	0x01, 0xFD, 0x94,
++	0x02, 0x81, 0x85,
++	0x03, 0x27, 0xA0,
++	0x03, 0xF8, 0xBD,
++	0x05, 0x9C, 0x2F,
++	0x07, 0xEC, 0xAA,
++	0x0B, 0x31, 0x90,
++	0x0F, 0xCF, 0xB7,
++	0x16, 0x55, 0x8D,
++	0x1F, 0x8C, 0x41,
++	0x7F, 0xFF, 0xFF,
++	0x65, 0xAC, 0x8C,
++	0x47, 0xFA, 0xCD,
++	0x32, 0xF5, 0x2D,
++	0x24, 0x13, 0x47,
++	0x19, 0x8A, 0x13,
++	0x12, 0x14, 0x9A,
++	0x0C, 0xCC, 0xCD,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x7F, 0xFF, 0xFF,
++	0x03, 0xFF, 0x00,
++	0x00, 0x00, 0x00,
++	0x02, 0x02, 0x70,
++	0x02, 0xD6, 0xB0,
++	0x04, 0x02, 0x70,
++	0x05, 0xA9, 0xE0,
++	0x08, 0x00, 0x00,
++	0x0B, 0x4C, 0xE0,
++	0x0F, 0xF6, 0x50,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00,
++	0x21, 0x87, 0x00,
++	0x00, 0x00, 0x00,
++	0x21, 0x2F, 0x00,
++	0x40, 0x00, 0x00,
++	0x7F, 0x8A, 0xD0,
++	0xAA, 0xD1, 0xB0,
++	0xD5, 0xA3, 0x70,
++	0x65, 0xD8, 0x00,
++	0xF8, 0x00, 0x00,
++	0x60, 0x00, 0x00,
++	0x6E, 0xD9, 0xF0,
++	0x49, 0xE6, 0xA0,
++	0xE7, 0x5D, 0xD0,
++	0x10, 0x6C, 0x20,
++	0xF2, 0x50, 0x90,
++	0x0C, 0xC5, 0xE0,
++	0xF3, 0x3A, 0x20,
++	0x08, 0x00, 0x00,
++	0x5A, 0x82, 0x80,
++	0x00, 0x00, 0x00,
++	0x05, 0x05, 0x00,
++	0x07, 0x1B, 0x00,
++	0x08, 0xB5, 0x00,
++	0x0A, 0x11, 0x00,
++	0x0B, 0x44, 0x00,
++	0x0C, 0x5A, 0x00,
++	0x0D, 0x5B, 0x00,
++	0x0E, 0x4A, 0x00,
++	0x0F, 0x2C, 0x00,
++	0x10, 0x02, 0x00,
++	0x10, 0xCE, 0x00,
++	0x11, 0x91, 0x00,
++	0x12, 0x4E, 0x00,
++	0x13, 0x03, 0x00,
++	0x13, 0xB3, 0x00,
++	0x14, 0x5D, 0x00,
++	0x15, 0x02, 0x00,
++	0x15, 0xA3, 0x00,
++	0x16, 0x41, 0x00,
++	0x16, 0xDA, 0x00,
++	0x17, 0x70, 0x00,
++	0x18, 0x03, 0x00,
++	0x18, 0x93, 0x00,
++	0x19, 0x20, 0x00,
++	0x19, 0xAB, 0x00,
++	0x1A, 0x33, 0x00,
++	0x1A, 0xB9, 0x00,
++	0x1B, 0x3D, 0x00,
++	0x1B, 0xBF, 0x00,
++	0x1C, 0x3F, 0x00,
++	0x1C, 0xBD, 0x00,
++	0x1D, 0x39, 0x00,
++	0x1D, 0xB4, 0x00,
++	0x1E, 0x2E, 0x00,
++	0x1E, 0xA5, 0x00,
++	0x1F, 0x1C, 0x00,
++	0x1F, 0x91, 0x00,
++	0x20, 0x05, 0x00,
++	0x20, 0x77, 0x00,
++	0x20, 0xE8, 0x00,
++	0x21, 0x59, 0x00,
++	0x21, 0xC8, 0x00,
++	0x22, 0x36, 0x00,
++	0x22, 0xA3, 0x00,
++	0x23, 0x0F, 0x00,
++	0x23, 0x7A, 0x00,
++	0x23, 0xE4, 0x00,
++	0x24, 0x4D, 0x00,
++	0x24, 0xB6, 0x00,
++	0x25, 0x1D, 0x00,
++	0x25, 0x84, 0x00,
++	0x25, 0xEA, 0x00,
++	0x26, 0x50, 0x00,
++	0x26, 0xB4, 0x00,
++	0x27, 0x18, 0x00,
++	0x27, 0x7B, 0x00,
++	0x27, 0xDE, 0x00,
++	0x28, 0x3F, 0x00,
++	0x28, 0xA1, 0x00,
++	0x29, 0x01, 0x00,
++	0x29, 0x61, 0x00,
++	0x29, 0xC1, 0x00,
++	0x2A, 0x1F, 0x00,
++	0x00, 0x01, 0x00,
++	0x00, 0x0E, 0x00,
++	0x20, 0x16, 0x00,
++	0x10, 0x17, 0x00,
++	0x01, 0x03, 0x00,
++};
++
++
++static u8 ak7755_ofreg_basic[]= {
++	0xB2,0x00,0x00,    // OFREG Write Command
++    0x00, 0x00, 0x00,  // 0x000
++    0x00, 0x00, 0x00,  // 0x001
++    0x00, 0x00, 0x00,  // 0x002
++    0x00, 0x00, 0x00,  // 0x003
++    0x00, 0x00, 0x00,  // 0x004
++    0x00, 0x00, 0x00,  // 0x005
++    0x00, 0x00, 0x00,  // 0x006
++    0x00, 0x00, 0x00,  // 0x007
++};
++
++static u8 ak7755_acram_basic[]= {
++	0xBB,0x00,0x00,    // ACRAM Write Command
++    0x00, 0x00, 0x00,  // 0x000
++    0x00, 0x00, 0x00,  // 0x001
++    0x00, 0x00, 0x00,  // 0x002
++    0x00, 0x00, 0x00,  // 0x003
++    0x00, 0x00, 0x00,  // 0x004
++    0x00, 0x00, 0x00,  // 0x005
++    0x00, 0x00, 0x00,  // 0x006
++    0x00, 0x00, 0x00,  // 0x007
++};
++
++
+diff --git a/sound/soc/codecs/ak7755ctl.h b/sound/soc/codecs/ak7755ctl.h
+new file mode 100644
+index 00000000..dd5e5246
+--- /dev/null
++++ b/sound/soc/codecs/ak7755ctl.h
+@@ -0,0 +1,75 @@
++ /* ak7755ioctrl.h
++ *
++ * Copyright (C) 2014 Asahi Kasei Microdevices Corporation.
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *      14/04/09	     1.0
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __DSP_AK7755_H__
++#define __DSP_AK7755_H__
++
++/* IO CONTROL definition of AK7755 */
++#define AK7755_IOCTL_MAGIC     's'
++
++#define AK7755_MAGIC	0xD0
++#define MAX_WREG		32
++#define MAX_WCRAM		48
++
++enum ak7755_ram_type {
++	RAMTYPE_PRAM = 0,
++	RAMTYPE_CRAM,
++	RAMTYPE_OFREG,
++	RAMTYPE_ACRAM,
++};
++
++
++enum ak7755_status {
++	POWERDOWN = 0,
++	SUSPEND,
++	STANDBY,
++	DOWNLOAD,
++	RUN,
++};
++
++typedef struct _REG_CMD {
++	unsigned char addr;
++	unsigned char data;
++} REG_CMD;
++
++struct ak7755_wreg_handle {
++	REG_CMD *regcmd;
++	int len;
++};
++
++struct ak7755_wcram_handle{
++	int    addr;
++	unsigned char *cram;
++	int    len;
++};
++
++struct ak7755_loadram_handle {
++	int ramtype;
++	int mode;
++};
++
++#define AK7755_IOCTL_SETSTATUS	_IOW(AK7755_MAGIC, 0x10, int)
++#define AK7755_IOCTL_GETSTATUS	_IOR(AK7755_MAGIC, 0x11, int)
++#define AK7755_IOCTL_SETMIR		_IOW(AK7755_MAGIC, 0x12, int)
++#define AK7755_IOCTL_GETMIR		_IOR(AK7755_MAGIC, 0x13, unsigned long)
++#define AK7755_IOCTL_WRITEREG	_IOW(AK7755_MAGIC, 0x14, struct ak7755_wreg_handle)
++#define AK7755_IOCTL_WRITECRAM	_IOW(AK7755_MAGIC, 0x15, struct ak7755_wcram_handle)
++#define AK7755_IOCTL_LOADRAM	_IOW(AK7755_MAGIC, 0x16, struct ak7755_loadram_handle)
++
++#endif
++
+diff --git a/sound/soc/codecs/ambarella_dummy.c b/sound/soc/codecs/ambarella_dummy.c
+new file mode 100644
+index 00000000..4b6e882c
+--- /dev/null
++++ b/sound/soc/codecs/ambarella_dummy.c
+@@ -0,0 +1,169 @@
++/*
++ * ambarella_dummy.c  --  A2SAUC ALSA SoC Audio driver
++ *
++ * History:
++ *	2008/10/17 - [Andrew Lu] created file
++ *	2009/03/12 - [Cao Rongrong] Port to 2.6.27
++ *	2009/06/10 - [Cao Rongrong] Port to 2.6.29
++ *	2011/03/20 - [Cao Rongrong] Port to 2.6.38
++ *
++ * Coryright (c) 2008-2009, Ambarella, Inc.
++ * http://www.ambarella.com
++ *
++ * 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.
++*/
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/of.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/initval.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <linux/of_gpio.h>
++#include "ambarella_dummy.h"
++
++static inline unsigned int ambdummy_codec_read(struct snd_soc_codec *codec,
++	unsigned int reg)
++{
++	return 0;
++}
++
++static inline int ambdummy_codec_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int value)
++{
++	return 0;
++}
++
++static int ambdummy_mute(struct snd_soc_dai *dai, int mute)
++{
++	return 0;
++}
++
++static int ambdummy_set_bias_level(struct snd_soc_codec *codec,
++				 enum snd_soc_bias_level level)
++{
++	codec->dapm.bias_level = level;
++	return 0;
++}
++
++#define AMBDUMMY_RATES SNDRV_PCM_RATE_8000_48000
++
++#define AMBDUMMY_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_ops ambdummy_dai_ops = {
++	.digital_mute = ambdummy_mute,
++};
++
++static struct snd_soc_dai_driver ambdummy_dai = {
++	.name = "AMBARELLA_DUMMY_CODEC",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 2,
++		.channels_max = 6,
++		.rates = AMBDUMMY_RATES,
++		.formats = AMBDUMMY_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 2,
++		.channels_max = 6,
++		.rates = AMBDUMMY_RATES,
++		.formats = AMBDUMMY_FORMATS,},
++	.ops = &ambdummy_dai_ops,
++};
++
++#if defined(CONFIG_PM)
++static int ambdummy_suspend(struct snd_soc_codec *codec)
++{
++	ambdummy_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	ambdummy_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	return 0;
++}
++
++static int ambdummy_resume(struct snd_soc_codec *codec)
++{
++	ambdummy_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	ambdummy_set_bias_level(codec, SND_SOC_BIAS_ON);
++
++	return 0;
++}
++#else
++#define ambdummy_suspend NULL
++#define ambdummy_resume NULL
++#endif
++static int ambdummy_probe(struct snd_soc_codec *codec)
++{
++	printk(KERN_INFO "AMBARELLA SoC Audio DUMMY Codec\n");
++
++	ambdummy_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return 0;
++}
++
++/* power down chip */
++static int ambdummy_remove(struct snd_soc_codec *codec)
++{
++	ambdummy_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	return 0;
++}
++
++static struct snd_soc_codec_driver soc_codec_dev_ambdummy = {
++	.probe = 	ambdummy_probe,
++	.remove = 	ambdummy_remove,
++	.suspend = 	ambdummy_suspend,
++	.resume =	ambdummy_resume,
++	.reg_cache_size	= 0,
++	.read =		ambdummy_codec_read,
++	.write =	ambdummy_codec_write,
++	.set_bias_level =ambdummy_set_bias_level,
++};
++
++static int ambdummy_codec_probe(struct platform_device *pdev)
++{
++	return snd_soc_register_codec(&pdev->dev,
++			&soc_codec_dev_ambdummy, &ambdummy_dai, 1);
++}
++
++static int ambdummy_codec_remove(struct platform_device *pdev)
++{
++	snd_soc_unregister_codec(&pdev->dev);
++	return 0;
++}
++
++static struct of_device_id ambdummy_of_match[] = {
++	{ .compatible = "ambarella,dummycodec",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, ambdummy_of_match);
++
++static struct platform_driver ambdummy_codec_driver = {
++	.probe		= ambdummy_codec_probe,
++	.remove		= ambdummy_codec_remove,
++	.driver		= {
++		.name	= "ambdummy-codec",
++		.owner	= THIS_MODULE,
++		.of_match_table = ambdummy_of_match,
++	},
++};
++
++static int __init ambarella_dummy_codec_init(void)
++{
++	return platform_driver_register(&ambdummy_codec_driver);
++
++}
++module_init(ambarella_dummy_codec_init);
++
++static void __exit ambarella_dummy_codec_exit(void)
++{
++	platform_driver_unregister(&ambdummy_codec_driver);
++}
++module_exit(ambarella_dummy_codec_exit);
++
++MODULE_DESCRIPTION("Soc Ambarella Dummy Codec Driver");
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/ambarella_dummy.h b/sound/soc/codecs/ambarella_dummy.h
+new file mode 100644
+index 00000000..127464d0
+--- /dev/null
++++ b/sound/soc/codecs/ambarella_dummy.h
+@@ -0,0 +1,9 @@
++/*
++ * ambarella_dummy.h  --  Ambarella dummy codec driver
++ *
++ */
++
++#ifndef _AMBARELLA_DUMMY_H
++#define _AMBARELLA_DUMMY_H
++
++#endif /* _AMBARELLA_DUMMY_H */
+diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
+new file mode 100644
+index 00000000..20bdcc1f
+--- /dev/null
++++ b/sound/soc/codecs/es8328.c
+@@ -0,0 +1,686 @@
++/*
++ * es8328.c  --  ES8328 ALSA Soc Audio driver
++ *
++ * Copyright 2011 Ambarella Ltd.
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * Based on es8328.c from Everest Semiconductor
++ *
++ * History:
++ *	2011/10/19 - [Cao Rongrong] Created file
++ *	2013/01/14 - [Ken He] Port to 3.8
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/gpio.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/tlv.h>
++#include <sound/es8328.h>
++
++#include "es8328.h"
++
++#define ES8328_VERSION "v1.0"
++
++/* codec private data */
++struct es8328_priv {
++	unsigned int sysclk;
++	void *control_data;
++};
++
++
++/*
++ * es8328 register cache
++ * We can't read the es8328 register space when we
++ * are using 2 wire for device control, so we cache them instead.
++ */
++static const u8 es8328_reg[] = {
++	0x06, 0x1C, 0xC3, 0xFC,  /*  0 */
++	0xC0, 0x00, 0x00, 0x7C,  /*  4 */
++	0x80, 0x00, 0x00, 0x06,  /*  8 */
++	0x00, 0x06, 0x30, 0x30,  /* 12 */
++	0xC0, 0xC0, 0x38, 0xB0,  /* 16 */
++	0x32, 0x06, 0x00, 0x00,  /* 20 */
++	0x06, 0x32, 0xC0, 0xC0,  /* 24 */
++	0x08, 0x06, 0x1F, 0xF7,  /* 28 */
++	0xFD, 0xFF, 0x1F, 0xF7,  /* 32 */
++	0xFD, 0xFF, 0x00, 0x38,  /* 36 */
++	0x38, 0x38, 0x38, 0x38,  /* 40 */
++	0x38, 0x00, 0x00, 0x00,  /* 44 */
++	0x00, 0x00, 0x00, 0x00,  /* 48 */
++	0x00, 0x00, 0x00, 0x00,  /* 52 */
++};
++
++/* DAC/ADC Volume: min -96.0dB (0xC0) ~ max 0dB (0x00)  ( 0.5 dB step ) */
++static const DECLARE_TLV_DB_SCALE(digital_tlv, -9600, 50, 0);
++/* Analog Out Volume: min -30.0dB (0x00) ~ max 3dB (0x21)  ( 1 dB step ) */
++static const DECLARE_TLV_DB_SCALE(out_tlv, -3000, 100, 0);
++/* Analog In Volume: min 0dB (0x00) ~ max 24dB (0x08)  ( 3 dB step ) */
++static const DECLARE_TLV_DB_SCALE(in_tlv, 0, 300, 0);
++
++static const struct snd_kcontrol_new es8328_snd_controls[] = {
++	SOC_DOUBLE_R_TLV("Playback Volume",
++		ES8328_LDAC_VOL, ES8328_RDAC_VOL, 0, 0xC0, 1, digital_tlv),
++	SOC_DOUBLE_R_TLV("Analog Out Volume",
++		ES8328_LOUT1_VOL, ES8328_ROUT1_VOL, 0, 0x1D, 0, out_tlv),
++
++	SOC_DOUBLE_R_TLV("Capture Volume",
++		ES8328_LADC_VOL, ES8328_RADC_VOL, 0, 0xC0, 1, digital_tlv),
++	SOC_DOUBLE_TLV("Analog In Volume",
++		ES8328_ADCCONTROL1, 4, 0, 0x08, 0, in_tlv),
++};
++
++/*
++ * DAPM Controls
++ */
++
++/* Channel Input Mixer */
++static const char *es8328_line_texts[] = { "Line 1", "Line 2", "Differential"};
++static const unsigned int es8328_line_values[] = { 0, 1, 3};
++
++static const struct soc_enum es8328_lline_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8328_ADCCONTROL2, 6, 0xC0,
++		ARRAY_SIZE(es8328_line_texts), es8328_line_texts,
++		es8328_line_values);
++static const struct snd_kcontrol_new es8328_left_line_controls =
++	SOC_DAPM_VALUE_ENUM("Route", es8328_lline_enum);
++
++static const struct soc_enum es8328_rline_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8328_ADCCONTROL2, 4, 0x30,
++		ARRAY_SIZE(es8328_line_texts), es8328_line_texts,
++		es8328_line_values);
++static const struct snd_kcontrol_new es8328_right_line_controls =
++	SOC_DAPM_VALUE_ENUM("Route", es8328_lline_enum);
++
++
++/* Left Mixer */
++static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL17, 7, 1, 0),
++	SOC_DAPM_SINGLE("Left Bypass Switch"  , ES8328_DACCONTROL17, 6, 1, 0),
++};
++
++/* Right Mixer */
++static const struct snd_kcontrol_new es8328_right_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL20, 7, 1, 0),
++	SOC_DAPM_SINGLE("Right Bypass Switch"  , ES8328_DACCONTROL20, 6, 1, 0),
++};
++
++/* Mono ADC Mux */
++static const char *es8328_mono_mux[] = {"Stereo", "Mono (Left)", "Mono (Right)", "NONE"};
++static const struct soc_enum monomux =
++	SOC_ENUM_SINGLE(ES8328_ADCCONTROL3, 3, 4, es8328_mono_mux);
++static const struct snd_kcontrol_new es8328_monomux_controls =
++	SOC_DAPM_ENUM("Route", monomux);
++
++static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = {
++	/* DAC Part */
++	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
++		&es8328_left_mixer_controls[0], ARRAY_SIZE(es8328_left_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
++		&es8328_right_mixer_controls[0], ARRAY_SIZE(es8328_right_mixer_controls)),
++
++	SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, &es8328_left_line_controls),
++	SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, &es8328_right_line_controls),
++
++	SND_SOC_DAPM_DAC("Left DAC"  , "Left Playback" , ES8328_DACPOWER, 7, 1),
++	SND_SOC_DAPM_DAC("Right DAC" , "Right Playback", ES8328_DACPOWER, 6, 1),
++	SND_SOC_DAPM_PGA("Left Out 1" , ES8328_DACPOWER, 5, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Right Out 1", ES8328_DACPOWER, 4, 0, NULL, 0),
++	/* SND_SOC_DAPM_PGA("Left Out 2" , ES8328_DACPOWER, 3, 0, NULL, 0), */
++	/* SND_SOC_DAPM_PGA("Right Out 2", ES8328_DACPOWER, 2, 0, NULL, 0), */
++
++	SND_SOC_DAPM_OUTPUT("LOUT1"),
++	SND_SOC_DAPM_OUTPUT("ROUT1"),
++	SND_SOC_DAPM_OUTPUT("LOUT2"),
++	SND_SOC_DAPM_OUTPUT("ROUT2"),
++
++	/* ADC Part */
++	SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, &es8328_monomux_controls),
++	SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, &es8328_monomux_controls),
++
++	SND_SOC_DAPM_PGA("Left Analog Input" , ES8328_ADCPOWER, 7, 1, NULL, 0),
++	SND_SOC_DAPM_PGA("Right Analog Input", ES8328_ADCPOWER, 6, 1, NULL, 0),
++	SND_SOC_DAPM_ADC("Left ADC" , "Left Capture" , ES8328_ADCPOWER, 5, 1),
++	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8328_ADCPOWER, 4, 1),
++
++	SND_SOC_DAPM_MICBIAS("Mic Bias", ES8328_ADCPOWER, 3, 1),
++
++	SND_SOC_DAPM_INPUT("MICIN"),
++	SND_SOC_DAPM_INPUT("LINPUT1"),
++	SND_SOC_DAPM_INPUT("LINPUT2"),
++	SND_SOC_DAPM_INPUT("RINPUT1"),
++	SND_SOC_DAPM_INPUT("RINPUT2"),
++};
++
++static const struct snd_soc_dapm_route intercon[] = {
++	/* left mixer */
++	{"Left Mixer", "Left Playback Switch", "Left DAC"},
++
++	/* right mixer */
++	{"Right Mixer", "Right Playback Switch", "Right DAC"},
++
++	/* left out 1 */
++	{"Left Out 1", NULL, "Left Mixer"},
++	{"LOUT1", NULL, "Left Out 1"},
++
++	/* right out 1 */
++	{"Right Out 1", NULL, "Right Mixer"},
++	{"ROUT1", NULL, "Right Out 1"},
++
++	/* Left Line Mux */
++	{"Left Line Mux", "Line 1", "LINPUT1"},
++	{"Left Line Mux", "Line 2", "LINPUT2"},
++	{"Left Line Mux", "Differential", "MICIN"},
++
++	/* Right Line Mux */
++	{"Right Line Mux", "Line 1", "RINPUT1"},
++	{"Right Line Mux", "Line 2", "RINPUT2"},
++	{"Right Line Mux", "Differential", "MICIN"},
++
++	/* Left ADC Mux */
++	{"Left ADC Mux", "Stereo", "Left Line Mux"},
++//	{"Left ADC Mux", "Mono (Left)" , "Left Line Mux"},
++
++	/* Right ADC Mux */
++	{"Right ADC Mux", "Stereo", "Right Line Mux"},
++//	{"Right ADC Mux", "Mono (Right)", "Right Line Mux"},
++
++	/* ADC */
++	{"Left ADC" , NULL, "Left ADC Mux"},
++	{"Right ADC", NULL, "Right ADC Mux"},
++};
++
++static inline unsigned int es8328_read_reg_cache(struct snd_soc_codec *codec,
++		unsigned int reg)
++{
++	u8 *cache = codec->reg_cache;
++
++	if (reg >= ES8328_CACHEREGNUM)
++		return -1;
++
++	return cache[reg];
++}
++
++static int es8328_write(struct snd_soc_codec *codec, unsigned int reg,
++			     unsigned int value)
++{
++	u8 *cache = codec->reg_cache;
++	struct i2c_client *client = codec->control_data;
++
++	if (reg >= ES8328_CACHEREGNUM)
++		return -EIO;
++
++	if (i2c_smbus_write_byte_data(client, reg, value)) {
++		pr_err("ES8328: I2C write failed\n");
++		return -EIO;
++	}
++	/* We've written to the hardware, so update the cache */
++	cache[reg] = value;
++
++	return 0;
++}
++
++static int es8328_sync(struct snd_soc_codec *codec)
++{
++	u8 *cache = codec->reg_cache;
++	int i, r = 0;
++
++	for (i = 0; i < ES8328_CACHEREGNUM; i++)
++		r |= snd_soc_write(codec, i, cache[i]);
++
++	return r;
++};
++
++static int es8328_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
++
++	es8328->sysclk = freq;
++	return 0;
++}
++
++static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 iface = 0;
++	u8 adciface = 0;
++	u8 daciface = 0;
++
++	iface = snd_soc_read(codec, ES8328_IFACE);
++	adciface = snd_soc_read(codec, ES8328_ADC_IFACE);
++	daciface = snd_soc_read(codec, ES8328_DAC_IFACE);
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:    // MASTER MODE
++		iface |= 0x80;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:    // SLAVE MODE
++		iface &= 0x7F;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		adciface &= 0xFC;
++		daciface &= 0xF9;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++	case SND_SOC_DAIFMT_LEFT_J:
++	case SND_SOC_DAIFMT_DSP_A:
++	case SND_SOC_DAIFMT_DSP_B:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		iface &= 0xDF;
++		adciface &= 0xDF;
++		daciface &= 0xBF;
++		break;
++	case SND_SOC_DAIFMT_IB_IF:
++		iface |= 0x20;
++		adciface |= 0x20;
++		daciface |= 0x40;
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		iface |= 0x20;
++		adciface &= 0xDF;
++		daciface &= 0xBF;
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		iface &= 0xDF;
++		adciface |= 0x20;
++		daciface |= 0x40;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	snd_soc_write(codec, ES8328_IFACE    , iface);
++	snd_soc_write(codec, ES8328_ADC_IFACE, adciface);
++	snd_soc_write(codec, ES8328_DAC_IFACE, daciface);
++
++	return 0;
++}
++
++static int es8328_pcm_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++	u16 iface;
++
++	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		iface = snd_soc_read(codec, ES8328_DAC_IFACE) & 0xC7;
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			iface |= 0x0018;
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			iface |= 0x0008;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			iface |= 0x0020;
++			break;
++		}
++		/* set iface & srate */
++		snd_soc_write(codec, ES8328_DAC_IFACE, iface);
++	} else {
++		iface = snd_soc_read(codec, ES8328_ADC_IFACE) & 0xE3;
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			iface |= 0x000C;
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			iface |= 0x0004;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			iface |= 0x0010;
++			break;
++		}
++		/* set iface */
++		snd_soc_write(codec, ES8328_ADC_IFACE, iface);
++	}
++
++	return 0;
++}
++
++static int es8328_mute(struct snd_soc_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	unsigned char val = 0;
++
++	val = snd_soc_read(codec, ES8328_DAC_MUTE);
++	if (mute){
++		val |= 0x04;
++	} else {
++		val &= ~0x04;
++	}
++
++	snd_soc_write(codec, ES8328_DAC_MUTE, val);
++
++	return 0;
++}
++
++
++static int es8328_set_bias_level(struct snd_soc_codec *codec,
++		enum snd_soc_bias_level level)
++{
++	switch(level) {
++	case SND_SOC_BIAS_ON:
++		break;
++
++	case SND_SOC_BIAS_PREPARE:
++		if(codec->dapm.bias_level != SND_SOC_BIAS_ON) {
++			/* updated by David-everest,5-25
++			// Chip Power on
++			snd_soc_write(codec, ES8328_CHIPPOWER, 0xF3);
++			// VMID control
++			snd_soc_write(codec, ES8328_CONTROL1 , 0x06);
++			// ADC/DAC DLL power on
++			snd_soc_write(codec, ES8328_CONTROL2 , 0xF3);
++			*/
++			snd_soc_write(codec, ES8328_ADCPOWER, 0x00);
++			snd_soc_write(codec, ES8328_DACPOWER , 0x30);
++			snd_soc_write(codec, ES8328_CHIPPOWER , 0x00);
++		}
++		break;
++
++	case SND_SOC_BIAS_STANDBY:
++		/*
++		// ADC/DAC DLL power on
++		snd_soc_write(codec, ES8328_CONTROL2 , 0xFF);
++		// Chip Power off
++		snd_soc_write(codec, ES8328_CHIPPOWER, 0xF3);
++		*/
++		snd_soc_write(codec, ES8328_ADCPOWER, 0x00);
++		snd_soc_write(codec, ES8328_DACPOWER , 0x30);
++		snd_soc_write(codec, ES8328_CHIPPOWER , 0x00);
++		break;
++
++	case SND_SOC_BIAS_OFF:
++		/*
++		// ADC/DAC DLL power off
++		snd_soc_write(codec, ES8328_CONTROL2 , 0xFF);
++		// Chip Control
++		snd_soc_write(codec, ES8328_CONTROL1 , 0x00);
++		// Chip Power off
++		snd_soc_write(codec, ES8328_CHIPPOWER, 0xFF);
++		*/
++		snd_soc_write(codec, ES8328_ADCPOWER, 0xff);
++		snd_soc_write(codec, ES8328_DACPOWER , 0xC0);
++		snd_soc_write(codec, ES8328_CHIPPOWER , 0xC3);
++		break;
++	}
++
++	codec->dapm.bias_level = level;
++
++	return 0;
++}
++
++
++#define ES8328_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++                    SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
++                    SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
++
++#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
++                    SNDRV_PCM_FMTBIT_S24_LE)
++
++static const struct snd_soc_dai_ops es8328_dai_ops = {
++	.hw_params    = es8328_pcm_hw_params,
++	.set_fmt      = es8328_set_dai_fmt,
++	.set_sysclk   = es8328_set_dai_sysclk,
++	.digital_mute = es8328_mute,
++};
++
++
++struct snd_soc_dai_driver es8328_dai = {
++	.name = "ES8328",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 2,
++		.channels_max = 2,
++		.rates = ES8328_RATES,
++		.formats = ES8328_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 2,
++		.channels_max = 2,
++		.rates = ES8328_RATES,
++		.formats = ES8328_FORMATS,},
++	.ops = &es8328_dai_ops,
++};
++
++EXPORT_SYMBOL_GPL(es8328_dai);
++
++
++static int es8328_suspend(struct snd_soc_codec *codec, pm_message_t state)
++{
++	es8328_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static int es8328_resume(struct snd_soc_codec *codec)
++{
++	es8328_sync(codec);
++	es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return 0;
++}
++
++static int es8328_remove(struct snd_soc_codec *codec)
++{
++	struct es8328_platform_data *es8328_pdata;
++
++	es8328_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	es8328_pdata = codec->dev->platform_data;
++	gpio_free(es8328_pdata->power_pin);
++
++	return 0;
++}
++
++static int es8328_probe(struct snd_soc_codec *codec)
++{
++	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
++	struct es8328_platform_data *es8328_pdata;
++	int ret = 0;
++
++	dev_info(codec->dev, "ES8328 Audio Codec %s", ES8328_VERSION);
++
++	codec->control_data = es8328->control_data;
++
++	es8328_pdata = codec->dev->platform_data;
++	if (!es8328_pdata)
++		return -EINVAL;
++
++	/* Power on ES8328 codec */
++	if (gpio_is_valid(es8328_pdata->power_pin)) {
++		ret = gpio_request(es8328_pdata->power_pin, "es8328 power");
++		if (ret < 0)
++			return ret;
++	} else {
++		return -ENODEV;
++	}
++	gpio_direction_output(es8328_pdata->power_pin, GPIO_HIGH);
++	msleep(es8328_pdata->power_delay);
++
++	es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	snd_soc_write(codec, ES8328_MASTERMODE  , 0x00);    // SLAVE MODE, MCLK not divide
++	snd_soc_write(codec, ES8328_CHIPPOWER   , 0xf3);    // Power down: ADC DEM, DAC DSM/DEM, ADC/DAC state machine, ADC/DAC ananlog reference
++	snd_soc_write(codec, ES8328_DACCONTROL21, 0x80);    // DACLRC and ADCLRC same, ADC/DAC DLL power up, Enable MCLK input from PAD.
++
++	snd_soc_write(codec, ES8328_CONTROL1   , 0x05);     // VMIDSEL (500 kohme divider enabled)
++	snd_soc_write(codec, ES8328_CONTROL2 , 0x72);   //
++
++	snd_soc_write(codec, ES8328_DACPOWER   , 0x30);     // DAC R/L Power on, OUT1 enable, OUT2 disable
++	snd_soc_write(codec, ES8328_ADCPOWER   , 0x00);     //
++	snd_soc_write(codec, ES8328_ANAVOLMANAG, 0x7C);     //
++
++	//-----------------------------------------------------------------------------------------------------------------
++	snd_soc_write(codec, ES8328_ADCCONTROL1, 0x66);     // MIC PGA gain: +24dB
++	snd_soc_write(codec, ES8328_ADCCONTROL2, 0xf0);     // LINSEL(L-R differential), RINGSEL(L-R differential)
++	snd_soc_write(codec, ES8328_ADCCONTROL3, 0x82);     // Input Select: LIN2/RIN2
++	snd_soc_write(codec, ES8328_ADCCONTROL4, 0x4C);     // Left data = left ADC, right data = right ADC, 24 bits I2S
++	snd_soc_write(codec, ES8328_ADCCONTROL5, 0x02);     // 256fs
++	//snd_soc_write(codec, ES8328_ADCCONTROL6, 0x00);     // Disable High pass filter
++
++	snd_soc_write(codec, ES8328_LADC_VOL, 0x00);        // 0dB
++	snd_soc_write(codec, ES8328_RADC_VOL, 0x00);        // 0dB
++
++	//snd_soc_write(codec, ES8328_ADCCONTROL10, 0x3A);    // ALC stereo, Max gain(17.5dB), Min gain(0dB)
++	snd_soc_write(codec, ES8328_ADCCONTROL10, 0xe2);    // ALC stereo, Max gain(17.5dB), Min gain(0dB),updated by david-everest,5-25
++	snd_soc_write(codec, ES8328_ADCCONTROL11, 0xA0);    // ALCLVL(-1.5dB), ALCHLD(0ms)
++	snd_soc_write(codec, ES8328_ADCCONTROL12, 0x05);    // ALCDCY(1.64ms/363us), ALCATK(1664us/363.2us)
++	snd_soc_write(codec, ES8328_ADCCONTROL13, 0x06);    // ALCMODE(ALC mode), ALCZC(disable), TIME_OUT(disable), WIN_SIZE(96 samples)
++	snd_soc_write(codec, ES8328_ADCCONTROL14, 0xd3);    // NGTH(XXX), NGG(mute ADC output), NGAT(enable)
++
++
++	//----------------------------------------------------------------------------------------------------------------
++	snd_soc_write(codec, ES8328_DACCONTROL1, 0x18);     // I2S 16bits
++	snd_soc_write(codec, ES8328_DACCONTROL2, 0x02);     // 256fs
++
++	snd_soc_write(codec, ES8328_LDAC_VOL, 0x00);    // left DAC volume
++	snd_soc_write(codec, ES8328_RDAC_VOL, 0x00);    // right DAC volume
++
++	snd_soc_write(codec, ES8328_DACCONTROL3, 0xE0);     // DAC unmute
++
++	snd_soc_write(codec, ES8328_DACCONTROL17, 0xb8);    // left DAC to left mixer enable,
++	snd_soc_write(codec, ES8328_DACCONTROL18, 0x38);    // ???
++	snd_soc_write(codec, ES8328_DACCONTROL19, 0x38);    // ???
++	snd_soc_write(codec, ES8328_DACCONTROL20, 0xb8);    // right DAC to right mixer enable,
++
++	snd_soc_write(codec, ES8328_CHIPPOWER, 0x00);   // ALL Block POWER ON
++	//snd_soc_write(codec, ES8328_CONTROL2 , 0x72);   // updated by david-everest,5-25
++	//mdelay(100);
++
++	snd_soc_write(codec, ES8328_LOUT1_VOL, 0x1D);   //
++	snd_soc_write(codec, ES8328_ROUT1_VOL, 0x1D);   //
++	snd_soc_write(codec, ES8328_LOUT2_VOL, 0x00);   // Disable LOUT2
++	snd_soc_write(codec, ES8328_ROUT2_VOL, 0x00);   // Disable ROUT2
++
++	snd_soc_add_codec_controls(codec, es8328_snd_controls,
++		ARRAY_SIZE(es8328_snd_controls));
++	snd_soc_dapm_new_controls(&codec->dapm, es8328_dapm_widgets,
++		ARRAY_SIZE(es8328_dapm_widgets));
++	snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon));
++
++	return ret;
++}
++
++
++static struct snd_soc_codec_driver soc_codec_dev_es8328 = {
++	.probe =	es8328_probe,
++	.remove =	es8328_remove,
++	.suspend =	es8328_suspend,
++	.resume =	es8328_resume,
++	.read =		es8328_read_reg_cache,
++	.write =	es8328_write,
++	.set_bias_level = es8328_set_bias_level,
++	.reg_cache_size = ARRAY_SIZE(es8328_reg),
++	.reg_word_size = sizeof(u8),
++	.reg_cache_default = es8328_reg,
++	.reg_cache_step = 1,
++};
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static int es8328_i2c_probe(struct i2c_client *i2c,
++			    const struct i2c_device_id *id)
++{
++	struct es8328_priv *es8328;
++	int ret;
++
++	es8328 = kzalloc(sizeof(struct es8328_priv), GFP_KERNEL);
++	if (es8328 == NULL)
++		return -ENOMEM;
++
++	i2c_set_clientdata(i2c, es8328);
++	es8328->control_data = i2c;
++
++	ret =  snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_es8328, &es8328_dai, 1);
++	if (ret < 0)
++		kfree(es8328);
++
++	return ret;
++}
++
++static int es8328_i2c_remove(struct i2c_client *i2c)
++{
++	snd_soc_unregister_codec(&i2c->dev);
++	kfree(i2c_get_clientdata(i2c));
++
++	return 0;
++}
++
++static const struct i2c_device_id es8328_i2c_id[] = {
++	{ "es8328", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, es8328_i2c_id);
++
++static struct i2c_driver es8328_i2c_driver = {
++	.driver = {
++		.name = "es8328-codec",
++		.owner = THIS_MODULE,
++	},
++	.probe    = es8328_i2c_probe,
++	.remove   = es8328_i2c_remove,
++	.id_table = es8328_i2c_id,
++};
++#endif
++
++static int __init es8328_modinit(void)
++{
++	int ret = 0;
++
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&es8328_i2c_driver);
++	if (ret != 0) {
++		pr_err("Failed to register ES8328 I2C driver: %d\n", ret);
++	}
++#endif
++	return ret;
++}
++module_init(es8328_modinit);
++
++static void __exit es8328_exit(void)
++{
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	i2c_del_driver(&es8328_i2c_driver);
++#endif
++}
++module_exit(es8328_exit);
++
++MODULE_DESCRIPTION("ASoC ES8328 driver");
++MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/es8328.h b/sound/soc/codecs/es8328.h
+new file mode 100644
+index 00000000..a8c3bc06
+--- /dev/null
++++ b/sound/soc/codecs/es8328.h
+@@ -0,0 +1,157 @@
++/*
++ * es8328.h  --  ES8328 Soc Audio driver
++ *
++ * Copyright 2011 Ambarella Ltd.
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++#ifndef _ES8328_H
++#define _ES8328_H
++
++#define CONFIG_HHTECH_MINIPMP	1
++
++/* ES8328 register space */
++
++#define ES8328_CONTROL1         0x00
++#define ES8328_CONTROL2         0x01
++#define ES8328_CHIPPOWER        0x02
++#define ES8328_ADCPOWER         0x03
++#define ES8328_DACPOWER         0x04
++#define ES8328_CHIPLOPOW1       0x05
++#define ES8328_CHIPLOPOW2       0x06
++#define ES8328_ANAVOLMANAG      0x07
++#define ES8328_MASTERMODE       0x08
++#define ES8328_ADCCONTROL1      0x09
++#define ES8328_ADCCONTROL2      0x0a
++#define ES8328_ADCCONTROL3      0x0b
++#define ES8328_ADCCONTROL4      0x0c
++#define ES8328_ADCCONTROL5      0x0d
++#define ES8328_ADCCONTROL6      0x0e
++#define ES8328_ADCCONTROL7      0x0f
++#define ES8328_ADCCONTROL8      0x10
++#define ES8328_ADCCONTROL9      0x11
++#define ES8328_ADCCONTROL10     0x12
++#define ES8328_ADCCONTROL11     0x13
++#define ES8328_ADCCONTROL12     0x14
++#define ES8328_ADCCONTROL13     0x15
++#define ES8328_ADCCONTROL14     0x16
++
++#define ES8328_DACCONTROL1      0x17
++#define ES8328_DACCONTROL2      0x18
++#define ES8328_DACCONTROL3      0x19
++#define ES8328_DACCONTROL4      0x1a
++#define ES8328_DACCONTROL5      0x1b
++#define ES8328_DACCONTROL6      0x1c
++#define ES8328_DACCONTROL7      0x1d
++#define ES8328_DACCONTROL8      0x1e
++#define ES8328_DACCONTROL9      0x1f
++#define ES8328_DACCONTROL10     0x20
++#define ES8328_DACCONTROL11     0x21
++#define ES8328_DACCONTROL12     0x22
++#define ES8328_DACCONTROL13     0x23
++#define ES8328_DACCONTROL14     0x24
++#define ES8328_DACCONTROL15     0x25
++#define ES8328_DACCONTROL16     0x26
++#define ES8328_DACCONTROL17     0x27
++#define ES8328_DACCONTROL18     0x28
++#define ES8328_DACCONTROL19     0x29
++#define ES8328_DACCONTROL20     0x2a
++#define ES8328_DACCONTROL21     0x2b
++#define ES8328_DACCONTROL22     0x2c
++#define ES8328_DACCONTROL23     0x2d
++#define ES8328_DACCONTROL24     0x2e
++#define ES8328_DACCONTROL25     0x2f
++#define ES8328_DACCONTROL26     0x30
++#define ES8328_DACCONTROL27     0x31
++#define ES8328_DACCONTROL28     0x32
++#define ES8328_DACCONTROL29     0x33
++#define ES8328_DACCONTROL30     0x34
++
++#define ES8328_LADC_VOL         ES8328_ADCCONTROL8
++#define ES8328_RADC_VOL         ES8328_ADCCONTROL9
++
++#define ES8328_LDAC_VOL         ES8328_DACCONTROL4
++#define ES8328_RDAC_VOL         ES8328_DACCONTROL5
++
++#define ES8328_LOUT1_VOL        ES8328_DACCONTROL24
++#define ES8328_ROUT1_VOL        ES8328_DACCONTROL25
++#define ES8328_LOUT2_VOL        ES8328_DACCONTROL26
++#define ES8328_ROUT2_VOL        ES8328_DACCONTROL27
++
++#define ES8328_ADC_MUTE         ES8328_ADCCONTROL7
++#define ES8328_DAC_MUTE         ES8328_DACCONTROL3
++
++
++
++#define ES8328_IFACE            ES8328_MASTERMODE
++
++#define ES8328_ADC_IFACE        ES8328_ADCCONTROL4
++#define ES8328_ADC_SRATE        ES8328_ADCCONTROL5
++
++#define ES8328_DAC_IFACE        ES8328_DACCONTROL1
++#define ES8328_DAC_SRATE        ES8328_DACCONTROL2
++
++
++
++#define ES8328_CACHEREGNUM      53
++#define ES8328_SYSCLK	        0
++
++struct es8328_setup_data {
++	int i2c_bus;
++	unsigned short i2c_address;
++};
++
++#if 1 //lzcx
++#define ES8328_PLL1			0
++#define ES8328_PLL2			1
++
++/* clock inputs */
++#define ES8328_MCLK		0
++#define ES8328_PCMCLK		1
++
++/* clock divider id's */
++#define ES8328_PCMDIV		0
++#define ES8328_BCLKDIV		1
++#define ES8328_VXCLKDIV		2
++
++/* PCM clock dividers */
++#define ES8328_PCM_DIV_1	(0 << 6)
++#define ES8328_PCM_DIV_3	(2 << 6)
++#define ES8328_PCM_DIV_5_5	(3 << 6)
++#define ES8328_PCM_DIV_2	(4 << 6)
++#define ES8328_PCM_DIV_4	(5 << 6)
++#define ES8328_PCM_DIV_6	(6 << 6)
++#define ES8328_PCM_DIV_8	(7 << 6)
++
++/* BCLK clock dividers */
++#define ES8328_BCLK_DIV_1	(0 << 7)
++#define ES8328_BCLK_DIV_2	(1 << 7)
++#define ES8328_BCLK_DIV_4	(2 << 7)
++#define ES8328_BCLK_DIV_8	(3 << 7)
++
++/* VXCLK clock dividers */
++#define ES8328_VXCLK_DIV_1	(0 << 6)
++#define ES8328_VXCLK_DIV_2	(1 << 6)
++#define ES8328_VXCLK_DIV_4	(2 << 6)
++#define ES8328_VXCLK_DIV_8	(3 << 6)
++#define ES8328_VXCLK_DIV_16	(4 << 6)
++
++#define ES8328_DAI_HIFI		0
++#define ES8328_DAI_VOICE		1
++
++#define ES8328_1536FS 1536
++#define ES8328_1024FS	1024
++#define ES8328_768FS	768
++#define ES8328_512FS	512
++#define ES8328_384FS	384
++#define ES8328_256FS	256
++#define ES8328_128FS	128
++#endif
++
++#endif
++
+diff --git a/sound/soc/codecs/es8374.c b/sound/soc/codecs/es8374.c
+new file mode 100644
+index 00000000..12897c48
+--- /dev/null
++++ b/sound/soc/codecs/es8374.c
+@@ -0,0 +1,1564 @@
++/*
++ * es8374.c  --  ES8374 ALSA SoC Audio Codec
++ *
++ * Copyright (C) 2016 Everest Semiconductor Co., Ltd
++ *
++ * Authors:  XianqingZheng(xqzheng@ambarella.com)
++ *
++ * Based on es8374.c by David Yang(yangxiaohua@everest-semi.com)
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/spi/spi.h>
++#include <linux/slab.h>
++#include <linux/regmap.h>
++#include <linux/stddef.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/tlv.h>
++#include <sound/soc.h>
++#include <sound/initval.h>
++#include <linux/of_gpio.h>
++#include "es8374.h"
++
++//#define ES8374_SPI
++/*
++ * es8374 register cache
++ */
++static struct reg_default  es8374_reg_defaults[] = {
++	{   0x00, 0x03 },
++	{   0x01, 0x03 },
++	{   0x02, 0x00 },
++	{   0x03, 0x20 },
++	{   0x04, 0x00 },
++	{   0x05, 0x11 },
++	{   0x06, 0x01 },
++	{   0x07, 0x00 },
++	{   0x08, 0x20 },
++	{   0x09, 0x80 },
++	{   0x0a, 0x4A },
++	{   0x0b, 0x00 },
++	{   0x0c, 0x00 },
++	{   0x0d, 0x00 },
++	{   0x0e, 0x00 },
++	{   0x0f, 0x00 },
++
++	{   0x10, 0x00 },
++	{   0x11, 0x00 },
++	{   0x12, 0x40 },
++	{   0x13, 0x40 },
++	{   0x14, 0x9C },
++	{   0x15, 0xBE },
++	{   0x16, 0x00 },
++	{   0x17, 0xA0 },
++	{   0x18, 0xFC },
++	{   0x19, 0x00 },
++	{   0x1a, 0x18 },
++	{   0x1b, 0x00 },
++	{   0x1c, 0x10 },
++	{   0x1d, 0x10 },
++	{   0x1e, 0x00 },
++	{   0x1f, 0x08 },
++
++	{   0x20, 0x08 },
++	{   0x21, 0xD4 },
++	{   0x22, 0x00 },
++	{   0x23, 0x00 },
++	{   0x24, 0x18 },
++	{   0x25, 0xC0 },
++	{   0x26, 0x1C },
++	{   0x27, 0x00 },
++	{   0x28, 0xB0 },
++	{   0x29, 0x32 },
++	{   0x2a, 0x03 },
++	{   0x2b, 0x00 },
++	{   0x2c, 0x0D },
++	{   0x2d, 0x06 },
++	{   0x2e, 0x1F },
++	{   0x2f, 0xF7 },
++
++	{   0x30, 0xFD },
++	{   0x31, 0xFF },
++	{   0x32, 0x1F },
++	{   0x33, 0xF7 },
++	{   0x34, 0xFD },
++	{   0x35, 0xFF },
++	{   0x36, 0x04 },
++	{   0x37, 0x01 },
++	{   0x38, 0xC0 },
++	{   0x39, 0x00 },
++	{   0x3a, 0x02 },
++	{   0x3b, 0x17 },
++	{   0x3c, 0xFD },
++	{   0x3d, 0xFF },
++	{   0x3e, 0x07 },
++	{   0x3f, 0xFD },
++
++	{   0x40, 0xFF },
++	{   0x41, 0x00 },
++	{   0x42, 0xFF },
++	{   0x43, 0xBB },
++	{   0x44, 0xFF },
++	{   0x45, 0x00 },
++	{   0x46, 0x00 },
++	{   0x47, 0x00 },
++	{   0x48, 0x00 },
++	{   0x49, 0x00 },
++	{   0x4a, 0x00 },
++	{   0x4b, 0x00 },
++	{   0x4c, 0x00 },
++	{   0x4d, 0x00 },
++	{   0x4e, 0x00 },
++	{   0x4f, 0x00 },
++
++	{   0x50, 0x00 },
++	{   0x51, 0x00 },
++	{   0x52, 0x00 },
++	{   0x53, 0x00 },
++	{   0x54, 0x00 },
++	{   0x55, 0x00 },
++	{   0x56, 0x00 },
++	{   0x57, 0x00 },
++	{   0x58, 0x00 },
++	{   0x59, 0x00 },
++	{   0x5a, 0x00 },
++	{   0x5b, 0x00 },
++	{   0x5c, 0x00 },
++	{   0x5d, 0x00 },
++	{   0x5e, 0x00 },
++	{   0x5f, 0x00 },
++
++	{   0x60, 0x00 },
++	{   0x61, 0x00 },
++	{   0x62, 0x00 },
++	{   0x63, 0x00 },
++	{   0x64, 0x00 },
++	{   0x65, 0x00 },
++	{   0x66, 0x00 },
++	{   0x67, 0x00 },
++	{   0x68, 0x00 },
++	{   0x69, 0x00 },
++	{   0x6a, 0x00 },
++	{   0x6b, 0x00 },
++	{   0x6c, 0x00 },
++	{   0x6d, 0x00 },
++	{   0x6e, 0x00 },
++	{   0x6f, 0x00 },
++
++};
++#if 0
++static u8 es8374_equalizer_src[] = {
++	0x0A, 0x9B, 0x32, 0x03, 0x5C, 0x5D, 0x4B, 0x24, 0x0A, 0x9B,
++	0x32, 0x03, 0x4C, 0x1F, 0x43, 0x05, 0x6D, 0x27, 0x54, 0x06,
++	0x4D, 0xE1, 0x32, 0x02, 0x3E, 0x55, 0x2A, 0x20, 0x4D, 0xE1,
++	0x32, 0x02, 0x2E, 0x17, 0x22, 0x01, 0x9F, 0xE7, 0x43, 0x25,
++	0x4B, 0xD9, 0x21, 0x01, 0xF9, 0xD4, 0x11, 0x21, 0x4B, 0xD9,
++	0x21, 0x01, 0xE9, 0x96, 0x19, 0x00, 0x4C, 0xE7, 0x22, 0x23,
++};
++#endif
++struct sp_config {
++	u8 spc, mmcc, spfs;
++	u32 srate;
++	u8 lrcdiv;
++	u8 sclkdiv;
++};
++
++/* codec private data */
++
++struct	es8374_private {
++	enum snd_soc_control_type control_type;
++	struct spi_device *spi;
++	struct i2c_client *i2c;
++
++	struct snd_soc_codec *codec;
++	struct regmap *regmap;
++	u32 clk_id;
++	u32 mclk;
++
++	/* platform dependant DVDD voltage configuration */
++/*	u8	dvdd_pwr_vol;
++	u8  pll_div;
++*/
++	int pwr_gpio;
++	unsigned int pwr_active;
++  	bool dmic_enable;
++	u8 reg_cache[110];
++};
++
++struct es8374_private *es8374_data;
++
++static bool es8374_volatile_register(struct device *dev,
++			unsigned int reg)
++{
++	if ((reg  < 0x80)) {
++		if((reg != 0x19) && (reg != 0x23)) {
++			return true;
++		} else {
++			return false;
++		}
++	} else {
++			return false;
++	}
++}
++
++static bool es8374_readable_register(struct device *dev,
++			unsigned int reg)
++{
++	if ((reg  < 0x80)) {
++		if((reg != 0x19) && (reg != 0x23)) {
++			return true;
++		} else {
++			return false;
++		}
++	} else {
++			return false;
++	}
++}
++static bool es8374_writable_register(struct device *dev,
++			unsigned int reg)
++{
++	if ((reg  < 0x80)) {
++		if((reg != 0x19) && (reg != 0x23)) {
++			return true;
++		} else {
++			return false;
++		}
++	} else {
++			return false;
++	}
++}
++
++
++/*
++*	Define ADC and DAC Volume
++*/
++static const DECLARE_TLV_DB_SCALE(vdac_tlv, 0, 50, 0);
++static const DECLARE_TLV_DB_SCALE(vadc_tlv, 0, 50, 0);
++/*
++*	Define D2SE MIC BOOST GAIN
++*/
++static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 1500, 0);
++/*
++*	Define LINE PGA GAIN
++*/
++static const DECLARE_TLV_DB_SCALE(linin_pga_tlv, 0, 300, 0);
++/*
++*	Define dmic boost gain
++*/
++static const DECLARE_TLV_DB_SCALE(dmic_6db_scaleup_tlv, 0, 600, 0);
++/*
++*	Definitiiion ALC noise gate type
++*/
++
++static const char * const ng_type_txt[] = {"Constant PGA Gain",
++	"Mute ADC Output"};
++static const struct soc_enum ng_type =
++SOC_ENUM_SINGLE(ES8374_ALC_NGTH_REG2B, 6, 2, ng_type_txt);
++
++
++static const char * const alc_mode_txt[] = {
++	"ALC Mode",
++	"Limiter Mode"
++};
++
++static const struct soc_enum alc_mode =
++SOC_ENUM_SINGLE(ES8374_ALC_EN_MAX_GAIN_REG26, 5, 2, alc_mode_txt);
++
++/*
++*	Define MONO output gain
++*/
++static const DECLARE_TLV_DB_SCALE(mono_out_gain_tlv, 0, 150, 0);
++/*
++*	Definitiiion dac auto mute type
++*/
++
++static const char * const dac_auto_mute_type_txt[] = {
++	"AUTO MUTE DISABLE",
++	"MONO OUTPUT MUTE",
++	"SPEAKER MUTE",
++	"MONO OUT & SPEAKER MUTE"
++	};
++static const struct soc_enum dac_auto_mute_type =
++SOC_ENUM_SINGLE(ES8374_DAC_CONTROL_REG37, 4, 4, dac_auto_mute_type_txt);
++/*
++*	Definitiiion dac dsm mute type
++*/
++
++static const char * const dac_dsm_mute_type_txt[] = {
++	"DAC DSM UNMUTE",
++	"DAC DSM MUTE",
++	};
++static const struct soc_enum dac_dsm_mute_type =
++SOC_ENUM_SINGLE(ES8374_DAC_CONTROL_REG37, 0, 2, dac_dsm_mute_type_txt);
++
++/*
++ * es8374 Controls
++ */
++static const struct snd_kcontrol_new es8374_snd_controls[] = {
++	/*
++	* controls for capture path
++	*/
++	SOC_SINGLE_TLV("D2SE MIC BOOST GAIN",
++					ES8374_AIN_PWR_SRC_REG21, 2, 1, 0, mic_boost_tlv),
++	SOC_SINGLE_TLV("LIN PGA GAIN",
++					ES8374_AIN_PGA_REG22, 0, 15, 0, linin_pga_tlv),
++	SOC_SINGLE_TLV("DMIC 6DB SCALE UP GAIN",
++					ES8374_ADC_CONTROL_REG24, 7, 1, 0, dmic_6db_scaleup_tlv),
++	SOC_SINGLE("ADC Double FS Mode", ES8374_ADC_CONTROL_REG24, 6, 1, 0),
++	SOC_SINGLE("ADC Soft Ramp", ES8374_ADC_CONTROL_REG24, 4, 1, 0),
++	SOC_SINGLE("ADC MUTE", ES8374_ADC_CONTROL_REG24, 5, 1, 0),
++	SOC_SINGLE("ADC INVERTED", ES8374_ADC_CONTROL_REG24, 2, 1, 0),
++	SOC_SINGLE("ADC HPF COEFFICIENT", ES8374_ADC_HPF_REG2C, 0, 31, 0),
++//	SOC_SINGLE_TLV("ADC Capture Volume",
++//				ES8374_ADC_VOLUME_REG25, 0, 192, 1, adc_rec_tlv),
++	SOC_SINGLE("ALC Capture Target Volume", ES8374_ALC_LVL_HLD_REG28, 4, 15, 0),
++	SOC_SINGLE("ALC Capture Max PGA", ES8374_ALC_EN_MAX_GAIN_REG26, 0, 31, 0),
++	SOC_SINGLE("ALC Capture Min PGA", ES8374_ALC_MIN_GAIN_REG27, 0, 31, 0),
++//	SOC_ENUM("ALC Capture Function", alc_func),
++	SOC_ENUM("ALC Mode", alc_mode),
++	SOC_SINGLE("ALC Capture Hold Time", ES8374_ALC_LVL_HLD_REG28, 0, 15, 0),
++	SOC_SINGLE("ALC Capture Decay Time", ES8374_ALC_DCY_ATK_REG29, 4, 15, 0),
++	SOC_SINGLE("ALC Capture Attack Time", ES8374_ALC_DCY_ATK_REG29, 0, 15, 0),
++	SOC_SINGLE("ALC Capture NG Threshold", ES8374_ALC_NGTH_REG2B, 0, 31, 0),
++	SOC_ENUM("ALC Capture NG Type", ng_type),
++	SOC_SINGLE("ALC Capture NG Switch", ES8374_ALC_NGTH_REG2B, 5, 1, 0),
++
++	/*
++	* controls for playback path
++	*/
++	SOC_SINGLE("DAC Double FS Mode", ES8374_DAC_CONTROL_REG37, 7, 1, 0),
++	SOC_SINGLE("DAC Soft Ramp Rate", ES8374_DAC_CONTROL_REG36, 2, 7, 0),
++	SOC_SINGLE("DAC MUTE", ES8374_DAC_CONTROL_REG36, 5, 1, 0),
++	SOC_SINGLE("DAC OFFSET", ES8374_DAC_OFFSET_REG39, 0, 255, 0),
++	SOC_ENUM("DAC AUTO MUTE TYPE", dac_auto_mute_type),
++	SOC_ENUM("DAC DSM MUTE TYPE", dac_dsm_mute_type),
++
++	SOC_SINGLE_TLV("ADC Capture Volume",
++					ES8374_ADC_VOLUME_REG25, 0, 192, 1, vadc_tlv),
++	SOC_SINGLE_TLV("DAC Playback Volume",
++					ES8374_DAC_VOLUME_REG38, 0, 192, 1, vdac_tlv),
++	SOC_SINGLE_TLV("MONO OUT GAIN",
++					ES8374_MONO_GAIN_REG1B, 0, 15, 0, mono_out_gain_tlv),
++	SOC_SINGLE_TLV("SPEAKER MIXER GAIN",
++					ES8374_SPK_MIX_GAIN_REG1D, 0, 15, 0, mono_out_gain_tlv),
++	SOC_SINGLE_TLV("SPEAKER OUTPUT Volume",
++					ES8374_SPK_OUT_GAIN_REG1E, 0, 7, 0, mono_out_gain_tlv),
++};
++
++/*
++ * DAPM Controls
++ */
++/*
++* alc on/off
++*/
++static const char * const es8374_alc_enable_txt[] = {
++	"ALC OFF",
++	"ALC ON",
++};
++
++static const struct soc_enum es8374_alc_enable_enum =
++SOC_ENUM_SINGLE(ES8374_ALC_EN_MAX_GAIN_REG26, 6,
++	ARRAY_SIZE(es8374_alc_enable_txt), es8374_alc_enable_txt);
++
++
++static const struct snd_kcontrol_new es8374_alc_enable_controls =
++	SOC_DAPM_ENUM("Route", es8374_alc_enable_enum);
++/*
++* adc line in select
++*/
++static const char * const es8374_adc_input_src_txt[] = {
++	"LIN1-RIN1",
++	"LIN2-RIN2",
++};
++static const unsigned int es8374_adc_input_src_values[] = {
++	0, 1};
++static const struct soc_enum es8374_adc_input_src_enum =
++SOC_VALUE_ENUM_SINGLE(ES8374_AIN_PWR_SRC_REG21, 4, 0x30,
++			ARRAY_SIZE(es8374_adc_input_src_txt),
++			es8374_adc_input_src_txt,
++			es8374_adc_input_src_values);
++static const struct snd_kcontrol_new es8374_adc_input_src_controls =
++	SOC_DAPM_ENUM("Route", es8374_adc_input_src_enum);
++
++/*
++ * ANALOG IN MUX
++ */
++static const char * const es8374_analog_input_mux_txt[] = {
++	"LIN1",
++	"LIN2",
++	"DIFF OUT1",
++	"DIFF OUT2",
++	"PGA OUT1",
++	"PGA OUT2"
++};
++static const unsigned int es8374_analog_input_mux_values[] = {
++	0, 1, 2, 3, 4, 5};
++static const struct soc_enum es8374_analog_input_mux_enum =
++SOC_VALUE_ENUM_SINGLE(ES8374_MONO_MIX_REG1A, 0, 0x7,
++			ARRAY_SIZE(es8374_analog_input_mux_txt),
++			es8374_analog_input_mux_txt,
++			es8374_analog_input_mux_values);
++static const struct snd_kcontrol_new es8374_analog_input_mux_controls =
++SOC_DAPM_ENUM("Route", es8374_analog_input_mux_enum);
++/*
++ * MONO OUTPUT MIXER
++ */
++static const struct snd_kcontrol_new es8374_mono_out_mixer_controls[] = {
++	SOC_DAPM_SINGLE("LIN TO MONO OUT Switch", ES8374_MONO_MIX_REG1A, 6, 1, 0),
++	SOC_DAPM_SINGLE("DAC TO MONO OUT Switch", ES8374_MONO_MIX_REG1A, 7, 1, 0),
++};
++/*
++ * SPEAKER OUTPUT MIXER
++ */
++static const struct snd_kcontrol_new es8374_speaker_mixer_controls[] = {
++	SOC_DAPM_SINGLE("LIN TO SPEAKER OUT Switch", ES8374_SPK_MIX_REG1C, 6, 1, 0),
++	SOC_DAPM_SINGLE("DAC TO SPEAKER OUT Switch", ES8374_SPK_MIX_REG1C, 7, 1, 0),
++};
++/*
++ * digital microphone soure
++ */
++static const char * const es8374_dmic_mux_txt[] = {
++		"DMIC DISABLE1",
++		"DMIC DISABLE2",
++		"DMIC AT HIGH LEVEL",
++		"DMIC AT LOW LEVEL",
++};
++static const unsigned int es8374_dmic_mux_values[] = {
++		0, 1, 2, 3};
++static const struct soc_enum es8374_dmic_mux_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8374_ADC_CONTROL_REG24, 0, 0x3,
++				ARRAY_SIZE(es8374_dmic_mux_txt),
++				es8374_dmic_mux_txt,
++				es8374_dmic_mux_values);
++static const struct snd_kcontrol_new es8374_dmic_mux_controls =
++	SOC_DAPM_ENUM("Route", es8374_dmic_mux_enum);
++/*
++ * ADC sdp  soure
++ */
++static const char * const es8374_adc_sdp_mux_txt[] = {
++		"FROM ADC OUT",
++		"FROM EQUALIZER",
++};
++static const unsigned int es8374_adc_sdp_mux_values[] = {
++		0, 1};
++static const struct soc_enum es8374_adc_sdp_mux_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8374_EQ_SRC_REG2D, 7, 0x80,
++				ARRAY_SIZE(es8374_adc_sdp_mux_txt),
++				es8374_adc_sdp_mux_txt,
++				es8374_adc_sdp_mux_values);
++static const struct snd_kcontrol_new es8374_adc_sdp_mux_controls =
++	SOC_DAPM_ENUM("Route", es8374_adc_sdp_mux_enum);
++
++/*
++ * DAC dsm  soure
++ */
++static const char * const es8374_dac_dsm_mux_txt[] = {
++		"FROM SDP IN",
++		"FROM EQUALIZER",
++};
++static const unsigned int  es8374_dac_dsm_mux_values[] = {
++		0, 1};
++static const struct soc_enum  es8374_dac_dsm_mux_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8374_EQ_SRC_REG2D, 6, 0x40,
++				ARRAY_SIZE(es8374_dac_dsm_mux_txt),
++				es8374_dac_dsm_mux_txt,
++				es8374_dac_dsm_mux_values);
++static const struct snd_kcontrol_new  es8374_dac_dsm_mux_controls =
++	SOC_DAPM_ENUM("Route", es8374_dac_dsm_mux_enum);
++/*
++ * equalizer data  soure
++ */
++static const char * const es8374_equalizer_src_mux_txt[] = {
++		"FROM ADC OUT",
++		"FROM SDP IN",
++};
++static const unsigned int  es8374_equalizer_src_mux_values[] = {
++		0, 1};
++static const struct soc_enum  es8374_equalizer_src_mux_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8374_EQ_SRC_REG2D, 5, 0x20,
++				ARRAY_SIZE(es8374_equalizer_src_mux_txt),
++				es8374_equalizer_src_mux_txt,
++				es8374_equalizer_src_mux_values);
++static const struct snd_kcontrol_new  es8374_equalizer_src_mux_controls =
++	SOC_DAPM_ENUM("Route", es8374_equalizer_src_mux_enum);
++/*
++ * DAC data  soure
++ */
++static const char * const es8374_dac_data_mux_txt[] = {
++		"SELECT SDP LEFT DATA",
++		"SELECT SDP RIGHT DATA",
++};
++static const unsigned int  es8374_dac_data_mux_values[] = {
++		0, 1};
++static const struct soc_enum  es8374_dac_data_mux_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8374_DAC_CONTROL_REG36, 6, 0x40,
++				ARRAY_SIZE(es8374_dac_data_mux_txt),
++				es8374_dac_data_mux_txt,
++				es8374_dac_data_mux_values);
++static const struct snd_kcontrol_new  es8374_dac_data_mux_controls =
++	SOC_DAPM_ENUM("Route", es8374_dac_data_mux_enum);
++
++static const struct snd_soc_dapm_widget es8374_dapm_widgets[] = {
++	/* Input Lines */
++		SND_SOC_DAPM_INPUT("DMIC"),
++		SND_SOC_DAPM_INPUT("MIC1"),
++		SND_SOC_DAPM_INPUT("MIC2"),
++		SND_SOC_DAPM_INPUT("LIN1"),
++		SND_SOC_DAPM_INPUT("LIN2"),
++
++	/*
++	*  Capture path
++	*/
++		SND_SOC_DAPM_MICBIAS("micbias", ES8374_ANA_REF_REG14,
++				4, 1),
++
++		/* Input MUX */
++		SND_SOC_DAPM_MUX("DIFFERENTIAL MUX", SND_SOC_NOPM, 0, 0,
++				&es8374_adc_input_src_controls),
++
++		SND_SOC_DAPM_PGA("DIFFERENTIAL PGA", SND_SOC_NOPM,
++				0, 0, NULL, 0),
++
++		SND_SOC_DAPM_PGA("LINE PGA", SND_SOC_NOPM,
++				0, 0, NULL, 0),
++
++		/* ADCs */
++		SND_SOC_DAPM_ADC("MONO ADC", NULL, SND_SOC_NOPM, 0, 0),
++
++		/* Dmic MUX */
++		SND_SOC_DAPM_MUX("DMIC MUX", SND_SOC_NOPM, 0, 0,
++				&es8374_dmic_mux_controls),
++
++		/* Dmic MUX */
++		SND_SOC_DAPM_MUX("ALC MUX", SND_SOC_NOPM, 0, 0,
++			&es8374_alc_enable_controls),
++
++
++		/* sdp MUX */
++		SND_SOC_DAPM_MUX("SDP OUT MUX", SND_SOC_NOPM, 0, 0,
++			&es8374_adc_sdp_mux_controls),
++
++		/* Digital Interface */
++		SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture",  1,
++				SND_SOC_NOPM, 0, 0),
++
++		/*
++		*	Render path
++		*/
++		SND_SOC_DAPM_AIF_IN("I2S IN", "I2S1 Playback", 0,
++				SND_SOC_NOPM, 0, 0),
++
++		/*	DACs SDP DATA SRC MUX */
++		SND_SOC_DAPM_MUX("DAC SDP SRC MUX", SND_SOC_NOPM, 0, 0,
++				&es8374_dac_data_mux_controls),
++
++		/*	DACs  DATA SRC MUX */
++		SND_SOC_DAPM_MUX("DAC SRC MUX", SND_SOC_NOPM, 0, 0,
++			&es8374_dac_dsm_mux_controls),
++
++		SND_SOC_DAPM_DAC("MONO DAC", NULL, SND_SOC_NOPM, 0, 0),
++
++
++		/* hpmux for hp mixer */
++		SND_SOC_DAPM_MUX("ANALOG INPUT MUX", SND_SOC_NOPM, 0, 0,
++				&es8374_analog_input_mux_controls),
++
++		/* Output mixer  */
++		SND_SOC_DAPM_MIXER("MONO MIXER", SND_SOC_NOPM,
++				0, 0, &es8374_mono_out_mixer_controls[0], ARRAY_SIZE(es8374_mono_out_mixer_controls)),
++		SND_SOC_DAPM_MIXER("SPEAKER MIXER", SND_SOC_NOPM,
++				0, 0, &es8374_speaker_mixer_controls[0], ARRAY_SIZE(es8374_speaker_mixer_controls)),
++
++		/*
++		*	Equalizer path
++		*/
++		SND_SOC_DAPM_MUX("EQUALIZER MUX", SND_SOC_NOPM, 0, 0,
++				&es8374_equalizer_src_mux_controls),
++
++		/* Output Lines */
++		SND_SOC_DAPM_OUTPUT("MOUT"),
++		SND_SOC_DAPM_OUTPUT("SPKOUT"),
++
++};
++
++
++static const struct snd_soc_dapm_route es8374_dapm_routes[] = {
++	/*
++	 * record route map
++	 */
++	{"MIC1", NULL, "micbias"},
++	{"MIC2", NULL, "micbias"},
++	{"DMIC", NULL, "micbias"},
++
++	{"DIFFERENTIAL MUX", "LIN1-RIN1", "MIC1"},
++	{"DIFFERENTIAL MUX", "LIN2-RIN2", "MIC2"},
++
++	{"DIFFERENTIAL PGA", NULL, "DIFFERENTIAL MUX"},
++
++	{"LINE PGA", NULL, "DIFFERENTIAL PGA"},
++
++	{"MONO ADC", NULL, "LINE PGA"},
++
++	{"DMIC MUX", "DMIC DISABLE1", "MONO ADC"},
++	{"DMIC MUX", "DMIC DISABLE2", "MONO ADC"},
++	{"DMIC MUX", "DMIC AT HIGH LEVEL", "DMIC"},
++	{"DMIC MUX", "DMIC AT LOW LEVEL", "DMIC"},
++
++	{"ALC MUX", "ALC OFF", "DMIC MUX"},
++	{"ALC MUX", "ALC ON", "DMIC MUX"},
++
++	/*
++	* Equalizer path
++	*/
++	{"EQUALIZER MUX", "FROM ADC OUT", "ALC MUX"},
++	{"EQUALIZER MUX", "FROM SDP IN", "I2S IN"},
++
++	{"SDP OUT MUX", "FROM ADC OUT", "ALC MUX"},
++	{"SDP OUT MUX", "FROM EQUALIZER", "EQUALIZER MUX"},
++
++	{"I2S OUT", NULL, "SDP OUT MUX"},
++	/*
++	 * playback route map
++	 */
++	{"DAC SDP SRC MUX", "SELECT SDP LEFT DATA", "I2S IN"},
++	{"DAC SDP SRC MUX", "SELECT SDP RIGHT DATA", "I2S IN"},
++
++
++
++	{"DAC SRC MUX", "FROM SDP IN", "DAC SDP SRC MUX"},
++	{"DAC SRC MUX", "FROM EQUALIZER", "EQUALIZER MUX"},
++
++	{"MONO DAC", NULL, "DAC SRC MUX"},
++
++	{"ANALOG INPUT MUX", "LIN1", "LIN1"},
++	{"ANALOG INPUT MUX", "LIN2", "LIN2"},
++	{"ANALOG INPUT MUX", "DIFF OUT1", "DIFFERENTIAL MUX"},
++	{"ANALOG INPUT MUX", "DIFF OUT2", "DIFFERENTIAL PGA"},
++	{"ANALOG INPUT MUX", "PGA OUT1", "LINE PGA"},
++	{"ANALOG INPUT MUX", "PGA OUT2", "LINE PGA"},
++
++
++	{"MONO MIXER", "LIN TO MONO OUT Switch", "ANALOG INPUT MUX"},
++	{"MONO MIXER", "DAC TO MONO OUT Switch", "MONO DAC"},
++
++	{"SPEAKER MIXER", "LIN TO SPEAKER OUT Switch", "ANALOG INPUT MUX"},
++	{"SPEAKER MIXER", "DAC TO SPEAKER OUT Switch", "MONO DAC"},
++
++
++	{"MOUT", NULL, "MONO MIXER"},
++	{"SPKOUT", NULL, "SPEAKER MIXER"},
++
++};
++
++#if 0
++static int es8374_set_pll(struct snd_soc_dai *dai, int pll_id,
++			int source, unsigned int freq_in, unsigned int freq_out)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct es8374_private *priv = snd_soc_codec_get_drvdata(codec);
++	u16 reg;
++	u8 N, K1, K2, K3;
++	float tmp;
++	u32 Kcoefficient;
++	switch (pll_id) {
++	case ES8374_PLL:
++		break;
++	default:
++		return -EINVAL;
++		break;
++	}
++	/* Disable PLL  */
++	// pll hold in reset state
++	snd_soc_update_bits(codec, ES8374_PLL_CONTROL1_REG09,
++							0x40, 0x00);
++
++	if (!freq_in || !freq_out)
++		return 0;
++
++	switch (source) {
++
++		case ES8374_PLL_SRC_FRM_MCLK:
++			// Select PLL
++			snd_soc_update_bits(codec, ES8374_CLK_MANAGEMENT_REG02,
++									0x08, 0x08);
++			break;
++		default:
++			//Disable PLL
++			snd_soc_update_bits(codec, ES8374_CLK_MANAGEMENT_REG02,
++									0x08, 0x00);
++			return -EINVAL;
++	}
++	/*get N & K */
++	tmp = 0;
++	if (source == ES8374_PLL_SRC_FRM_MCLK) {
++			if(freq_in >19200000)
++			{
++				freq_in /= 2;
++				snd_soc_update_bits(codec, ES8374_CLK_MANAGEMENT_REG01,
++								0x80, 0x80);	/* mclk div2	= 1 */
++			}
++			tmp = (float)freq_out * (float)priv->pll_div + 4000;
++			tmp /= (float)freq_in;
++			N =  (u8)tmp;
++			tmp = tmp - (float)N;
++			tmp = tmp * 0.6573598222296 * (1<<22);
++			Kcoefficient = (u32)tmp;
++			K1 = Kcoefficient / 65536;
++			Kcoefficient = Kcoefficient - K1 * 65536;
++			K2 = Kcoefficient /256;
++			K3 = Kcoefficient - K2 * 256;
++		}
++		dev_dbg(codec->dev, "N=%x, K3=%x, K2=%x, K1=%x\n", N, K3, K2, K1);
++
++		reg =  snd_soc_read(codec, ES8374_PLL_N_REG0B);
++		reg &= 0xF0;
++		reg |= (N & 0x0F);
++		snd_soc_write(codec, ES8374_PLL_N_REG0B, reg);
++
++		K1 &= 0x3F;
++		snd_soc_write(codec, ES8374_PLL_K_REG0C, K1);
++		snd_soc_write(codec, ES8374_PLL_K_REG0D, K2);
++		snd_soc_write(codec, ES8374_PLL_K_REG0E, K3);
++
++
++		/* pll div 8 */
++		reg =  snd_soc_read(codec, ES8374_PLL_CONTROL1_REG09);
++		reg &= 0xfc;
++		reg |= 0x01;
++		snd_soc_write(codec, ES8374_PLL_CONTROL1_REG09, reg);
++
++		/* configure the pll power voltage  */
++		switch (priv->dvdd_pwr_vol) {
++			case 0x18:
++				snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x00); /* dvdd=1.8v */
++				break;
++			case 0x25:
++				snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x04); /* dvdd=2.5v */
++				break;
++			case 0x33:
++				snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x08); /* dvdd=3.3v */
++				break;
++			default:
++				snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x00); /* dvdd=1.8v */
++				break;
++		}
++		/* enable PLL  */
++		snd_soc_update_bits(codec, ES8374_PLL_CONTROL1_REG09,
++								0x40, 0x40);
++		priv->mclk = freq_out;
++		return 0;
++}
++#endif
++
++struct _coeff_div {
++	u32 mclk;       /* mclk frequency */
++	u32 rate;       /* sample rate */
++	u8 div;         /* adcclk and dacclk divider */
++	u8 fsmode;         /* adcclk and dacclk divider */
++	u8 divdouble;         /* adcclk and dacclk divider */
++	u8 lrck_h;      /* adclrck divider and daclrck divider */
++	u8 lrck_l;
++	u8 sr;          /* sclk divider */
++	u8 osr;         /* adc osr */
++};
++
++
++/* codec hifi mclk clock divider coefficients */
++static const struct _coeff_div coeff_div[] = {
++
++//	MCLK	,	LRCK,DIV,FSMODE,divDOUBLE,LRCK-H,LRCK-L,BCLK,OSR
++	/*
++	//12M288
++	{12288000, 96000 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
++	{12288000, 64000 , 3 , 1 , 1 , 0x00 , 0xC0 , 2 , 32},
++	{12288000, 48000 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
++	{12288000, 32000 , 3 , 0 , 1 , 0x01 , 0x80 , 2 , 32},
++	{12288000, 24000 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
++	{12288000, 16000 , 3 , 0 , 0 , 0x03 , 0x00 , 2 , 32},
++	{12288000, 12000 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
++	{12288000, 8000  , 6 , 0 , 0 , 0x06 , 0x00 , 2 , 32},
++
++	// 12M
++	{12000000, 96000 , 1 , 1 , 0 , 0x00 , 0x7D , 2 , 31},
++	{12000000, 88200 , 1 , 1 , 0 , 0x00 , 0x88 , 2 , 34},
++	{12000000, 48000 , 5 , 1 , 1 , 0x00 , 0xFA , 2 , 25},
++	{12000000, 44100 , 1 , 0 , 0 , 0x01 , 0x10 , 2 , 34},
++	{12000000, 32000 , 3 , 1 , 0 , 0x01 , 0x77 , 2 , 31},
++	{12000000, 24000 , 5 , 1 , 0 , 0x02 , 0x00 , 2 , 25},
++	{12000000, 22050 , 2 , 0 , 0 , 0x02 , 0x20 , 2 , 34},
++	{12000000, 16000 , 15, 1 , 1 , 0x02 , 0xEE , 2 , 25},
++	{12000000, 12000 , 5 , 0 , 0 , 0x03 , 0xE8 , 2 , 25},
++	{12000000, 11025 , 4 , 0 , 0 , 0x04 , 0x40 , 2 , 34},
++	{12000000, 8000  , 15, 0 , 1 , 0x05 , 0xDC , 2 , 25},
++
++	//11M2896
++	{11289600, 88200 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
++	{11289600, 44100 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
++	{11289600, 22050 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
++	{11289600, 11025 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
++
++*/
++
++	/* 8k */
++	{12288000, 8000  , 6 , 0 , 0 , 0x06 , 0x00 , 2 , 32},
++	{12000000, 8000  , 15, 0 , 1 , 0x05 , 0xDC , 2 , 25},
++	{11289600, 8000 , 6 , 0 , 0 , 0x05, 0x83, 20, 29},
++	{18432000, 8000 , 9 , 0 , 0 , 0x09, 0x00, 27, 32},
++	{16934400, 8000 , 8 , 0 , 0 , 0x08, 0x44, 25, 33},
++	{12000000, 8000 , 7 , 0 , 0 , 0x05, 0xdc, 21, 25},
++	{19200000, 8000 , 12, 0 , 0 , 0x09, 0x60, 27, 25},
++
++	/* 11.025k */
++	{11289600, 11025 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
++	{12000000, 11025 , 4 , 0 , 0 , 0x04 , 0x40 , 2 , 34},
++	{16934400, 11025, 6 ,  0 , 0 , 0x06, 0x00, 21, 32},
++
++
++	/* 12k */
++	{12000000, 12000 , 5 , 0 , 0 , 0x03 , 0xE8 , 2 , 25},
++	{12288000, 12000 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
++
++	/* 16k */
++	{12288000, 16000 , 3 , 0 , 0 , 0x03 , 0x00 , 2 , 32},
++	{18432000, 16000, 5 ,  0 , 0 , 0x04, 0x80, 18, 25},
++	{12000000, 16000 , 15, 1 , 1 , 0x02 , 0xEE , 2 , 25},
++	{19200000, 16000, 6 ,  0 , 0 , 0x04, 0xb0, 18, 25},
++
++	/* 22.05k */
++	{11289600, 22050 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
++	{16934400, 22050, 3 ,  0 , 0 , 0x03, 0x00, 12, 32},
++	{12000000, 22050 , 2 , 0 , 0 , 0x02 , 0x20 , 2 , 34},
++
++	/* 24k */
++	{12000000, 24000 , 5 , 1 , 0 , 0x02 , 0x00 , 2 , 25},
++	{12288000, 24000 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
++
++	/* 32k */
++	{12288000, 32000 , 3 , 0 , 1 , 0x01 , 0x80 , 2 , 32},
++	{18432000, 32000, 2 ,  0 , 0 , 0x02, 0x40, 9 , 32},
++	{12000000, 32000 , 3 , 1 , 0 , 0x01 , 0x77 , 2 , 31},
++	{19200000, 32000, 3 ,  0 , 0 , 0x02, 0x58, 10, 25},
++
++	/* 44.1k */
++	{11289600, 44100 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
++	{16934400, 44100, 1 ,  0 , 0 , 0x01, 0x80, 6 , 32},
++	{12000000, 44100 , 1 , 0 , 0 , 0x01 , 0x10 , 2 , 34},
++
++	/* 48k */
++	{12288000, 48000 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
++	{18432000, 48000, 1 ,  0 , 0 , 0x01, 0x80, 6 , 32},
++	{12000000, 48000 , 5 , 1 , 1 , 0x00 , 0xFA , 2 , 25},
++	{19200000, 48000, 2 ,  0 , 0 , 0x01, 0x90, 6, 25},
++
++	/* 64k */
++	{12288000, 64000 , 3 , 1 , 1 , 0x00 , 0xC0 , 2 , 32},
++
++	/* 88.2k */
++	{11289600, 88200 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
++	{16934400, 88200, 1 ,  0 , 0 , 0x00, 0xc0, 3 , 48},
++	{12000000, 88200 , 1 , 1 , 0 , 0x00 , 0x88 , 2 , 34},
++
++	/* 96k */
++	{12288000, 96000 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
++	{18432000, 96000, 1 ,  0 , 0 , 0x00, 0xc0, 3 , 48},
++	{12000000, 96000 , 1 , 1 , 0 , 0x00 , 0x7D , 2 , 31},
++	{19200000, 96000, 1 ,  0 , 0 , 0x00, 0xc8, 3 , 25},
++};
++static inline int get_coeff(int mclk, int rate)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
++		if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
++			return i;
++	}
++
++	return -EINVAL;
++}
++
++/* The set of rates we can generate from the above for each SYSCLK */
++#if 0
++static unsigned int rates_12288[] = {
++	8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
++};
++
++static struct snd_pcm_hw_constraint_list constraints_12288 = {
++	.count	= ARRAY_SIZE(rates_12288),
++	.list	= rates_12288,
++};
++
++static unsigned int rates_112896[] = {
++	8000, 11025, 22050, 44100,
++};
++
++static struct snd_pcm_hw_constraint_list constraints_112896 = {
++	.count	= ARRAY_SIZE(rates_112896),
++	.list	= rates_112896,
++};
++
++static unsigned int rates_12[] = {
++	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
++	48000, 88235, 96000,
++};
++
++static struct snd_pcm_hw_constraint_list constraints_12 = {
++	.count	= ARRAY_SIZE(rates_12),
++	.list	= rates_12,
++};
++#endif
++
++/*
++ * if PLL not be used, use internal clk1 for mclk,otherwise, use internal clk2 for PLL source.
++ */
++static int es8374_set_dai_sysclk(struct snd_soc_dai *dai,
++			int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = dai->codec;
++
++	if (clk_id == ES8374_CLKID_MCLK) {
++		snd_soc_write(codec,0x09,0x80);	//pll set:reset on ,set start
++		snd_soc_write(codec,0x0C,0x00);	//pll set:k
++		snd_soc_write(codec,0x0D,0x00);	//pll set:k
++		snd_soc_write(codec,0x0E,0x00);	//pll set:k
++
++	}
++
++	return 0;
++}
++
++static int es8374_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 iface = 0;
++	u8 adciface = 0;
++	u8 daciface = 0;
++
++	iface    = snd_soc_read(codec, ES8374_MS_BCKDIV_REG0F);
++	adciface = snd_soc_read(codec, ES8374_ADC_FMT_REG10);
++	daciface = snd_soc_read(codec, ES8374_DAC_FMT_REG11);
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:    /* MASTER MODE */
++		iface |= 0x80;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:    /* SLAVE MODE */
++		iface &= 0x7F;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		adciface &= 0xFC;
++		daciface &= 0xFC;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		return -EINVAL;
++	case SND_SOC_DAIFMT_LEFT_J:
++		adciface &= 0xFC;
++		daciface &= 0xFC;
++		adciface |= 0x01;
++		daciface |= 0x01;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		adciface &= 0xDC;
++		daciface &= 0xDC;
++		adciface |= 0x03;
++		daciface |= 0x03;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		adciface &= 0xDC;
++		daciface &= 0xDC;
++		adciface |= 0x23;
++		daciface |= 0x23;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++
++	/* clock inversion */
++	if(((fmt & SND_SOC_DAIFMT_FORMAT_MASK)==SND_SOC_DAIFMT_I2S) ||
++		((fmt & SND_SOC_DAIFMT_FORMAT_MASK)==SND_SOC_DAIFMT_LEFT_J))
++		{
++
++		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++		case SND_SOC_DAIFMT_NB_NF:
++
++			iface    &= 0xDF;
++			adciface &= 0xDF;
++			daciface &= 0xDF;
++			break;
++		case SND_SOC_DAIFMT_IB_IF:
++			iface    |= 0x20;
++			adciface |= 0x20;
++			daciface |= 0x20;
++			break;
++		case SND_SOC_DAIFMT_IB_NF:
++			iface    |= 0x20;
++			adciface &= 0xDF;
++			daciface &= 0xDF;
++			break;
++		case SND_SOC_DAIFMT_NB_IF:
++			iface    &= 0xDF;
++			adciface |= 0x20;
++			daciface |= 0x20;
++			break;
++		default:
++			return -EINVAL;
++		}
++	}
++	snd_soc_write(codec, ES8374_MS_BCKDIV_REG0F, iface);
++	snd_soc_write(codec, ES8374_ADC_FMT_REG10, adciface);
++	snd_soc_write(codec, ES8374_DAC_FMT_REG11, daciface);
++	return 0;
++}
++static int es8374_pcm_startup(struct snd_pcm_substream *substream,
++		struct snd_soc_dai *dai)
++{
++	return 0;
++}
++
++static int es8374_pcm_hw_params(struct snd_pcm_substream *substream,
++			struct snd_pcm_hw_params *params,
++			struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++	struct es8374_private *es8374 = snd_soc_codec_get_drvdata(codec);
++	u16 iface;
++
++	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		iface = snd_soc_read(codec, ES8374_DAC_FMT_REG11) & 0xE3;
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			iface |= 0x0c;
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			iface |= 0x04;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			iface |= 0x10;
++			break;
++		}
++		/* set iface & srate */
++		snd_soc_write(codec, ES8374_DAC_FMT_REG11, iface);
++		/*set speak and mono for playback*/
++		snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0xA0);
++		snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x90);
++
++	} else {
++		iface = snd_soc_read(codec, ES8374_ADC_FMT_REG10) & 0xE3;
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			iface |= 0x0c;
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			iface |= 0x04;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			iface |= 0x10;
++			break;
++		}
++		/* set iface */
++		snd_soc_write(codec, ES8374_ADC_FMT_REG10, iface);
++	}
++
++	if(es8374->dmic_enable){
++		snd_soc_write(codec, ES8374_ADC_CONTROL_REG24, 0x8A);  //6DB & DIMC=H
++		snd_soc_write(codec,0x12,0x40);
++		snd_soc_write(codec,0x13,0x40);
++		snd_soc_write(codec,0x22,0x00);
++		snd_soc_write(codec, 0x26, 0x50);
++		snd_soc_write(codec, 0x28, 0x80);
++
++	} else {
++		snd_soc_write(codec,0x24,0x08);	//adc set
++		snd_soc_write(codec, ES8374_GPIO_INSERT_REG6D, 0x1F);  //set gpio1 to GM SHORT
++	}
++
++/*
++*	please add the hardware clock divider setting to get the correct LRCK, SCLK frequency
++*/
++	return 0;
++}
++
++static int es8374_set_bias_level(struct snd_soc_codec *codec,
++			enum snd_soc_bias_level level)
++{
++
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++		snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x7f);
++		snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x8a);
++		snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0x40);
++		snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x00);
++		snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0xa0);
++		snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x90);
++		snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x02);
++		snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0xa0);
++		snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x00);
++		snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x00);
++		snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0x00);
++		snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0x00);
++		snd_soc_write(codec, ES8374_AIN_PGA_REG22, 0x06);
++
++		break;
++
++	case SND_SOC_BIAS_PREPARE:
++		break;
++
++	case SND_SOC_BIAS_STANDBY:
++		snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0xc0);
++		break;
++
++	case SND_SOC_BIAS_OFF:
++		snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0xc0);
++		snd_soc_write(codec, ES8374_ALC_LVL_HLD_REG28, 0x1c);
++		snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x00);
++		snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0xbf);
++		snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x14);
++		snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x03);
++		snd_soc_write(codec, ES8374_AIN_PGA_REG22, 0x00);
++		break;
++	}
++
++	codec->dapm.bias_level = level;
++
++	return 0;
++}
++
++/*
++static int es8374_set_tristate(struct snd_soc_dai *dai, int tristate)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	dev_dbg(codec->dev, "es8374_set_tristate........\n");
++	if(tristate) {
++		snd_soc_update_bits(codec, ES8374_MS_BCKDIV_REG0F,
++					0x40, 0x40);
++	} else {
++		snd_soc_update_bits(codec, ES8374_MS_BCKDIV_REG0F,
++					0x40, 0x00);
++	}
++
++	return 0;
++}
++*/
++
++static int es8374_mute(struct snd_soc_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++
++	dev_dbg(codec->dev, "%s %d\n", __func__, mute);
++	if (mute) {
++		snd_soc_update_bits(codec, ES8374_DAC_CONTROL_REG36, 0x20, 0x20);
++	} else {
++		if (dai->playback_active)
++			snd_soc_update_bits(codec, ES8374_DAC_CONTROL_REG36, 0x20, 0x00);
++	}
++	return 0;
++}
++
++
++#define es8374_RATES SNDRV_PCM_RATE_8000_96000
++
++#define es8374_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
++		SNDRV_PCM_FMTBIT_S24_LE)
++
++static struct snd_soc_dai_ops es8374_ops = {
++	.startup = es8374_pcm_startup,
++	.hw_params = es8374_pcm_hw_params,
++	.set_fmt = es8374_set_dai_fmt,
++	.set_sysclk = es8374_set_dai_sysclk,
++	.digital_mute = es8374_mute,
++};
++
++static struct snd_soc_dai_driver es8374_dai[] = {
++	{	.name = "ES8374 HiFi",
++		.playback = {
++			.stream_name = "Playback",
++			.channels_min = 1,
++			.channels_max = 2,
++			.rates = es8374_RATES,
++			.formats = es8374_FORMATS,
++		},
++		.capture = {
++			.stream_name = "Capture",
++			.channels_min = 1,
++			.channels_max = 2,
++			.rates = es8374_RATES,
++			.formats = es8374_FORMATS,
++		},
++		.ops = &es8374_ops,
++		.symmetric_rates = 1,
++	},
++};
++
++static int es8374_suspend(struct snd_soc_codec *codec)
++{
++	struct es8374_private *es8374 = snd_soc_codec_get_drvdata(codec);
++	int i;
++
++	for(i = 0; i <= 110; i++) {
++		es8374->reg_cache[i] = snd_soc_read(codec, i);
++	}
++
++	snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0xc0);
++	snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0xc0);
++	snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x20);
++	snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x21);
++	snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0x08);
++	snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x10);
++	snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x10);
++	snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0x40);
++	snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x00);
++	snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0xbf);
++	snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x14);
++	snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x03);
++
++	return 0;
++}
++
++static int es8374_resume(struct snd_soc_codec *codec)
++{
++	struct es8374_private *es8374 = snd_soc_codec_get_drvdata(codec);
++	int i;
++#if 0
++	snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x7f);
++	snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x8a);
++	snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0x40);
++	snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x50);
++	snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0xa0);
++	snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x90);
++	snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x02);
++	snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0xa0);
++	snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x00);
++	snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x00);
++	snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0x00);
++	snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0x00);
++#endif
++
++	for(i = 0; i <= 110; i++) {
++		snd_soc_write(codec, i, es8374->reg_cache[i]);
++	}
++
++	return 0;
++}
++
++static int es8374_parse_dts(struct es8374_private *es8374)
++{
++#ifdef CONFIG_OF
++	struct device *dev;
++	struct device_node *np;
++	enum of_gpio_flags flags;
++	int ret, dmic;
++
++	if (es8374->control_type == SND_SOC_I2C) {
++		dev = &(es8374->i2c->dev);
++	} else {
++		dev = &(es8374->spi->dev);
++	}
++
++	np = dev->of_node;
++
++	if (!np)
++		return -1;
++
++	ret = of_property_read_u32(np, "es8374,dmic", &dmic);
++	if(ret == 0 && dmic == 1) {
++		es8374->dmic_enable = 1;
++	} else {
++		es8374->dmic_enable = 0;
++	}
++
++	es8374->pwr_gpio = of_get_named_gpio_flags(np, "es8374,pwr-gpio", 0, &flags);
++	if (es8374->pwr_gpio < 0 || !gpio_is_valid(es8374->pwr_gpio)) {
++		es8374->pwr_gpio = -1;
++	} else {
++		es8374->pwr_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	}
++
++#endif
++
++	return 0;
++}
++
++static int es8374_probe(struct snd_soc_codec *codec)
++{
++	int ret = 0;
++	struct es8374_private *es8374 = es8374_data;
++
++	codec->control_data = es8374->regmap;
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
++	if (ret < 0)
++		return ret;
++
++	es8374->codec = codec;
++	snd_soc_codec_set_drvdata(codec, es8374);
++
++	es8374_parse_dts(es8374);
++	if (gpio_is_valid(es8374->pwr_gpio)) {
++		ret = devm_gpio_request(codec->dev, es8374->pwr_gpio, "es8374 power pin");
++		if(ret == 0)
++			gpio_direction_output(es8374->pwr_gpio, es8374->pwr_active);
++	}
++
++	snd_soc_write(codec,0x00,0x3F);	//IC Rst start
++	msleep(1);  					//DELAY_MS
++	snd_soc_write(codec,0x00,0x03);	//IC Rst stop
++	snd_soc_write(codec,0x01,0x7F);	//IC clk on
++	snd_soc_write(codec,0x05,0x11);	//clk div set
++	snd_soc_write(codec,0x36,0x00);	//dac set
++	snd_soc_write(codec,0x12,0x30);	//timming set
++	snd_soc_write(codec,0x13,0x20);	//timming set
++	snd_soc_write(codec,0x21,0x50);	//adc set:	SEL LIN1 CH+PGAGAIN=0DB
++	snd_soc_write(codec,0x22,0xFF);	//adc set:	PGA GAIN=0DB
++	snd_soc_write(codec,0x21,0x10);	//adc set:	SEL LIN1 CH+PGAGAIN=0DB
++	snd_soc_write(codec,0x00,0x80);	// IC START
++	msleep(50);  					//DELAY_MS
++	snd_soc_write(codec,0x14,0x8A);	// IC START
++	snd_soc_write(codec,0x15,0x40);	// IC START
++	snd_soc_write(codec,0x1A,0xA0);	// monoout set
++	snd_soc_write(codec,0x1B,0x19);	// monoout set
++	snd_soc_write(codec,0x1C,0x90);	// spk set
++	snd_soc_write(codec,0x1D,0x02);	// spk set
++	snd_soc_write(codec,0x1F,0x00);	// spk set
++	snd_soc_write(codec,0x1E,0xA0);	// spk on
++	snd_soc_write(codec,0x28,0x00);	// alc set
++	snd_soc_write(codec,0x25,0x00);	// ADCVOLUME  on
++	snd_soc_write(codec,0x38,0x00);	// DACVOLUMEL on
++	snd_soc_write(codec,0x37,0x00);	// dac set
++	snd_soc_write(codec,0x6D,0x40);	//SEL:GPIO1=DMIC CLK OUT+SEL:GPIO2=PLL CLK OUT
++
++	es8374_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return ret;
++}
++
++static int es8374_remove(struct snd_soc_codec *codec)
++{
++	es8374_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static struct snd_soc_codec_driver soc_codec_dev_es8374 = {
++	.probe =	es8374_probe,
++	.remove =	es8374_remove,
++	.suspend =	es8374_suspend,
++	.resume =	es8374_resume,
++	.set_bias_level = es8374_set_bias_level,
++
++	.controls = es8374_snd_controls,
++	.num_controls = ARRAY_SIZE(es8374_snd_controls),
++	.dapm_widgets = es8374_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(es8374_dapm_widgets),
++	.dapm_routes = es8374_dapm_routes,
++	.num_dapm_routes = ARRAY_SIZE(es8374_dapm_routes),
++};
++
++static struct regmap_config es8374_regmap = {
++	.reg_bits = 8,
++	.val_bits = 8,
++
++	.max_register = ES8374_MAX_REGISTER,
++	.reg_defaults = es8374_reg_defaults,
++	.num_reg_defaults = ARRAY_SIZE(es8374_reg_defaults),
++	.volatile_reg = es8374_volatile_register,
++	.writeable_reg = es8374_writable_register,
++	.readable_reg  = es8374_readable_register,
++	.cache_type = REGCACHE_RBTREE,
++};
++
++#ifdef CONFIG_OF
++static struct of_device_id es8374_if_dt_ids[] = {
++	{ .compatible = "ambarella,es8374", },
++	{ }
++};
++#endif
++
++#if defined(ES8374_SPI)
++static int es8374_spi_probe(struct spi_device *spi)
++{
++	struct es8374_private *es8374;
++	int ret;
++
++	es8374 = kzalloc(sizeof(struct es8374_private), GFP_KERNEL);
++	if (es8374 == NULL)
++		return -ENOMEM;
++
++	es8374->control_type = SND_SOC_SPI;
++	es8374->spi = spi;
++
++	spi_set_drvdata(spi, es8374);
++
++	es8374->regmap = devm_regmap_init_spi(spi, &es8374_regmap);
++	if (IS_ERR(es8374->regmap)) {
++		ret = PTR_ERR(es8374->regmap);
++		dev_err(&spi->dev, "regmap_init() failed: %d\n", ret);
++		return ret;
++	}
++
++	es8374_data = es8374;
++
++	ret = snd_soc_register_codec(&spi->dev,
++			&soc_codec_dev_es8374, &es8374_dai, 1);
++	if (ret < 0)
++		kfree(es8374);
++	return ret;
++}
++
++static int es8374_spi_remove(struct spi_device *spi)
++{
++	snd_soc_unregister_codec(&spi->dev);
++	kfree(spi_get_drvdata(spi));
++	return 0;
++}
++
++static struct spi_driver es8374_spi_driver = {
++	.driver = {
++		.name	= "es8374",
++		.owner	= THIS_MODULE,
++#ifdef CONFIG_OF
++		.of_match_table = of_match_ptr(es8374_if_dt_ids),
++#endif
++	},
++	.probe	= es8374_spi_probe,
++	.remove	= es8374_spi_remove,
++};
++#endif /* CONFIG_SPI_MASTER */
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static void es8374_i2c_shutdown(struct i2c_client *i2c)
++{
++	struct snd_soc_codec *codec;
++	struct es8374_private *es8374;
++
++	es8374 = i2c_get_clientdata(i2c);
++	codec = es8374->codec;
++
++	snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0xc0);
++	snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0xc0);
++	snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x20);
++	snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x21);
++	snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0x08);
++	snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x10);
++	snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x10);
++	snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0x40);
++	snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0xc0);
++	snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0xbf);
++	snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x14);
++	snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x03);
++
++	return;
++}
++
++static int es8374_i2c_probe(struct i2c_client *i2c_client,
++		const struct i2c_device_id *id)
++{
++	struct es8374_private *es8374;
++	int ret = -1;
++
++	es8374 = kzalloc(sizeof(*es8374), GFP_KERNEL);
++	if (es8374 == NULL)
++		return -ENOMEM;
++
++	es8374->control_type = SND_SOC_I2C;
++	es8374->i2c = i2c_client;
++
++	i2c_set_clientdata(i2c_client, es8374);
++	es8374->regmap = devm_regmap_init_i2c(i2c_client, &es8374_regmap);
++	if (IS_ERR(es8374->regmap)) {
++		ret = PTR_ERR(es8374->regmap);
++		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
++		return ret;
++	}
++
++	es8374_data = es8374;
++
++	ret =  snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_es8374,
++			&es8374_dai[0], ARRAY_SIZE(es8374_dai));
++	if (ret < 0) {
++		kfree(es8374);
++		return ret;
++	}
++
++	return ret;
++}
++
++static  int es8374_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	kfree(i2c_get_clientdata(client));
++	return 0;
++}
++
++static const struct i2c_device_id es8374_i2c_id[] = {
++	{"es8374", 0 },
++	{"10ES8374:00", 0},
++	{"10ES8374", 0},
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, es8374_i2c_id);
++
++static struct i2c_driver es8374_i2c_driver = {
++	.driver = {
++		.name	= "es8374",
++		.owner	= THIS_MODULE,
++#ifdef CONFIG_OF
++		.of_match_table = of_match_ptr(es8374_if_dt_ids),
++#endif
++	},
++	.shutdown	= es8374_i2c_shutdown,
++	.probe	= es8374_i2c_probe,
++	.remove	= es8374_i2c_remove,
++	.id_table	= es8374_i2c_id,
++};
++#endif
++
++static int __init es8374_init(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	return i2c_add_driver(&es8374_i2c_driver);
++#endif
++#ifdef ES8374_SPI
++	return spi_register_driver(&es8374_spi_driver);
++#endif
++}
++
++static void __exit es8374_exit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	return i2c_del_driver(&es8374_i2c_driver);
++#endif
++#ifdef ES8374_SPI
++	return spi_unregister_driver(&es8374_spi_driver);
++#endif
++}
++
++module_init(es8374_init);
++module_exit(es8374_exit);
++
++MODULE_DESCRIPTION("ASoC es8374 driver");
++MODULE_AUTHOR("XianqingZheng <xqzheng@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/es8374.h b/sound/soc/codecs/es8374.h
+new file mode 100644
+index 00000000..0d427004
+--- /dev/null
++++ b/sound/soc/codecs/es8374.h
+@@ -0,0 +1,151 @@
++/*
++* ES8374.h  --  ES8374 ALSA SoC Audio Codec
++*
++*
++*
++* Authors:
++*
++* Based on ES8374.h by David Yang
++*
++* 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.
++*/
++
++#ifndef _ES8374_H
++#define _ES8374_H
++
++/*       THE REGISTER DEFINITION FORMAT            */
++/*
++*	ES8374_REGISTER NAME_REG_REGISTER ADDRESS
++*/
++#define ES8374_RESET_REG00			0x00  /* this register is used to reset digital,csm,clock manager etc.*/
++
++/*
++* Clock Scheme Register definition
++*/
++#define ES8374_CLK_MANAGEMENT_REG01		0x01 /* The register is used to turn on/off the clock for ADC, DAC, MCLK, BCLK and CLASS D */
++#define ES8374_CLK_MANAGEMENT_REG02		0x02 /* ADC, PLL clock */
++
++
++#define ES8374_ADC_OSR_REG03			0x03 /* The ADC OSR setting */
++#define ES8374_DAC_FLT_CNT_REG04		0x04 /* The DAC filter counter waiting cycles control */
++#define ES8374_CLK_DIV_REG05			0x05 /* ADC&DAC internal mclk Divider */
++#define ES8374_LRCK_DIV_REG06			0x06 /* The  LRCK divider */
++#define ES8374_LRCK_DIV_REG07			0x07
++#define ES8374_CLASS_D_DIV_REG08		0x08 /* Class D clock divider */
++/*
++* PLL control register definition
++*/
++#define ES8374_PLL_CONTROL1_REG09		0x09 /* Register 0x09 for PLL reset, power up/down, dither and divider settting */
++#define ES8374_PLL_CONTROL2_REG0A		0x0A /* Register 0x0A for PLL low power, gain, supply voltage and  vco setting */
++#define ES8374_PLL_N_REG0B			0x0B /* Register 0x0B for N and pll calibrate */
++#define ES8374_PLL_K_REG0C			0x0C /* Register 0x0C - 0x0E for PLLK */
++#define ES8374_PLL_K_REG0D			0x0D
++#define ES8374_PLL_K_REG0E			0x0E
++/*
++*	The serial digital audio port
++*/
++#define ES8374_MS_BCKDIV_REG0F			0x0F /* The setting for Master/Slave mode and BCLK divider */
++#define ES8374_ADC_FMT_REG10			0x10 /* ADC Format	*/
++#define ES8374_DAC_FMT_REG11			0x11 /* DAC Format	*/
++
++/*
++*	The system Control
++*/
++#define ES8374_CHP_INI_REG12			0x12 /* The time control for chip initialization	*/
++#define ES8374_POWERUP_REG13			0x13 /* The time control for power up	*/
++/*
++*	The analog control
++*/
++#define ES8374_ANA_REF_REG14			0x14 /* The analog reference */
++#define ES8374_ANA_PWR_CTL_REG15		0x15 /* The analog power up/down */
++#define ES8374_ANA_LOW_PWR_REG16		0x16 /* Low power setting*/
++#define ES8374_ANA_REF_LP_REG17			0x17 /* Reference and low power setting */
++#define ES8374_ANA_BIAS_REG18		  	0x18 /* Bias selecting */
++/*
++*	MONO OUT
++*/
++#define ES8374_MONO_MIX_REG1A			0x1A /* MonoMixer */
++#define ES8374_MONO_GAIN_REG1B			0x1B /* Mono Out Gain */
++/*
++* SPEAKER OUT
++*/
++#define ES8374_SPK_MIX_REG1C			0x1C /* Speaker Mixer */
++#define ES8374_SPK_MIX_GAIN_REG1D		0x1D /* Speaker Mixer Gain */
++#define ES8374_SPK_OUT_GAIN_REG1E		0x1E /* Speaker Output Gain */
++#define ES8374_SPK_CTL_REG1F		 	 0x1F /* Speaker control */
++#define ES8374_SPK_CTL_REG20		  	0x20 /* Speaker control */
++/*
++* Analog In
++*/
++#define ES8374_AIN_PWR_SRC_REG21		0x21 /* Power control and source selecting for AIN*/
++#define ES8374_AIN_PGA_REG22		  	0x22 /* AIN PGA Gain Control */
++/*
++*	ADC Control
++*/
++#define ES8374_ADC_CONTROL_REG24		0x24 /* adc and DMIC Setting */
++#define ES8374_ADC_VOLUME_REG25			0x25 /* adc volume */
++/*
++* ADC ALC
++*/
++#define ES8374_ALC_EN_MAX_GAIN_REG26		0x26 /* adc alc enable and max gain setting */
++#define ES8374_ALC_MIN_GAIN_REG27		0x27 /* ADC Alc min gain */
++#define ES8374_ALC_LVL_HLD_REG28		0x28 /* alc level and hold time control */
++#define ES8374_ALC_DCY_ATK_REG29		0x29 /* ALC DCY and ATK time control */
++#define ES8374_ALC_WIN_SIZE_REG2A		0x2A /* ALC WIN Size */
++#define ES8374_ALC_NGTH_REG2B		 	0x2B /* alc noise gate setting */
++/*
++*	ADC HPF setting
++*/
++#define ES8374_ADC_HPF_REG2C		    	0x2C /* The high pass filter coefficient*/
++/*
++*	Equalizer SRC setting
++*/
++#define ES8374_EQ_SRC_REG2D			0x2D /* adc src, dac src and EQ SRC setting */
++
++/*
++* ADC 1st shelving filter
++*/
++#define ES8374_ADC_SHV_A_REG2E		 	0x2E /* adc shelving A*/
++#define ES8374_ADC_SHV_A_REG2F		  	0x2F
++#define ES8374_ADC_SHV_A_REG30		 	0x30
++#define ES8374_ADC_SHV_A_REG31			0x31
++
++#define ES8374_ADC_SHV_B_REG32		 	0x32 /* ADC Shelving B*/
++#define ES8374_ADC_SHV_B_REG33		  	0x33
++#define ES8374_ADC_SHV_B_REG34		  	0x34
++#define ES8374_ADC_SHV_B_REG35			0x35
++
++/*
++* DAC control
++*/
++#define ES8374_DAC_CONTROL_REG36		0x36 /* dac control1 */
++#define ES8374_DAC_CONTROL_REG37		0x37 /* dac control2 */
++
++#define ES8374_DAC_VOLUME_REG38		    	0x38 /* dac volume */
++#define ES8374_DAC_OFFSET_REG39			0x39 /* DAC offset */
++
++/*
++* DAC 2nd shleving filter
++*/
++/* register 0x3A to 0x44 is for dac shelving filter */
++/*
++* Equalizer coeffient
++*/
++/* register 0x45 to 0x6c is for 2nd equalizer filter, this filter can be shared by DAC and ADC */
++
++#define ES8374_GPIO_INSERT_REG6D	    	0x6D /* GPIO & HP INSERT CONTROL */
++#define ES8374_FLAG_REG6E	  		0x6E /* Flag register */
++
++/* The End Of Register definition */
++
++#define ES8374_PLL			1
++#define ES8374_PLL_SRC_FRM_MCLK		1
++
++#define ES8374_CLKID_MCLK		0
++#define ES8374_CLKID_PLLO		1
++
++#define ES8374_MAX_REGISTER		128
++
++#endif
+diff --git a/sound/soc/codecs/es8388.c b/sound/soc/codecs/es8388.c
+new file mode 100644
+index 00000000..164141cd
+--- /dev/null
++++ b/sound/soc/codecs/es8388.c
+@@ -0,0 +1,971 @@
++/*
++ * es8388.c  --  ES8388 ALSA Soc Audio driver
++ *
++ * Copyright 2014 Ambarella Ltd.
++ *
++ * Author: Ken He <jianhe@ambarella.com>
++ *
++ * Based on es8328.c from Everest Semiconductor
++ *
++ * History:
++ *	2014/07/01 - [Ken He] Created file
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/gpio.h>
++#include <linux/of_gpio.h>
++#include <linux/of_device.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/tlv.h>
++#include <linux/regmap.h>
++
++#include "es8388.h"
++
++#define ES8388_VERSION "v1.0"
++
++/* codec private data */
++struct es8388_priv {
++	unsigned int aud_rst_pin;
++	unsigned int aud_rst_active;
++	struct regmap *regmap;
++	unsigned int sysclk;
++};
++
++/*
++ * es8388 register
++ */
++static struct reg_default  es8388_reg_defaults[] = {
++	{ 0,  0x06 },
++	{ 1,  0x1c },
++	{ 2,  0xC3 },
++	{ 3,  0xFC },
++	{ 4,  0xC0 },
++	{ 5,  0x00 },
++	{ 6,  0x00 },
++	{ 7,  0x7C },
++	{ 8,  0x80 },
++	{ 9,  0x00 },
++	{ 10, 0x00 },
++	{ 11, 0x06 },
++	{ 12, 0x00 },
++	{ 13, 0x06 },
++	{ 14, 0x30 },
++	{ 15, 0x30 },
++	{ 16, 0xC0 },
++	{ 17, 0xC0 },
++	{ 18, 0x38 },
++	{ 19, 0xB0 },
++	{ 20, 0x32 },
++	{ 21, 0x06 },
++	{ 22, 0x00 },
++	{ 23, 0x00 },
++	{ 24, 0x06 },
++	{ 25, 0x32 },
++	{ 26, 0xC0 },
++	{ 27, 0xC0 },
++	{ 28, 0x08 },
++	{ 29, 0x06 },
++	{ 30, 0x1F },
++	{ 31, 0xF7 },
++	{ 32, 0xFD },
++	{ 33, 0xFF },
++	{ 34, 0x1F },
++	{ 35, 0xF7 },
++	{ 36, 0xFD },
++	{ 37, 0xFF },
++	{ 38, 0x00 },
++	{ 39, 0x38 },
++	{ 40, 0x38 },
++	{ 41, 0x38 },
++	{ 42, 0x38 },
++	{ 43, 0x38 },
++	{ 44, 0x38 },
++	{ 45, 0x00 },
++	{ 46, 0x00 },
++	{ 47, 0x00 },
++	{ 48, 0x00 },
++	{ 49, 0x00 },
++	{ 50, 0x00 },
++	{ 51, 0x00 },
++	{ 52, 0x00 },
++};
++
++static int spk_event(struct snd_soc_dapm_widget *w,
++				struct snd_kcontrol *kcontrol, int event)
++{
++	int i;
++	struct snd_soc_codec *codec = w->codec;
++	struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
++	//printk("%s %d  *****\n", __FUNCTION__, __LINE__);
++
++	switch (event) {
++		case SND_SOC_DAPM_PRE_PMU:
++			gpio_direction_output(es8388->aud_rst_pin, 0);
++			break;
++		case SND_SOC_DAPM_POST_PMU:
++			//Add speaker amplifier mute control
++			mdelay(100);
++			for( i = 0; i < 0x1d; i++)
++			{
++				snd_soc_write(codec, ES8388_DACCONTROL24, i);    //LOUT1/ROUT1 VOLUME
++				snd_soc_write(codec, ES8388_DACCONTROL25, i);
++				snd_soc_write(codec, ES8388_DACCONTROL26, i);    //LOUT2/ROUT2 VOLUME
++				snd_soc_write(codec, ES8388_DACCONTROL27, i);
++				mdelay(5);
++			}
++			gpio_direction_output(es8388->aud_rst_pin, 1);
++			break;
++		case SND_SOC_DAPM_PRE_PMD:
++			gpio_direction_output(es8388->aud_rst_pin, 0);
++			snd_soc_write(codec, ES8388_DACPOWER, 0x00);
++			mdelay(100);
++			for( i = 0; i < 0x1d; i++)
++			{
++				snd_soc_write(codec, ES8388_DACCONTROL24, 0x1d-i);    //LOUT1/ROUT1 VOLUME
++				snd_soc_write(codec, ES8388_DACCONTROL25,  0x1d-i);
++				snd_soc_write(codec, ES8388_DACCONTROL26,  0x1d-i);    //LOUT2/ROUT2 VOLUME
++				snd_soc_write(codec, ES8388_DACCONTROL27,  0x1d-i);
++				mdelay(5);
++			}
++			break;
++		default:
++			break;
++	}
++
++	return 0;
++}
++
++static int adc_event(struct snd_soc_dapm_widget *w,
++				struct snd_kcontrol *kcontrol, int event)
++{
++	unsigned int regv;
++	struct snd_soc_codec *codec = w->codec;
++	//printk("%s %d****************     *****\n", __FUNCTION__, __LINE__);
++
++	switch (event) {
++		case SND_SOC_DAPM_POST_PMU:
++			snd_soc_write(codec, ES8388_ADCPOWER, 0x00);
++			snd_soc_write(codec, ES8388_CHIPPOWER, 0x00);
++			mdelay(100);
++			regv = snd_soc_read(codec, ES8388_ADCCONTROL3);
++			regv &= 0xFB;
++			snd_soc_write(codec, ES8388_ADCCONTROL3, regv);
++			break;
++		case SND_SOC_DAPM_POST_PMD:
++			regv = snd_soc_read(codec, ES8388_ADCCONTROL3);
++			regv |= 0x4;
++			snd_soc_write(codec, ES8388_ADCCONTROL3, regv);
++			snd_soc_write(codec, ES8388_ADCPOWER, 0xF9);
++			break;
++		default:
++			break;
++		}
++	return 0;
++}
++
++
++/* DAC/ADC Volume: min -96.0dB (0xC0) ~ max 0dB (0x00)  ( 0.5 dB step ) */
++static const DECLARE_TLV_DB_SCALE(digital_tlv, -9600, 50, 0);
++/* Analog Out Volume: min -30.0dB (0x00) ~ max 3dB (0x21)  ( 1 dB step ) */
++static const DECLARE_TLV_DB_SCALE(out_tlv, -3000, 100, 0);
++/* Analog In Volume: min 0dB (0x00) ~ max 24dB (0x08)  ( 3 dB step ) */
++static const DECLARE_TLV_DB_SCALE(in_tlv, 0, 300, 0);
++
++static const struct snd_kcontrol_new es8388_snd_controls[] = {
++	SOC_DOUBLE_R_TLV("Playback Volume",
++		ES8388_LDAC_VOL, ES8388_RDAC_VOL, 0, 0xC0, 1, digital_tlv),
++	SOC_DOUBLE_R_TLV("Analog Out Volume",
++		ES8388_LOUT1_VOL, ES8388_ROUT1_VOL, 0, 0x1D, 0, out_tlv),
++
++	SOC_DOUBLE_R_TLV("Capture Volume",
++		ES8388_LADC_VOL, ES8388_RADC_VOL, 0, 0xC0, 1, digital_tlv),
++	SOC_DOUBLE_TLV("Analog In Volume",
++		ES8388_ADCCONTROL1, 4, 0, 0x08, 0, in_tlv),
++};
++
++/*
++ * DAPM Controls
++ */
++
++/* Channel Input Mixer */
++static const char *es8388_line_texts[] = { "Line 1", "Line 2", "Differential"};
++static const unsigned int es8388_line_values[] = { 0, 1, 3};
++
++static const struct soc_enum es8388_lline_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8388_ADCCONTROL2, 6, 4,
++		ARRAY_SIZE(es8388_line_texts), es8388_line_texts,
++		es8388_line_values);
++static const struct snd_kcontrol_new es8388_left_line_controls =
++	SOC_DAPM_VALUE_ENUM("Route", es8388_lline_enum);
++
++static const struct soc_enum es8388_rline_enum =
++	SOC_VALUE_ENUM_SINGLE(ES8388_ADCCONTROL2, 4, 4,
++		ARRAY_SIZE(es8388_line_texts), es8388_line_texts,
++		es8388_line_values);
++static const struct snd_kcontrol_new es8388_right_line_controls =
++	SOC_DAPM_VALUE_ENUM("Route", es8388_rline_enum);
++
++
++/* Left Mixer */
++static const struct snd_kcontrol_new es8388_left_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Left Playback Switch", ES8388_DACCONTROL17, 7, 1, 0),
++	SOC_DAPM_SINGLE("Left Bypass Switch"  , ES8388_DACCONTROL17, 6, 1, 0),
++};
++
++/* Right Mixer */
++static const struct snd_kcontrol_new es8388_right_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Right Playback Switch", ES8388_DACCONTROL20, 7, 1, 0),
++	SOC_DAPM_SINGLE("Right Bypass Switch"  , ES8388_DACCONTROL20, 6, 1, 0),
++};
++#if 0
++/* Differential Mux */
++static const char *es8388_diff_sel[] = {"Line 1", "Line 2"};
++static const struct soc_enum diffmux =
++	SOC_ENUM_SINGLE(ES8388_ADCCONTROL3, 7, 2, es8388_diff_sel);
++static const struct snd_kcontrol_new es8388_diffmux_controls =
++	SOC_DAPM_ENUM("Route", diffmux);
++#endif
++/* Mono ADC Mux */
++static const char *es8388_mono_mux[] = {"Stereo", "Mono (Left)", "Mono (Right)", "NONE"};
++static const unsigned int es8388_monomux_values[] = { 0, 1, 2, 3};
++/*static const struct soc_enum monomux =
++	SOC_ENUM_SINGLE(ES8388_ADCCONTROL3, 3, 4, es8388_mono_mux);
++static const struct snd_kcontrol_new es8388_monomux_controls =
++	SOC_DAPM_ENUM("Route", monomux);
++*/
++static const struct soc_enum monomux =
++	SOC_VALUE_ENUM_SINGLE(ES8388_ADCCONTROL3, 3, 4,
++		ARRAY_SIZE(es8388_mono_mux), es8388_mono_mux,
++		es8388_monomux_values);
++static const struct snd_kcontrol_new es8388_monomux_controls =
++	SOC_DAPM_VALUE_ENUM("Route", monomux);
++
++#if 0
++static const struct snd_kcontrol_new adc_switch_ctl =
++SOC_DAPM_SINGLE("Switch",ES8388_ADCCONTROL7, 2, 1, 1);
++#endif
++
++static const struct snd_soc_dapm_widget es8388_dapm_widgets[] = {
++	/* DAC Part */
++	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
++		&es8388_left_mixer_controls[0], ARRAY_SIZE(es8388_left_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
++		&es8388_right_mixer_controls[0], ARRAY_SIZE(es8388_right_mixer_controls)),
++
++	SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, &es8388_left_line_controls),
++	SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, &es8388_right_line_controls),
++
++	SND_SOC_DAPM_DAC("Left DAC"  , "Left Playback" , ES8388_DACPOWER, 7, 1),
++	SND_SOC_DAPM_DAC("Right DAC" , "Right Playback", ES8388_DACPOWER, 6, 1),
++	SND_SOC_DAPM_PGA_E("Left Out 1", ES8388_DACPOWER, 5, 0, NULL,
++         0, spk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
++	SND_SOC_DAPM_PGA_E("Right Out 1", ES8388_DACPOWER, 4, 0, NULL,
++         0, spk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
++
++	 /* SND_SOC_DAPM_PGA("Left Out 2" , ES8388_DACPOWER, 3, 0, NULL, 0), */
++	/* SND_SOC_DAPM_PGA("Right Out 2", ES8388_DACPOWER, 2, 0, NULL, 0), */
++
++	SND_SOC_DAPM_OUTPUT("LOUT1"),
++	SND_SOC_DAPM_OUTPUT("ROUT1"),
++	SND_SOC_DAPM_OUTPUT("LOUT2"),
++	SND_SOC_DAPM_OUTPUT("ROUT2"),
++
++	/* ADC Part */
++//	SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
++//		&es8388_diffmux_controls),
++
++//	SND_SOC_DAPM_MUX("Left Line Mux", ES8388_ADCPOWER, 7, 1, &es8388_left_line_controls),
++//	SND_SOC_DAPM_MUX("Right Line Mux", ES8388_ADCPOWER, 6, 1, &es8388_right_line_controls),
++
++	SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, &es8388_monomux_controls),
++	SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, &es8388_monomux_controls),
++//SND_SOC_DAPM_MUX("Left ADC Mux", ES8388_ADCPOWER, 7, 1, &es8388_monomux_controls),
++//SND_SOC_DAPM_MUX("Right ADC Mux", ES8388_ADCPOWER, 6, 1, &es8388_monomux_controls),
++	SND_SOC_DAPM_PGA("Left Analog Input" , ES8388_ADCPOWER, 7, 1, NULL, 0),
++	SND_SOC_DAPM_PGA("Right Analog Input", ES8388_ADCPOWER, 6, 1, NULL, 0),
++	SND_SOC_DAPM_ADC_E("Left ADC" , "Left Capture" , ES8388_ADCPOWER, 5, 1,
++	                   adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_ADC_E("Right ADC", "Right Capture", ES8388_ADCPOWER, 4, 1,
++	                   adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
++
++	SND_SOC_DAPM_MICBIAS("Mic Bias", ES8388_ADCPOWER, 3, 1),
++
++	SND_SOC_DAPM_INPUT("MICIN"),
++	SND_SOC_DAPM_INPUT("LINPUT1"),
++	SND_SOC_DAPM_INPUT("LINPUT2"),
++	SND_SOC_DAPM_INPUT("RINPUT1"),
++	SND_SOC_DAPM_INPUT("RINPUT2"),
++};
++
++static const struct snd_soc_dapm_route audio_map[] = {
++	/* left mixer */
++	{"Left Mixer", "Left Playback Switch", "Left DAC"},
++
++	/* right mixer */
++	{"Right Mixer", "Right Playback Switch", "Right DAC"},
++
++	/* left out 1 */
++	{"Left Out 1", NULL, "Left Mixer"},
++	{"LOUT1", NULL, "Left Out 1"},
++
++	/* right out 1 */
++	{"Right Out 1", NULL, "Right Mixer"},
++	{"ROUT1", NULL, "Right Out 1"},
++
++	/* Left Line Mux */
++	{"Left Line Mux", "Line 1", "LINPUT1"},
++	{"Left Line Mux", "Line 2", "LINPUT2"},
++	{"Left Line Mux", NULL, "MICIN"},
++
++	/* Right Line Mux */
++	{"Right Line Mux", "Line 1", "RINPUT1"},
++	{"Right Line Mux", "Line 2", "RINPUT2"},
++	{"Right Line Mux", NULL, "MICIN"},
++
++	/* Left ADC Mux */
++	{"Left ADC Mux", "Stereo", "Left Line Mux"},
++//	{"Left ADC Mux", "Mono (Left)" , "Left Line Mux"},
++
++	/* Right ADC Mux */
++	{"Right ADC Mux", "Stereo", "Right Line Mux"},
++//	{"Right ADC Mux", "Mono (Right)", "Right Line Mux"},
++
++	/* ADC */
++	{"Left ADC" , NULL, "Left ADC Mux"},
++	{"Right ADC", NULL, "Right ADC Mux"},
++};
++
++static int es8388_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
++
++	es8388->sysclk = freq;
++	return 0;
++}
++
++static int es8388_set_dai_fmt(struct snd_soc_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 iface = 0;
++	u8 adciface = 0;
++	u8 daciface = 0;
++
++	iface = snd_soc_read(codec, ES8388_IFACE);
++	adciface = snd_soc_read(codec, ES8388_ADC_IFACE);
++	daciface = snd_soc_read(codec, ES8388_DAC_IFACE);
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:    // MASTER MODE
++		iface |= 0x80;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:    // SLAVE MODE
++		iface &= 0x7F;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		adciface &= 0xFC;
++		daciface &= 0xF9;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++	case SND_SOC_DAIFMT_LEFT_J:
++	case SND_SOC_DAIFMT_DSP_A:
++	case SND_SOC_DAIFMT_DSP_B:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		iface &= 0xDF;
++		adciface &= 0xDF;
++		daciface &= 0xBF;
++		break;
++	case SND_SOC_DAIFMT_IB_IF:
++		iface |= 0x20;
++		adciface |= 0x20;
++		daciface |= 0x40;
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		iface |= 0x20;
++		adciface &= 0xDF;
++		daciface &= 0xBF;
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		iface &= 0xDF;
++		adciface |= 0x20;
++		daciface |= 0x40;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	snd_soc_write(codec, ES8388_IFACE, iface);
++	snd_soc_write(codec, ES8388_ADC_IFACE, adciface);
++	snd_soc_write(codec, ES8388_DAC_IFACE, daciface);
++
++	return 0;
++}
++
++static int es8388_pcm_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 iface;
++
++	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		iface = snd_soc_read(codec, ES8388_DAC_IFACE) & 0xC7;
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			iface |= 0x0018;
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			iface |= 0x0008;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			iface |= 0x0020;
++			break;
++		}
++		/* set iface & srate */
++		snd_soc_write(codec, ES8388_DAC_IFACE, iface);
++	} else {
++		iface = snd_soc_read(codec, ES8388_ADC_IFACE) & 0xE3;
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			iface |= 0x000C;
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			iface |= 0x0004;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			iface |= 0x0010;
++			break;
++		}
++		/* set iface */
++		snd_soc_write(codec, ES8388_ADC_IFACE, iface);
++	}
++
++	return 0;
++}
++
++static int es8388_mute(struct snd_soc_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	unsigned char val = 0;
++
++	val = snd_soc_read(codec, ES8388_DAC_MUTE);
++	if (mute){
++		val |= 0x04;
++	} else {
++		val &= ~0x04;
++	}
++
++	snd_soc_write(codec, ES8388_DAC_MUTE, val);
++
++	return 0;
++}
++
++
++static int es8388_set_bias_level(struct snd_soc_codec *codec,
++		enum snd_soc_bias_level level)
++{
++	switch(level) {
++	case SND_SOC_BIAS_ON:
++		break;
++
++	case SND_SOC_BIAS_PREPARE:
++		if(codec->dapm.bias_level != SND_SOC_BIAS_ON) {
++			/* updated by David-everest,5-25
++			// Chip Power on
++			snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
++			// VMID control
++			snd_soc_write(codec, ES8388_CONTROL1 , 0x06);
++			// ADC/DAC DLL power on
++			snd_soc_write(codec, ES8388_CONTROL2 , 0xF3);
++			*/
++			snd_soc_write(codec, ES8388_ADCPOWER, 0x00);
++			snd_soc_write(codec, ES8388_DACPOWER , 0x30);
++			snd_soc_write(codec, ES8388_CHIPPOWER , 0x00);
++		}
++		break;
++
++	case SND_SOC_BIAS_STANDBY:
++		/*
++		// ADC/DAC DLL power on
++		snd_soc_write(codec, ES8388_CONTROL2 , 0xFF);
++		// Chip Power off
++		snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
++		*/
++		snd_soc_write(codec, ES8388_ADCPOWER, 0x00);
++		snd_soc_write(codec, ES8388_DACPOWER , 0x30);
++		snd_soc_write(codec, ES8388_CHIPPOWER , 0x00);
++		break;
++
++	case SND_SOC_BIAS_OFF:
++		/*
++		// ADC/DAC DLL power off
++		snd_soc_write(codec, ES8388_CONTROL2 , 0xFF);
++		// Chip Control
++		snd_soc_write(codec, ES8388_CONTROL1 , 0x00);
++		// Chip Power off
++		snd_soc_write(codec, ES8388_CHIPPOWER, 0xFF);
++		*/
++		snd_soc_write(codec, ES8388_ADCPOWER, 0xFF);
++		snd_soc_write(codec, ES8388_DACPOWER , 0xC0);
++		snd_soc_write(codec, ES8388_CHIPPOWER , 0xC3);
++		break;
++	}
++
++	codec->dapm.bias_level = level;
++
++	return 0;
++}
++
++
++#define ES8388_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++                    SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
++                    SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
++
++#define ES8388_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
++                    SNDRV_PCM_FMTBIT_S24_LE)
++
++static const struct snd_soc_dai_ops es8388_dai_ops = {
++	.hw_params    = es8388_pcm_hw_params,
++	.set_fmt      = es8388_set_dai_fmt,
++	.set_sysclk   = es8388_set_dai_sysclk,
++	.digital_mute = es8388_mute,
++};
++
++
++struct snd_soc_dai_driver es8388_dai = {
++	.name = "es8388-hifi",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = ES8388_RATES,
++		.formats = ES8388_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = ES8388_RATES,
++		.formats = ES8388_FORMATS,},
++	.ops = &es8388_dai_ops,
++	.symmetric_rates = 1,
++};
++
++static int es8388_suspend(struct snd_soc_codec *codec)
++{
++	es8388_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static int es8388_resume(struct snd_soc_codec *codec)
++{
++	es8388_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return 0;
++}
++
++static int es8388_remove(struct snd_soc_codec *codec)
++{
++	es8388_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static inline int es8388_reset(struct regmap *map)
++{
++	int ret = 0;
++	regmap_write(map, 0x00, 0x80);
++	ret = regmap_write(map, 0x00, 0x00);
++	return ret;
++}
++
++static int es8388_probe(struct snd_soc_codec *codec)
++{
++	struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
++	int ret = 0;
++	//int i = 0;
++
++	dev_info(codec->dev, "ES8388 Audio Codec %s", ES8388_VERSION);
++	codec->control_data = es8388->regmap;
++
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++	ret = devm_gpio_request(codec->dev, es8388->aud_rst_pin, "es8388 aud reset");
++	if (ret < 0){
++		dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
++		return ret;
++	}
++
++	/* Reset NS4890 aud */
++	gpio_direction_output(es8388->aud_rst_pin, es8388->aud_rst_active);
++	msleep(1);
++
++	es8388_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	snd_soc_write(codec, ES8388_MASTERMODE,0x00);
++	snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
++	snd_soc_write(codec, ES8388_DACCONTROL23, 0x00);
++//	snd_soc_write(codec, ES8388_ANAVOLMANAG, 0x74);
++	snd_soc_write(codec, ES8388_DACCONTROL21, 0x80);
++	snd_soc_write(codec, ES8388_CONTROL1, 0x30);
++	snd_soc_write(codec, ES8388_CHIPLOPOW2, 0xFF);
++	snd_soc_write(codec, ES8388_CHIPLOPOW1, 0x00);
++	//-------------ADC---------------------------//
++	snd_soc_write(codec, ES8388_ADCCONTROL1, 0x88);
++	snd_soc_write(codec, ES8388_ADCCONTROL2, 0xF0);
++	snd_soc_write(codec, ES8388_ADCCONTROL3, 0x06);  //adc output in tri-state
++	snd_soc_write(codec, ES8388_ADCCONTROL4, 0x0C);
++	snd_soc_write(codec, ES8388_ADCCONTROL5, 0x66);  //compitable with ES8388S
++	snd_soc_write(codec, ES8388_ADCCONTROL7, 0x30);
++	snd_soc_write(codec, ES8388_ADCCONTROL8, 0x00);
++	snd_soc_write(codec, ES8388_ADCCONTROL9, 0x00);
++	snd_soc_write(codec, ES8388_ADCCONTROL10, 0xD2);
++	snd_soc_write(codec, ES8388_ADCCONTROL11, 0xB0);
++	snd_soc_write(codec, ES8388_ADCCONTROL12, 0x12);
++	snd_soc_write(codec, ES8388_ADCCONTROL13, 0x06);
++	snd_soc_write(codec, ES8388_ADCCONTROL14, 0x11);
++	//-------------DAC-----------------------------//
++	snd_soc_write(codec, ES8388_DACCONTROL1, 0x18);
++	snd_soc_write(codec, ES8388_DACCONTROL2, 0x82);  //compitable with ES8388S
++	snd_soc_write(codec, ES8388_DACCONTROL3, 0x76);
++	snd_soc_write(codec, ES8388_DACCONTROL4, 0x00);
++	snd_soc_write(codec, ES8388_DACCONTROL5, 0x00);
++	snd_soc_write(codec, ES8388_DACCONTROL17, 0xB8);
++	snd_soc_write(codec, ES8388_DACCONTROL20, 0xB8);
++
++	snd_soc_write(codec, ES8388_CHIPPOWER, 0x00);
++	snd_soc_write(codec, ES8388_CONTROL1, 0x36);
++	snd_soc_write(codec, ES8388_CONTROL2, 0x72);
++	snd_soc_write(codec, ES8388_DACPOWER, 0x00);    //only start up DAC, disable LOUT/ROUT
++	snd_soc_write(codec, ES8388_ADCPOWER, 0x09);
++	snd_soc_write(codec, ES8388_CONTROL1, 0x32);
++	snd_soc_write(codec, ES8388_DACCONTROL3, 0x72);
++/*
++	for( i = 0; i < 0x1d; i++)
++	{
++		snd_soc_write(codec, ES8388_DACCONTROL24, i);    //LOUT1/ROUT1 VOLUME
++		snd_soc_write(codec, ES8388_DACCONTROL25, i);
++		snd_soc_write(codec, ES8388_DACCONTROL26, i);    //LOUT2/ROUT2 VOLUME
++		snd_soc_write(codec, ES8388_DACCONTROL27, i);
++		msleep(5);
++	}
++*/
++	return ret;
++}
++
++static int es8388s_probe(struct snd_soc_codec *codec)
++{
++	struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
++	int ret = 0;
++
++	dev_info(codec->dev, "ES8388s Audio Codec %s", ES8388_VERSION);
++	codec->control_data = es8388->regmap;
++
++	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++	es8388_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	/* Enable Diff PGA for ES8388S */
++	snd_soc_write(codec, 0x35,0xA0);
++	snd_soc_write(codec, 0x38,0x02);
++
++	snd_soc_write(codec, ES8388_MASTERMODE,0x00);
++	snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
++	snd_soc_write(codec, ES8388_DACCONTROL23, 0x00);
++//	snd_soc_write(codec, ES8388_ANAVOLMANAG, 0x74);
++	snd_soc_write(codec, ES8388_DACCONTROL21, 0x80);
++	snd_soc_write(codec, ES8388_CONTROL1, 0x30);
++	snd_soc_write(codec, ES8388_CHIPLOPOW2, 0xFF);
++	snd_soc_write(codec, ES8388_CHIPLOPOW1, 0x00);
++	//-------------ADC---------------------------//
++	snd_soc_write(codec, ES8388_ADCCONTROL1, 0x40);
++	snd_soc_write(codec, ES8388_ADCCONTROL2, 0xF0);
++	snd_soc_write(codec, ES8388_ADCCONTROL3, 0x82);  /* adc output in tri-state */
++	snd_soc_write(codec, ES8388_ADCCONTROL4, 0x4C);
++	snd_soc_write(codec, ES8388_ADCCONTROL5, 0x02);  /* compitable with ES8388S */
++	snd_soc_write(codec, ES8388_ADCCONTROL6, 0x2c);
++	snd_soc_write(codec, ES8388_ADCCONTROL8, 0x00);
++	snd_soc_write(codec, ES8388_ADCCONTROL9, 0x00);
++	snd_soc_write(codec, ES8388_ADCCONTROL10, 0xDa);
++	snd_soc_write(codec, ES8388_ADCCONTROL11, 0xB0);
++	snd_soc_write(codec, ES8388_ADCCONTROL12, 0x12);
++	snd_soc_write(codec, ES8388_ADCCONTROL13, 0x06);
++	snd_soc_write(codec, ES8388_ADCCONTROL14, 0x11);
++	//-------------DAC-----------------------------//
++	snd_soc_write(codec, ES8388_DACCONTROL1, 0x18);
++	snd_soc_write(codec, ES8388_DACCONTROL2, 0x02);  /* compitable with ES8388S */
++	snd_soc_write(codec, ES8388_DACCONTROL3, 0x76);
++	snd_soc_write(codec, ES8388_DACCONTROL4, 0x00);
++	snd_soc_write(codec, ES8388_DACCONTROL5, 0x00);
++	snd_soc_write(codec, ES8388_DACCONTROL17, 0xB8);
++	snd_soc_write(codec, ES8388_DACCONTROL20, 0xB8);
++
++	snd_soc_write(codec, ES8388_CHIPPOWER, 0x00);
++	snd_soc_write(codec, ES8388_CONTROL1, 0x36);
++	snd_soc_write(codec, ES8388_CONTROL2, 0x72);
++	snd_soc_write(codec, ES8388_DACPOWER, 0x00);    //only start up DAC, disable LOUT/ROUT
++	snd_soc_write(codec, ES8388_ADCPOWER, 0x09);
++	snd_soc_write(codec, ES8388_CONTROL1, 0x32);
++	snd_soc_write(codec, ES8388_DACCONTROL3, 0x72);
++
++	return ret;
++}
++
++static bool es8388_volatile_register(struct device *dev,
++							unsigned int reg)
++{
++	switch (reg) {
++		case ES8388_CONTROL1:
++		case ES8388_CONTROL2:
++		case ES8388_CHIPPOWER:
++		case ES8388_ADCPOWER:
++		case ES8388_DACPOWER:
++		case ES8388_CHIPLOPOW1:
++		case ES8388_CHIPLOPOW2:
++		case ES8388_ANAVOLMANAG:
++		case ES8388_MASTERMODE:
++		case ES8388_ADCCONTROL1:
++		case ES8388_ADCCONTROL2:
++		case ES8388_ADCCONTROL3:
++		case ES8388_ADCCONTROL4:
++		case ES8388_ADCCONTROL5:
++		case ES8388_ADCCONTROL6:
++		case ES8388_ADCCONTROL7:
++		case ES8388_ADCCONTROL8:
++		case ES8388_ADCCONTROL9:
++		case ES8388_ADCCONTROL10:
++		case ES8388_ADCCONTROL11:
++		case ES8388_ADCCONTROL12:
++		case ES8388_ADCCONTROL13:
++		case ES8388_ADCCONTROL14:
++		case ES8388_DACCONTROL1:
++		case ES8388_DACCONTROL2:
++		case ES8388_DACCONTROL3:
++		case ES8388_DACCONTROL4:
++		case ES8388_DACCONTROL5:
++		case ES8388_DACCONTROL6:
++		case ES8388_DACCONTROL7:
++		case ES8388_DACCONTROL8:
++		case ES8388_DACCONTROL9:
++		case ES8388_DACCONTROL10:
++		case ES8388_DACCONTROL11:
++		case ES8388_DACCONTROL12:
++		case ES8388_DACCONTROL13:
++		case ES8388_DACCONTROL14:
++		case ES8388_DACCONTROL15:
++		case ES8388_DACCONTROL16:
++		case ES8388_DACCONTROL17:
++		case ES8388_DACCONTROL18:
++		case ES8388_DACCONTROL19:
++		case ES8388_DACCONTROL20:
++		case ES8388_DACCONTROL21:
++		case ES8388_DACCONTROL22:
++		case ES8388_DACCONTROL23:
++		case ES8388_DACCONTROL24:
++		case ES8388_DACCONTROL25:
++		case ES8388_DACCONTROL26:
++		case ES8388_DACCONTROL27:
++		case ES8388_DACCONTROL28:
++		case ES8388_DACCONTROL29:
++		case ES8388_DACCONTROL30:
++		return true;
++
++	default:
++		break;
++	}
++
++	return false;
++}
++
++
++static struct snd_soc_codec_driver soc_codec_dev_es8388 = {
++	.probe =	es8388_probe,
++	.remove =	es8388_remove,
++	.suspend =	es8388_suspend,
++	.resume =	es8388_resume,
++	.set_bias_level = es8388_set_bias_level,
++
++	.dapm_widgets = es8388_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(es8388_dapm_widgets),
++	.dapm_routes = audio_map,
++	.num_dapm_routes = ARRAY_SIZE(audio_map),
++
++	.controls = es8388_snd_controls,
++	.num_controls = ARRAY_SIZE(es8388_snd_controls),
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_es8388s = {
++	.probe =	es8388s_probe,
++	.remove =	es8388_remove,
++	.suspend =	es8388_suspend,
++	.resume =	es8388_resume,
++	.set_bias_level = es8388_set_bias_level,
++
++	.dapm_widgets = es8388_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(es8388_dapm_widgets),
++	.dapm_routes = audio_map,
++	.num_dapm_routes = ARRAY_SIZE(audio_map),
++
++	.controls = es8388_snd_controls,
++	.num_controls = ARRAY_SIZE(es8388_snd_controls),
++};
++
++static struct regmap_config es8388_regmap = {
++	.reg_bits = 8,
++	.val_bits = 8,
++
++	.max_register = ES8388_MAX_REGISTER,
++	.reg_defaults = es8388_reg_defaults,
++	.num_reg_defaults = ARRAY_SIZE(es8388_reg_defaults),
++	.volatile_reg = es8388_volatile_register,
++	.cache_type = REGCACHE_RBTREE,
++};
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static struct of_device_id es8388_of_match[];
++static int es8388_i2c_probe(struct i2c_client *i2c,
++			    const struct i2c_device_id *id)
++{
++	struct device_node *np = i2c->dev.of_node;
++	struct es8388_priv *es8388;
++	int ret = 0;
++	enum of_gpio_flags flags;
++	int rst_pin;
++	const struct snd_soc_codec_driver *driver;
++
++	es8388 = devm_kzalloc(&i2c->dev, sizeof(struct es8388_priv), GFP_KERNEL);
++	if (es8388 == NULL)
++		return -ENOMEM;
++
++	rst_pin = of_get_gpio_flags(np, 0, &flags);
++	if (rst_pin < 0 || !gpio_is_valid(rst_pin))
++		return -ENXIO;
++
++	es8388->aud_rst_pin = rst_pin;
++	es8388->aud_rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	i2c_set_clientdata(i2c, es8388);
++	es8388->regmap = devm_regmap_init_i2c(i2c, &es8388_regmap);
++	if (IS_ERR(es8388->regmap)) {
++		ret = PTR_ERR(es8388->regmap);
++		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
++		return ret;
++	}
++
++	driver = NULL;
++	if (np) {
++		const struct of_device_id *of_id;
++
++		of_id = of_match_device(es8388_of_match, &i2c->dev);
++		if (of_id)
++			driver = of_id->data;
++	} else {
++		driver = (struct snd_soc_codec_driver *)id->driver_data;
++	}
++
++	if (!driver) {
++		dev_err(&i2c->dev, "no driver\n");
++		return -EINVAL;
++	}
++
++	ret =  snd_soc_register_codec(&i2c->dev,
++			driver, &es8388_dai, 1);
++
++	return ret;
++}
++
++static int es8388_i2c_remove(struct i2c_client *i2c)
++{
++	snd_soc_unregister_codec(&i2c->dev);
++	return 0;
++}
++
++static struct of_device_id es8388_of_match[] = {
++	{ .compatible = "ambarella,es8388", .data = &soc_codec_dev_es8388},
++	{ .compatible = "ambarella,es8388s",.data = &soc_codec_dev_es8388s},
++	{},
++};
++MODULE_DEVICE_TABLE(of, es8388_of_match);
++static const struct i2c_device_id es8388_i2c_id[] = {
++	{ "es8388", (kernel_ulong_t)&soc_codec_dev_es8388},
++	{ "es8388s",(kernel_ulong_t)&soc_codec_dev_es8388s},
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, es8388_i2c_id);
++
++static struct i2c_driver es8388_i2c_driver = {
++	.driver = {
++		.name = "es8388-codec",
++		.owner = THIS_MODULE,
++		.of_match_table = es8388_of_match,
++	},
++	.probe    = es8388_i2c_probe,
++	.remove   = es8388_i2c_remove,
++	.id_table = es8388_i2c_id,
++};
++#endif
++
++static int __init es8388_modinit(void)
++{
++	int ret = 0;
++
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&es8388_i2c_driver);
++	if (ret != 0) {
++		pr_err("Failed to register ES8388 I2C driver: %d\n", ret);
++	}
++#endif
++	return ret;
++}
++module_init(es8388_modinit);
++
++static void __exit es8388_exit(void)
++{
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	i2c_del_driver(&es8388_i2c_driver);
++#endif
++}
++module_exit(es8388_exit);
++
++MODULE_DESCRIPTION("ASoC ES8388 driver");
++MODULE_AUTHOR("Ken He <jianhe@ambarella.com>");
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/soc/codecs/es8388.h b/sound/soc/codecs/es8388.h
+new file mode 100644
+index 00000000..cbb144ba
+--- /dev/null
++++ b/sound/soc/codecs/es8388.h
+@@ -0,0 +1,159 @@
++/*
++ * es8388.h  --  ES8388 Soc Audio driver
++ *
++ * Copyright 2011 Ambarella Ltd.
++ *
++ * Author: Cao Rongrong <rrcao@ambarella.com>
++ *
++ * 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.
++ */
++
++#ifndef _ES8388_H
++#define _ES8388_H
++
++#define CONFIG_HHTECH_MINIPMP	1
++
++/* ES8388 register space */
++
++#define ES8388_CONTROL1         0x00
++#define ES8388_CONTROL2         0x01
++#define ES8388_CHIPPOWER        0x02
++#define ES8388_ADCPOWER         0x03
++#define ES8388_DACPOWER         0x04
++#define ES8388_CHIPLOPOW1       0x05
++#define ES8388_CHIPLOPOW2       0x06
++#define ES8388_ANAVOLMANAG      0x07
++#define ES8388_MASTERMODE       0x08
++#define ES8388_ADCCONTROL1      0x09
++#define ES8388_ADCCONTROL2      0x0a
++#define ES8388_ADCCONTROL3      0x0b
++#define ES8388_ADCCONTROL4      0x0c
++#define ES8388_ADCCONTROL5      0x0d
++#define ES8388_ADCCONTROL6      0x0e
++#define ES8388_ADCCONTROL7      0x0f
++#define ES8388_ADCCONTROL8      0x10
++#define ES8388_ADCCONTROL9      0x11
++#define ES8388_ADCCONTROL10     0x12
++#define ES8388_ADCCONTROL11     0x13
++#define ES8388_ADCCONTROL12     0x14
++#define ES8388_ADCCONTROL13     0x15
++#define ES8388_ADCCONTROL14     0x16
++
++#define ES8388_DACCONTROL1      0x17
++#define ES8388_DACCONTROL2      0x18
++#define ES8388_DACCONTROL3      0x19
++#define ES8388_DACCONTROL4      0x1a
++#define ES8388_DACCONTROL5      0x1b
++#define ES8388_DACCONTROL6      0x1c
++#define ES8388_DACCONTROL7      0x1d
++#define ES8388_DACCONTROL8      0x1e
++#define ES8388_DACCONTROL9      0x1f
++#define ES8388_DACCONTROL10     0x20
++#define ES8388_DACCONTROL11     0x21
++#define ES8388_DACCONTROL12     0x22
++#define ES8388_DACCONTROL13     0x23
++#define ES8388_DACCONTROL14     0x24
++#define ES8388_DACCONTROL15     0x25
++#define ES8388_DACCONTROL16     0x26
++#define ES8388_DACCONTROL17     0x27
++#define ES8388_DACCONTROL18     0x28
++#define ES8388_DACCONTROL19     0x29
++#define ES8388_DACCONTROL20     0x2a
++#define ES8388_DACCONTROL21     0x2b
++#define ES8388_DACCONTROL22     0x2c
++#define ES8388_DACCONTROL23     0x2d
++#define ES8388_DACCONTROL24     0x2e
++#define ES8388_DACCONTROL25     0x2f
++#define ES8388_DACCONTROL26     0x30
++#define ES8388_DACCONTROL27     0x31
++#define ES8388_DACCONTROL28     0x32
++#define ES8388_DACCONTROL29     0x33
++#define ES8388_DACCONTROL30     0x34
++
++#define ES8388_LADC_VOL         ES8388_ADCCONTROL8
++#define ES8388_RADC_VOL         ES8388_ADCCONTROL9
++
++#define ES8388_LDAC_VOL         ES8388_DACCONTROL4
++#define ES8388_RDAC_VOL         ES8388_DACCONTROL5
++
++#define ES8388_LOUT1_VOL        ES8388_DACCONTROL24
++#define ES8388_ROUT1_VOL        ES8388_DACCONTROL25
++#define ES8388_LOUT2_VOL        ES8388_DACCONTROL26
++#define ES8388_ROUT2_VOL        ES8388_DACCONTROL27
++
++#define ES8388_ADC_MUTE         ES8388_ADCCONTROL7
++#define ES8388_DAC_MUTE         ES8388_DACCONTROL3
++
++
++
++#define ES8388_IFACE            ES8388_MASTERMODE
++
++#define ES8388_ADC_IFACE        ES8388_ADCCONTROL4
++#define ES8388_ADC_SRATE        ES8388_ADCCONTROL5
++
++#define ES8388_DAC_IFACE        ES8388_DACCONTROL1
++#define ES8388_DAC_SRATE        ES8388_DACCONTROL2
++
++
++#define ES8388_MAX_REGISTER		53
++#define ES8388_CACHEREGNUM      53
++#define ES8388_SYSCLK	        0
++
++struct es8388_setup_data {
++	int i2c_bus;
++	unsigned short i2c_address;
++};
++
++#if 1 //lzcx
++#define ES8388_PLL1			0
++#define ES8388_PLL2			1
++
++/* clock inputs */
++#define ES8388_MCLK		0
++#define ES8388_PCMCLK		1
++#define ES8388_BCLK_IN		1
++#define ES8388_MCLK_IN_BCLK_OUT 2
++
++/* clock divider id's */
++#define ES8388_PCMDIV		0
++#define ES8388_BCLKDIV		1
++#define ES8388_VXCLKDIV		2
++
++/* PCM clock dividers */
++#define ES8388_PCM_DIV_1	(0 << 6)
++#define ES8388_PCM_DIV_3	(2 << 6)
++#define ES8388_PCM_DIV_5_5	(3 << 6)
++#define ES8388_PCM_DIV_2	(4 << 6)
++#define ES8388_PCM_DIV_4	(5 << 6)
++#define ES8388_PCM_DIV_6	(6 << 6)
++#define ES8388_PCM_DIV_8	(7 << 6)
++
++/* BCLK clock dividers */
++#define ES8388_BCLK_DIV_1	(0 << 7)
++#define ES8388_BCLK_DIV_2	(1 << 7)
++#define ES8388_BCLK_DIV_4	(2 << 7)
++#define ES8388_BCLK_DIV_8	(3 << 7)
++
++/* VXCLK clock dividers */
++#define ES8388_VXCLK_DIV_1	(0 << 6)
++#define ES8388_VXCLK_DIV_2	(1 << 6)
++#define ES8388_VXCLK_DIV_4	(2 << 6)
++#define ES8388_VXCLK_DIV_8	(3 << 6)
++#define ES8388_VXCLK_DIV_16	(4 << 6)
++
++#define ES8388_DAI_HIFI		0
++#define ES8388_DAI_VOICE		1
++
++#define ES8388_1536FS 1536
++#define ES8388_1024FS	1024
++#define ES8388_768FS	768
++#define ES8388_512FS	512
++#define ES8388_384FS	384
++#define ES8388_256FS	256
++#define ES8388_128FS	128
++#endif
++
++#endif
++
+diff --git a/sound/soc/codecs/rt5670-dsp.c b/sound/soc/codecs/rt5670-dsp.c
+new file mode 100644
+index 00000000..86bdc1f4
+--- /dev/null
++++ b/sound/soc/codecs/rt5670-dsp.c
+@@ -0,0 +1,1429 @@
++/*
++ * rt5670.c  --  RT5670 ALSA SoC DSP driver
++ *
++ * Copyright 2011 Realtek Semiconductor Corp.
++ * Author: Johnny Hsu <johnnyhsu@realtek.com>
++ *
++ * 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.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#define RTK_IOCTL
++#ifdef RTK_IOCTL
++#include <linux/spi/spi.h>
++#include "rt_codec_ioctl.h"
++#endif
++
++#include "rt5670.h"
++#include "rt5670-dsp.h"
++
++#define DSP_CLK_RATE RT5670_DSP_CLK_96K
++
++static unsigned short rt5670_dsp_patch[][2] = {
++	{0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9},
++	{0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
++	{0xe1, 0x3f00}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f01}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f02}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f03}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f04}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f05}, {0xe2, 0x4009}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f06}, {0xe2, 0x267c}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f07}, {0xe2, 0x23a2}, {0xe3, 0x00d0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f08}, {0xe2, 0x9212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f09}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0a}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0b}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0c}, {0xe2, 0x1bf0}, {0xe3, 0x00a1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0d}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0e}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0f}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f10}, {0xe2, 0x1918}, {0xe3, 0x004f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f11}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f12}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f13}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f14}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f15}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f16}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f17}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f18}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f19}, {0xe2, 0x1bf1}, {0xe3, 0x0071}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1a}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1b}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1c}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1d}, {0xe2, 0x191b}, {0xe3, 0x004f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1e}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1f}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f20}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f21}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f22}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f23}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f24}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f25}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f26}, {0xe2, 0x1bf2}, {0xe3, 0x0041}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f27}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f28}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f29}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2a}, {0xe2, 0x1921}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2b}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2c}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2d}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2e}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2f}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f30}, {0xe2, 0x4009}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f31}, {0xe2, 0x267c}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f32}, {0xe2, 0x23a2}, {0xe3, 0x00d0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f33}, {0xe2, 0x9212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f34}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f35}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f36}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f37}, {0xe2, 0x1bf3}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f38}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f39}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3a}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3b}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3c}, {0xe2, 0x1a09}, {0xe3, 0x00ef}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3d}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3e}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3f}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f40}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f41}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f42}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f43}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f44}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f45}, {0xe2, 0x1bf4}, {0xe3, 0x0031}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f46}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f47}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f48}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f49}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4a}, {0xe2, 0x1a0c}, {0xe3, 0x00ef}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4b}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4c}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4d}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4e}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4f}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f50}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f51}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f52}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f53}, {0xe2, 0x1bf5}, {0xe3, 0x0011}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f54}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f55}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f56}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f57}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f58}, {0xe2, 0x1a13}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f59}, {0xe2, 0x8e77}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5a}, {0xe2, 0x34b8}, {0xe3, 0x0001}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5b}, {0xe2, 0x3960}, {0xe3, 0x0002}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5c}, {0xe2, 0x17f6}, {0xe3, 0x000e}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5d}, {0xe2, 0x6000}, {0xe3, 0x0016}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5e}, {0xe2, 0x7000}, {0xe3, 0x005a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5f}, {0xe2, 0x6800}, {0xe3, 0x0055}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f60}, {0xe2, 0x7800}, {0xe3, 0x0019}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f61}, {0xe2, 0x1859}, {0xe3, 0x00bf}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f62}, {0xe2, 0x8230}, {0xe3, 0x0010}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f63}, {0xe2, 0x26e0}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f64}, {0xe2, 0x1bf6}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f65}, {0xe2, 0x3c00}, {0xe3, 0x0015}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f66}, {0xe2, 0x194f}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f67}, {0xe2, 0x0c20}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f68}, {0xe2, 0x8240}, {0xe3, 0x0003}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f69}, {0xe2, 0x8324}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6a}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6b}, {0xe2, 0x9240}, {0xe3, 0x000c}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6c}, {0xe2, 0x824c}, {0xe3, 0x0003}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6d}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6e}, {0xe2, 0x924c}, {0xe3, 0x000c}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6f}, {0xe2, 0x0c30}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f70}, {0xe2, 0x1950}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f71}, {0xe2, 0x962c}, {0xe3, 0x0076}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f72}, {0xe2, 0x962c}, {0xe3, 0x0086}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f73}, {0xe2, 0x4001}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f74}, {0xe2, 0x922c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f75}, {0xe2, 0x3521}, {0xe3, 0x0091}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f76}, {0xe2, 0x3521}, {0xe3, 0x0062}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f77}, {0xe2, 0x3521}, {0xe3, 0x00c0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f78}, {0xe2, 0x3c00}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f79}, {0xe2, 0x0c0c}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7a}, {0xe2, 0x17f8}, {0xe3, 0x00ee}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7b}, {0xe2, 0x6000}, {0xe3, 0x00a5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7c}, {0xe2, 0x22fa}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7d}, {0xe2, 0x6000}, {0xe3, 0x0049}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7e}, {0xe2, 0x66e2}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7f}, {0xe2, 0x1bf8}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f80}, {0xe2, 0x26ea}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f81}, {0xe2, 0x1bf8}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f82}, {0xe2, 0x822c}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f83}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f84}, {0xe2, 0x822c}, {0xe3, 0x0094}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f85}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f86}, {0xe2, 0x1bf8}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f83}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f84}, {0xe2, 0x822c}, {0xe3, 0x0094}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f85}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f86}, {0xe2, 0x1bf8}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f87}, {0xe2, 0x822c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f88}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f89}, {0xe2, 0x922c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8a}, {0xe2, 0x822c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8b}, {0xe2, 0x922c}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8c}, {0xe2, 0x822c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8d}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8e}, {0xe2, 0x922c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8f}, {0xe2, 0x0c08}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f90}, {0xe2, 0x8230}, {0xe3, 0x0030}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f91}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f92}, {0xe2, 0x1bfa}, {0xe3, 0x0020}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f93}, {0xe2, 0x822c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f94}, {0xe2, 0x822c}, {0xe3, 0x00c4}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f95}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f96}, {0xe2, 0x1bf9}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f97}, {0xe2, 0x822c}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f98}, {0xe2, 0x22e2}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f99}, {0xe2, 0x922c}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f9a}, {0xe2, 0x1bfa}, {0xe3, 0x0022}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f9b}, {0xe2, 0x962c}, {0xe3, 0x00a6}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f9c}, {0xe2, 0x962c}, {0xe3, 0x00b6}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f9d}, {0xe2, 0x1bfa}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f9e}, {0xe2, 0x4100}, {0xe3, 0x0014}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f9f}, {0xe2, 0x922c}, {0xe3, 0x00b4}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa0}, {0xe2, 0x4001}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa1}, {0xe2, 0x922c}, {0xe3, 0x00a4}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa2}, {0xe2, 0x3c00}, {0xe3, 0x0075}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa3}, {0xe2, 0x193c}, {0xe3, 0x00af}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa4}, {0xe2, 0x8230}, {0xe3, 0x0030}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa5}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa6}, {0xe2, 0x1bfb}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa7}, {0xe2, 0x822c}, {0xe3, 0x00ba}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa8}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fa9}, {0xe2, 0x1bfb}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
++	{0xe1, 0x3faa}, {0xe2, 0x8230}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fab}, {0xe2, 0x267a}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fac}, {0xe2, 0x4001}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fad}, {0xe2, 0x4001}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fae}, {0xe2, 0x2279}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3faf}, {0xe2, 0x0d04}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb0}, {0xe2, 0x3724}, {0xe3, 0x0001}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb1}, {0xe2, 0x0900}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb2}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb3}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb4}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb5}, {0xe2, 0x3b24}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb6}, {0xe2, 0x194f}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb7}, {0xe2, 0x822e}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb8}, {0xe2, 0x2780}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fb9}, {0xe2, 0x1bfb}, {0xe3, 0x00e0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fba}, {0xe2, 0x3c00}, {0xe3, 0x0025}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fbb}, {0xe2, 0x3916}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fbc}, {0xe2, 0x3501}, {0xe3, 0x00a1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fbd}, {0xe2, 0x1dbe}, {0xe3, 0x008f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fbe}, {0xe2, 0x810b}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3fbf}, {0xe2, 0x1831}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
++	{0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
++	{0xe1, 0x3fa0}, {0xe2, 0x9183}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa1}, {0xe2, 0x91b3}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb1}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa2}, {0xe2, 0x9216}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb2}, {0xe2, 0x3f1e}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa3}, {0xe2, 0xe09d}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb3}, {0xe2, 0x3f2b}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa4}, {0xe2, 0xe0cd}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb4}, {0xe2, 0x3f3d}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa5}, {0xe2, 0xe130}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb5}, {0xe2, 0x3f4b}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa6}, {0xe2, 0x859a}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb6}, {0xe2, 0x3f59}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa7}, {0xe2, 0x94fc}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb7}, {0xe2, 0x3f62}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa8}, {0xe2, 0x93c9}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb8}, {0xe2, 0x3f71}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa9}, {0xe2, 0x94f2}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb9}, {0xe2, 0x3fa4}, {0xe0, 0x3bcb},
++	{0xe1, 0x22cc}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
++	{0xe1, 0x3faa}, {0xe2, 0x823a}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fba}, {0xe2, 0x023e}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fab}, {0xe2, 0x831c}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fbb}, {0xe2, 0x3fb7}, {0xe0, 0x3bcb},
++	{0xe1, 0x0010}, {0xe2, 0x0001}, {0xe0, 0x6ac9},
++	{0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
++	{0xe1, 0x3f00}, {0xe2, 0x26e1}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f01}, {0xe2, 0x1924}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f02}, {0xe2, 0x82f5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f03}, {0xe2, 0x26e0}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f04}, {0xe2, 0x1bf0}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f05}, {0xe2, 0x3400}, {0xe3, 0x0008}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f06}, {0xe2, 0x198e}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f07}, {0xe2, 0x0c20}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f08}, {0xe2, 0x80f5}, {0xe3, 0x00b3}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f09}, {0xe2, 0x8149}, {0xe3, 0x00b7}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0a}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0b}, {0xe2, 0x90f5}, {0xe3, 0x00bc}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0c}, {0xe2, 0x8101}, {0xe3, 0x00b3}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0d}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0e}, {0xe2, 0x9101}, {0xe3, 0x00bc}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f0f}, {0xe2, 0x0c30}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f10}, {0xe2, 0x198e}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f11}, {0xe2, 0x9433}, {0xe3, 0x0006}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f12}, {0xe2, 0x9433}, {0xe3, 0x0016}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f13}, {0xe2, 0x4001}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f14}, {0xe2, 0x9033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f15}, {0xe2, 0x3527}, {0xe3, 0x0041}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f16}, {0xe2, 0x3527}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f17}, {0xe2, 0x3527}, {0xe3, 0x0070}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f18}, {0xe2, 0x3c00}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f19}, {0xe2, 0x0c0c}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1a}, {0xe2, 0x17f2}, {0xe3, 0x00ee}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1b}, {0xe2, 0x6000}, {0xe3, 0x00a5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1c}, {0xe2, 0x22fa}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1d}, {0xe2, 0x6000}, {0xe3, 0x0049}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1e}, {0xe2, 0x66e2}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f1f}, {0xe2, 0x1bf2}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f20}, {0xe2, 0x26ea}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f21}, {0xe2, 0x1bf2}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f22}, {0xe2, 0x8033}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f23}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f24}, {0xe2, 0x8033}, {0xe3, 0x0024}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f25}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f26}, {0xe2, 0x1bf2}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f27}, {0xe2, 0x8033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f28}, {0xe2, 0x2262}, {0xe3, 0x621f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f29}, {0xe2, 0x9033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2a}, {0xe2, 0x8033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2b}, {0xe2, 0x9033}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2c}, {0xe2, 0x8033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2d}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2e}, {0xe2, 0x9033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f2f}, {0xe2, 0x0c08}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f30}, {0xe2, 0x82f5}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f31}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f32}, {0xe2, 0x1bf4}, {0xe3, 0x0020}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f33}, {0xe2, 0x8033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f34}, {0xe2, 0x8033}, {0xe3, 0x0054}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f35}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f36}, {0xe2, 0x1bf3}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f37}, {0xe2, 0x8033}, {0xe3, 0x003a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f38}, {0xe2, 0x22e2}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f39}, {0xe2, 0x9033}, {0xe3, 0x003a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3a}, {0xe2, 0x1bf4}, {0xe3, 0x0022}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3b}, {0xe2, 0x9433}, {0xe3, 0x0036}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3c}, {0xe2, 0x9433}, {0xe3, 0x0046}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3d}, {0xe2, 0x1bf4}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3e}, {0xe2, 0x4100}, {0xe3, 0x0014}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f3f}, {0xe2, 0x9033}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f40}, {0xe2, 0x4001}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f41}, {0xe2, 0x9033}, {0xe3, 0x0034}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f42}, {0xe2, 0x3c00}, {0xe3, 0x0075}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f43}, {0xe2, 0x192f}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f44}, {0xe2, 0x82f5}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f45}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f46}, {0xe2, 0x1bf5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f47}, {0xe2, 0x8033}, {0xe3, 0x004a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f48}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f49}, {0xe2, 0x1bf5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4a}, {0xe2, 0x82f5}, {0xe3, 0x005a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4b}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4c}, {0xe2, 0x4001}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4d}, {0xe2, 0x4001}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4e}, {0xe2, 0x2279}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f4f}, {0xe2, 0x0d04}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f50}, {0xe2, 0x3549}, {0xe3, 0x00b1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f51}, {0xe2, 0x0900}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f52}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f53}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f54}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f55}, {0xe2, 0x3949}, {0xe3, 0x00b0}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f56}, {0xe2, 0x1984}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f57}, {0xe2, 0x82b6}, {0xe3, 0x0061}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f58}, {0xe2, 0x17f8}, {0xe3, 0x006e}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f59}, {0xe2, 0x8291}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5a}, {0xe2, 0x602a}, {0xe3, 0x0065}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5b}, {0xe2, 0x2084}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5c}, {0xe2, 0x0d00}, {0xe3, 0x00fc}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5d}, {0xe2, 0x0d00}, {0xe3, 0x00eb}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5e}, {0xe2, 0x2058}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f5f}, {0xe2, 0x1067}, {0xe3, 0x00be}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f60}, {0xe2, 0x1073}, {0xe3, 0x0087}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f61}, {0xe2, 0x1047}, {0xe3, 0x00a9}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f62}, {0xe2, 0x0e5b}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f63}, {0xe2, 0x2262}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f64}, {0xe2, 0x902f}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f65}, {0xe2, 0x902f}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f66}, {0xe2, 0x1c95}, {0xe3, 0x00cf}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f67}, {0xe2, 0x1c50}, {0xe3, 0x00cf}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f68}, {0xe2, 0x0f22}, {0xe3, 0x00ff}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f69}, {0xe2, 0x802f}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6a}, {0xe2, 0x0d00}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6b}, {0xe2, 0x4000}, {0xe3, 0x0004}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6c}, {0xe2, 0x060a}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6d}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6e}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f6f}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f70}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f71}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f72}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f73}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f74}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f75}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f76}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f77}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f78}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f79}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7a}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7b}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7c}, {0xe2, 0x802f}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7d}, {0xe2, 0x2b3a}, {0xe3, 0x00b4}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7e}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f7f}, {0xe2, 0x0d00}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f80}, {0xe2, 0x1023}, {0xe3, 0x0061}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f81}, {0xe2, 0x2027}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f82}, {0xe2, 0x428b}, {0xe3, 0x00e6}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f83}, {0xe2, 0x2024}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f84}, {0xe2, 0x82b7}, {0xe3, 0x0084}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f85}, {0xe2, 0x2b24}, {0xe3, 0x0078}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f86}, {0xe2, 0x92b7}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f87}, {0xe2, 0x1a20}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f88}, {0xe2, 0x47ff}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f89}, {0xe2, 0x92b5}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8a}, {0xe2, 0x356d}, {0xe3, 0x00b1}, {0xe0, 0x0dcf},
++	{0xe1, 0x3f8b}, {0xe2, 0x19e4}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
++	{0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
++	{0xe1, 0x3fa0}, {0xe2, 0x9248}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa1}, {0xe2, 0x98e2}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb1}, {0xe2, 0x3f02}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa2}, {0xe2, 0x92f0}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb2}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa3}, {0xe2, 0x9842}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb3}, {0xe2, 0x3f44}, {0xe0, 0x3bcb},
++	{0xe1, 0x0335}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa4}, {0xe2, 0xa1d6}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb4}, {0xe2, 0x3f57}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fa5}, {0xe2, 0x9e3f}, {0xe0, 0x3bcb},
++	{0xe1, 0x3fb5}, {0xe2, 0x3f88}, {0xe0, 0x3bcb},
++	{0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9}
++};
++#define RT5670_DSP_PATCH_NUM \
++	(sizeof(rt5670_dsp_patch) / sizeof(rt5670_dsp_patch[0]))
++
++/* DSP init */
++static unsigned short rt5670_dsp_init[][2] = {
++	{0x2260, 0x30d9}, {0x2261, 0x30d9}, {0x2289, 0x7fff}, {0x2290, 0x7fff},
++	{0x2288, 0x0002}, {0x22b2, 0x0002}, {0x2295, 0x0001}, {0x22b3, 0x0001},
++	{0x22d7, 0x0008}, {0x22d8, 0x0009}, {0x22d9, 0x0000}, {0x22da, 0x0001},
++	{0x22fd, 0x009e}, {0x22c1, 0x1006}, {0x22c2, 0x1006}, {0x22c3, 0x1007},
++	{0x22c4, 0x1007}
++};
++#define RT5670_DSP_INIT_NUM \
++	(sizeof(rt5670_dsp_init) / sizeof(rt5670_dsp_init[0]))
++
++/* MCLK rate */
++static unsigned short rt5670_dsp_4096000[][2] = {
++	{0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x0022},
++};
++#define RT5670_DSP_4096000_NUM \
++	(sizeof(rt5670_dsp_4096000) / sizeof(rt5670_dsp_4096000[0]))
++
++static unsigned short rt5670_dsp_12288000[][2] = {
++	{0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x0026},
++};
++#define RT5670_DSP_12288000_NUM \
++	(sizeof(rt5670_dsp_12288000) / sizeof(rt5670_dsp_12288000[0]))
++
++static unsigned short rt5670_dsp_11289600[][2] = {
++	{0x226c, 0x0031}, {0x226d, 0x0050}, {0x226e, 0x0009},
++};
++#define RT5670_DSP_11289600_NUM \
++	(sizeof(rt5670_dsp_11289600) / sizeof(rt5670_dsp_11289600[0]))
++
++static unsigned short rt5670_dsp_24576000[][2] = {
++	{0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x002c},
++};
++#define RT5670_DSP_24576000_NUM \
++	(sizeof(rt5670_dsp_24576000) / sizeof(rt5670_dsp_24576000[0]))
++
++/* sample rate */
++static unsigned short rt5670_dsp_48_441[][2] = {
++	{0x22f2, 0x0058}, {0x2301, 0x0016}
++};
++#define RT5670_DSP_48_441_NUM \
++	(sizeof(rt5670_dsp_48_441) / sizeof(rt5670_dsp_48_441[0]))
++
++static unsigned short rt5670_dsp_24[][2] = {
++	{0x22f2, 0x0058}, {0x2301, 0x0004}
++};
++#define RT5670_DSP_24_NUM (sizeof(rt5670_dsp_24) / sizeof(rt5670_dsp_24[0]))
++
++static unsigned short rt5670_dsp_16[][2] = {
++	{0x22f2, 0x004c}, {0x2301, 0x0002}
++};
++#define RT5670_DSP_16_NUM (sizeof(rt5670_dsp_16) / sizeof(rt5670_dsp_16[0]))
++
++static unsigned short rt5670_dsp_8[][2] = {
++	{0x22f2, 0x004c}, {0x2301, 0x0000}
++};
++#define RT5670_DSP_8_NUM (sizeof(rt5670_dsp_8) / sizeof(rt5670_dsp_8[0]))
++
++/* DSP mode */
++static unsigned short rt5670_dsp_ns[][2] = {
++	{0x22f8, 0x8005}, {0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332},
++	{0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238a, 0x0000}, {0x238b, 0x1000},
++	{0x238c, 0x1000}, {0x23a1, 0x2000}, {0x2303, 0x0200}, {0x2304, 0x0032},
++	{0x2305, 0x0000}, {0x230c, 0x0200}, {0x22fb, 0x0000}
++};
++#define RT5670_DSP_NS_NUM \
++	(sizeof(rt5670_dsp_ns) / sizeof(rt5670_dsp_ns[0]))
++
++static unsigned short rt5670_dsp_aec[][2] = {
++	{0x22f8, 0x8003}, {0x232f, 0x00d0}, {0x2355, 0x2666}, {0x2356, 0x2666},
++	{0x2357, 0x2666}, {0x2358, 0x6666}, {0x2359, 0x6666}, {0x235a, 0x6666},
++	{0x235b, 0x7fff}, {0x235c, 0x7fff}, {0x235d, 0x7fff}, {0x235e, 0x7fff},
++	{0x235f, 0x7fff}, {0x2360, 0x7fff}, {0x2361, 0x7fff}, {0x2362, 0x1000},
++	{0x2367, 0x0007}, {0x2368, 0x4000}, {0x2369, 0x0008}, {0x236a, 0x2000},
++	{0x236b, 0x0009}, {0x236c, 0x003c}, {0x236d, 0x0000}, {0x236f, 0x2000},
++	{0x2370, 0x0008}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
++	{0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
++	{0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238a, 0x4000},
++	{0x238b, 0x1000}, {0x238c, 0x1000}, {0x2398, 0x4668}, {0x23a1, 0x2000},
++	{0x23a3, 0x4000}, {0x23ad, 0x2000}, {0x23ae, 0x2000}, {0x23af, 0x2000},
++	{0x23b4, 0x2000}, {0x23b5, 0x2000}, {0x23b6, 0x2000}, {0x23bb, 0x6000},
++	{0x2303, 0x0710}, {0x2304, 0x0332}, {0x230c, 0x0200}, {0x230d, 0x0080},
++	{0x2310, 0x0010}, {0x22fb, 0x0000}
++};
++#define RT5670_DSP_AEC_NUM \
++	(sizeof(rt5670_dsp_aec) / sizeof(rt5670_dsp_aec[0]))
++
++static unsigned short rt5670_dsp_vt[][2] = {
++	{0x22f8, 0x8003}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
++	{0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
++	{0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238b, 0x1000},
++	{0x238c, 0x1000}, {0x23a1, 0x2000}, {0x2304, 0x0332}, {0x230c, 0x0200},
++	{0x22fb, 0x0000}
++};
++#define RT5670_DSP_VT_NUM (sizeof(rt5670_dsp_vt) / sizeof(rt5670_dsp_vt[0]))
++
++static unsigned short rt5670_dsp_vr[][2] = {
++	{0x22f8, 0x8003}, {0x2304, 0x0332}, {0x2305, 0x0000}, {0x2309, 0x0400},
++	{0x230c, 0x0200}, {0x230d, 0x0080}, {0x2310, 0x0004}, {0x232f, 0x0100},
++	{0x2371, 0x000a}, {0x2373, 0x3000}, {0x2374, 0x5000}, {0x2375, 0x7ff0},
++	{0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000}, {0x237a, 0x1000},
++	{0x2386, 0x0200}, {0x2388, 0x4000}, {0x2389, 0x4000}, {0x238a, 0x0000},
++	{0x238b, 0x2000}, {0x238c, 0x1800}, {0x239b, 0x0000}, {0x239c, 0x0a00},
++	{0x239d, 0x0000}, {0x239e, 0x7fff}, {0x239f, 0x0001}, {0x23a1, 0x3000},
++	{0x23a2, 0x1000}, {0x23ad, 0x0000}, {0x23ae, 0x0000}, {0x23af, 0x0000},
++	{0x23c4, 0x2000}, {0x23b0, 0x0000}, {0x23b1, 0x0000}, {0x23b2, 0x0000},
++	{0x23b3, 0x0000}, {0x23b4, 0x0000}, {0x23b5, 0x0000}, {0x23b6, 0x0000},
++	{0x23b7, 0x0000}, {0x23b8, 0x0000}, {0x23b9, 0x0000}, {0x23ba, 0x0000},
++	{0x23bb, 0x0000}, {0x22fb, 0x0000}
++};
++#define RT5670_DSP_VR_NUM (sizeof(rt5670_dsp_vr) / sizeof(rt5670_dsp_vr[0]))
++
++static unsigned short rt5670_dsp_ffp_ns[][2] = {
++	{0x22f8, 0x8003}, {0x2304, 0x8332}, {0x2371, 0x000a}, {0x2373, 0x0000},
++	{0x2374, 0x7fff}, {0x2379, 0x1800}, {0x237a, 0x1800}, {0x230c, 0x0200},
++	{0x23a2, 0x1000}, {0x2388, 0x7000}, {0x238b, 0x2000}, {0x238c, 0x2000},
++	{0x23a8, 0x2000}, {0x23a9, 0x4000}, {0x23aa, 0x0100}, {0x23ab, 0x7800},
++	{0x22fb, 0x0000}
++};
++#define RT5670_DSP_FFP_NS_NUM \
++	(sizeof(rt5670_dsp_ffp_ns) / sizeof(rt5670_dsp_ffp_ns[0]))
++
++static unsigned short rt5670_dsp_48k_sto_ffp[][2] = {
++	{0x22c1, 0x1025}, {0x22c2, 0x1026}, {0x22f8, 0x8004}, {0x22ea, 0x0001},
++	{0x230c, 0x0100}, {0x230d, 0x0100}, {0x2301, 0x0010}, {0x2303, 0x0200},
++	{0x2304, 0x8000}, {0x2305, 0x0000}, {0x2388, 0x6500}, {0x238b, 0x4000},
++	{0x238c, 0x4000}, {0x23a9, 0x2000}, {0x23aa, 0x0200}, {0x23ab, 0x7c00},
++	{0x22fb, 0x0000}
++};
++#define RT5670_DSP_48K_STO_FFP_NUM \
++	(sizeof(rt5670_dsp_48k_sto_ffp) / sizeof(rt5670_dsp_48k_sto_ffp[0]))
++
++static unsigned short rt5670_dsp_2mic_handset[][2] = {
++	{0x22f8, 0x8002}, {0x2301, 0x0002}, {0x2302, 0x0002}, {0x2303, 0x0710},
++	{0x2304, 0x4332}, {0x2305, 0x206c}, {0x236e, 0x0000}, {0x236f, 0x0001},
++	{0x237e, 0x0001}, {0x237f, 0x3800}, {0x2380, 0x3000}, {0x2381, 0x0005},
++	{0x2382, 0x0040}, {0x2383, 0x7fff}, {0x2388, 0x2c00}, {0x2389, 0x2800},
++	{0x238b, 0x1800}, {0x238c, 0x1800}, {0x238f, 0x2000}, {0x239b, 0x0002},
++	{0x239c, 0x0a00}, {0x239f, 0x0001}, {0x230c, 0x0200}, {0x22fb, 0x0000}
++};
++#define RT5670_DSP_2MIC_HANDSET_NUM \
++	(sizeof(rt5670_dsp_2mic_handset) / sizeof(rt5670_dsp_2mic_handset[0]))
++
++static unsigned short rt5670_dsp_2mic_handsfree[][2] = {
++	{0x22f8, 0x8003}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
++	{0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
++	{0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238b, 0x1000},
++	{0x238c, 0x1000}, {0x23a1, 0x2000}, {0x2304, 0x0332}, {0x230c, 0x0200},
++	{0x22fb, 0x0000}
++};
++#define RT5670_DSP_2MIC_HANDSFREE_NUM \
++	(sizeof(rt5670_dsp_2mic_handsfree) / \
++	sizeof(rt5670_dsp_2mic_handsfree[0]))
++
++static unsigned short rt5670_dsp_aec_handsfree[][2] = {
++	{0x22f8, 0x8003}, {0x232f, 0x00d0}, {0x2355, 0x2666}, {0x2356, 0x2666},
++	{0x2357, 0x2666}, {0x2358, 0x6666}, {0x2359, 0x6666}, {0x235a, 0x6666},
++	{0x235b, 0x7fff}, {0x235c, 0x7fff}, {0x235d, 0x7fff}, {0x235e, 0x7fff},
++	{0x235f, 0x7fff}, {0x2360, 0x7fff}, {0x2361, 0x7fff}, {0x2362, 0x1000},
++	{0x2367, 0x0007}, {0x2368, 0x4000}, {0x2369, 0x0008}, {0x236a, 0x2000},
++	{0x236b, 0x0009}, {0x236c, 0x003c}, {0x236d, 0x0000}, {0x236f, 0x2000},
++	{0x2370, 0x0008}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
++	{0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
++	{0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238a, 0x4000},
++	{0x238b, 0x1000}, {0x238c, 0x1000}, {0x2398, 0x4668}, {0x23a1, 0x2000},
++	{0x23a3, 0x4000}, {0x23ad, 0x2000}, {0x23ae, 0x2000}, {0x23af, 0x2000},
++	{0x23b4, 0x2000}, {0x23b5, 0x2000}, {0x23b6, 0x2000}, {0x23bb, 0x6000},
++	{0x2303, 0x0710}, {0x2304, 0x0332}, {0x230c, 0x0200}, {0x230d, 0x0080},
++	{0x2310, 0x0010}, {0x22fb, 0x0000}
++};
++#define RT5670_DSP_AEC_HANDSFREE_NUM \
++	(sizeof(rt5670_dsp_aec_handsfree) / sizeof(rt5670_dsp_aec_handsfree[0]))
++
++/**
++ * rt5670_dsp_done - Wait until DSP is ready.
++ * @codec: SoC Audio Codec device.
++ *
++ * To check voice DSP status and confirm it's ready for next work.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_done(struct snd_soc_codec *codec)
++{
++	unsigned int count = 0, dsp_val;
++
++	dsp_val = snd_soc_read(codec, RT5670_DSP_CTRL1);
++	while (dsp_val & RT5670_DSP_BUSY_MASK) {
++		if (count > 10)
++			return -EBUSY;
++		dsp_val = snd_soc_read(codec, RT5670_DSP_CTRL1);
++		count++;
++	}
++
++	return 0;
++}
++
++/**
++ * rt5670_dsp_write - Write DSP register.
++ * @codec: SoC audio codec device.
++ * @param: DSP parameters.
++  *
++ * Modify voice DSP register for sound effect. The DSP can be controlled
++ * through DSP command format (0xfc), addr (0xc4), data (0xc5) and cmd (0xc6)
++ * register. It has to wait until the DSP is ready.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_write(struct snd_soc_codec *codec,
++		unsigned int addr, unsigned int data)
++{
++	unsigned int dsp_val;
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL2, addr);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL3, data);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret);
++		goto err;
++	}
++	dsp_val = RT5670_DSP_I2C_AL_16 | RT5670_DSP_DL_2 |
++		RT5670_DSP_CMD_MW | DSP_CLK_RATE | RT5670_DSP_CMD_EN;
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
++		goto err;
++	}
++	ret = rt5670_dsp_done(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "DSP is busy: %d\n", ret);
++		goto err;
++	}
++
++	return 0;
++
++err:
++	return ret;
++}
++
++/**
++ * rt5670_dsp_read - Read DSP register.
++ * @codec: SoC audio codec device.
++ * @reg: DSP register index.
++ *
++ * Read DSP setting value from voice DSP. The DSP can be controlled
++ * through DSP addr (0xc4), data (0xc5) and cmd (0xc6) register. Each
++ * command has to wait until the DSP is ready.
++ *
++ * Returns DSP register value or negative error code.
++ */
++static unsigned int rt5670_dsp_read(
++	struct snd_soc_codec *codec, unsigned int reg)
++{
++	unsigned int value;
++	unsigned int dsp_val;
++	int ret = 0;
++
++	ret = rt5670_dsp_done(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "DSP is busy: %d\n", ret);
++		goto err;
++	}
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL2, reg);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
++		goto err;
++	}
++	dsp_val = RT5670_DSP_I2C_AL_16 | RT5670_DSP_DL_0 | RT5670_DSP_RW_MASK |
++		RT5670_DSP_CMD_MR | DSP_CLK_RATE | RT5670_DSP_CMD_EN;
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
++		goto err;
++	}
++
++	ret = rt5670_dsp_done(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "DSP is busy: %d\n", ret);
++		goto err;
++	}
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL2, 0x26);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
++		goto err;
++	}
++	dsp_val = RT5670_DSP_DL_1 | RT5670_DSP_CMD_RR | RT5670_DSP_RW_MASK |
++		DSP_CLK_RATE | RT5670_DSP_CMD_EN;
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
++		goto err;
++	}
++
++	ret = rt5670_dsp_done(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "DSP is busy: %d\n", ret);
++		goto err;
++	}
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL2, 0x25);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
++		goto err;
++	}
++
++	dsp_val = RT5670_DSP_DL_1 | RT5670_DSP_CMD_RR | RT5670_DSP_RW_MASK |
++		DSP_CLK_RATE | RT5670_DSP_CMD_EN;
++
++	ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
++		goto err;
++	}
++
++	ret = rt5670_dsp_done(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "DSP is busy: %d\n", ret);
++		goto err;
++	}
++
++	ret = snd_soc_read(codec, RT5670_DSP_CTRL5);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
++		goto err;
++	}
++
++	value = ret;
++	return value;
++
++err:
++	return ret;
++}
++
++static int rt5670_dsp_get(struct snd_kcontrol *kcontrol,
++		struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	ucontrol->value.integer.value[0] = rt5670->dsp_sw;
++
++	return 0;
++}
++
++static int rt5670_dsp_put(struct snd_kcontrol *kcontrol,
++		struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	if (rt5670->dsp_sw != ucontrol->value.integer.value[0])
++		rt5670->dsp_sw = ucontrol->value.integer.value[0];
++
++	return 0;
++}
++
++/* DSP Path Control 1 */
++static const char * const rt5670_src_rxdp_mode[] = {
++	"Normal", "Divided by 3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_src_rxdp_enum, RT5670_DSP_PATH1,
++	RT5670_RXDP_SRC_SFT, rt5670_src_rxdp_mode);
++
++static const char * const rt5670_src_txdp_mode[] = {
++	"Normal", "Multiplied by 3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_src_txdp_enum, RT5670_DSP_PATH1,
++	RT5670_TXDP_SRC_SFT, rt5670_src_txdp_mode);
++
++/* Sound Effect */
++static const char *rt5670_dsp_mode[] = {
++	"Disable", "NS", "AEC", "VT", "VR", "FFP+NS", "48K-stereo+FFP",
++	"2MIC Handset", "2MIC Handsfree", "AEC Handsfree"
++};
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_dsp_enum, 0, 0,
++	rt5670_dsp_mode);
++
++static const struct snd_kcontrol_new rt5670_dsp_snd_controls[] = {
++	/* AEC */
++	SOC_ENUM_EXT("DSP Function Switch", rt5670_dsp_enum,
++		rt5670_dsp_get, rt5670_dsp_put),
++};
++
++/**
++ * rt5670_dsp_conf - Set DSP basic setting.
++ *
++ * @codec: SoC audio codec device.
++ *
++ * Set parameters of basic setting to DSP.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_conf(struct snd_soc_codec *codec)
++{
++	int ret, i;
++
++	for (i = 0; i < RT5670_DSP_INIT_NUM; i++) {
++		ret = rt5670_dsp_write(codec, rt5670_dsp_init[i][0],
++			rt5670_dsp_init[i][1]);
++		if (ret < 0) {
++			dev_err(codec->dev, "Fail to config Dsp: %d\n", ret);
++			goto conf_err;
++		}
++	}
++
++	return 0;
++
++conf_err:
++
++	return ret;
++}
++
++/**
++ * rt5670_dsp_rate - Set DSP rate setting.
++ *
++ * @codec: SoC audio codec device.
++ * @sys_clk: System clock.
++ * @srate: Sampling rate.
++ *
++ * Set parameters of system clock and sampling rate to DSP.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_rate(struct snd_soc_codec *codec, int sys_clk,
++	int srate)
++{
++	int ret, i, tab_num;
++	unsigned short (*rate_tab)[2];
++
++	dev_dbg(codec->dev,"rt5670_dsp_rate sys:%d srate:%d\n", sys_clk, srate);
++
++	switch(sys_clk) {
++	case 4096000:
++		rate_tab = rt5670_dsp_4096000;
++		tab_num = RT5670_DSP_4096000_NUM;
++		break;
++	case 11289600:
++		rate_tab = rt5670_dsp_11289600;
++		tab_num = RT5670_DSP_11289600_NUM;
++		break;
++	case 12288000:
++		rate_tab = rt5670_dsp_12288000;
++		tab_num = RT5670_DSP_12288000_NUM;
++		break;
++	case 24576000:
++		rate_tab = rt5670_dsp_24576000;
++		tab_num = RT5670_DSP_24576000_NUM;
++		break;
++	default:
++		return -EINVAL;
++		break;
++	}
++
++	for (i = 0; i < tab_num; i++) {
++		ret = rt5670_dsp_write(codec, rate_tab[i][0], rate_tab[i][1]);
++		if (ret < 0)
++			goto rate_err;
++	}
++
++	switch(srate) {
++	case 8000:
++		rate_tab = rt5670_dsp_8;
++		tab_num = RT5670_DSP_8_NUM;
++		break;
++	case 16000:
++		rate_tab = rt5670_dsp_16;
++		tab_num = RT5670_DSP_16_NUM;
++		break;
++	case 24000:
++		rate_tab = rt5670_dsp_24;
++		tab_num = RT5670_DSP_24_NUM;
++		break;
++	case 44100:
++	case 48000:
++		rate_tab = rt5670_dsp_48_441;
++		tab_num = RT5670_DSP_48_441_NUM;
++		break;
++	default:
++		return -EINVAL;
++		break;
++	}
++
++	for (i = 0; i < tab_num; i++) {
++		ret = rt5670_dsp_write(codec, rate_tab[i][0], rate_tab[i][1]);
++		if (ret < 0)
++			goto rate_err;
++	}
++
++	return 0;
++
++rate_err:
++
++	dev_err(codec->dev, "Fail to set rate parameters: %d\n", ret);
++	return ret;
++}
++
++/**
++ * rt5670_dsp_do_patch - Write DSP patch code.
++ *
++ * @codec: SoC audio codec device.
++ *
++ * Write patch codes to DSP.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_do_patch(struct snd_soc_codec *codec)
++{
++	int ret, i;
++
++	for (i = 0; i < RT5670_DSP_PATCH_NUM; i++) {
++		ret = snd_soc_write(codec, rt5670_dsp_patch[i][0],
++			rt5670_dsp_patch[i][1]);
++		if (ret < 0)
++			goto patch_err;
++
++
++		if (rt5670_dsp_patch[i][0] == 0xe0) {
++			ret = rt5670_dsp_done(codec);
++			if (ret < 0) {
++				dev_err(codec->dev, "DSP is busy: %d\n", ret);
++				goto patch_err;
++			}
++		}
++	}
++
++	return 0;
++
++patch_err:
++
++	return ret;
++}
++
++/**
++ * rt5670_dsp_set_mode - Set DSP mode parameters.
++ *
++ * @codec: SoC audio codec device.
++ * @mode: DSP mode.
++ *
++ * Set parameters of mode to DSP.
++ * There are three modes which includes " mic AEC + NS + FENS",
++ * "HFBF" and "Far-field pickup".
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_set_mode(struct snd_soc_codec *codec, int mode)
++{
++	int ret, i, tab_num;
++	unsigned short (*mode_tab)[2];
++
++	switch (mode) {
++	case RT5670_DSP_NS:
++		dev_info(codec->dev, "NS\n");
++		mode_tab = rt5670_dsp_ns;
++		tab_num = RT5670_DSP_NS_NUM;
++		break;
++
++	case RT5670_DSP_AEC:
++		dev_info(codec->dev, "AEC\n");
++		mode_tab = rt5670_dsp_aec;
++		tab_num = RT5670_DSP_AEC_NUM;
++		break;
++
++	case RT5670_DSP_VT:
++		dev_info(codec->dev, "VT\n");
++		mode_tab = rt5670_dsp_vt;
++		tab_num = RT5670_DSP_VT_NUM;
++		break;
++
++	case RT5670_DSP_VR:
++		dev_info(codec->dev, "VR\n");
++		mode_tab = rt5670_dsp_vr;
++		tab_num = RT5670_DSP_VR_NUM;
++		break;
++
++	case RT5670_DSP_FFP_NS:
++		dev_info(codec->dev, "FFP_NS\n");
++		mode_tab = rt5670_dsp_ffp_ns;
++		tab_num = RT5670_DSP_FFP_NS_NUM;
++		break;
++
++	case RT5670_DSP_48K_STO_FFP:
++		dev_info(codec->dev, "48K_STO_FFP\n");
++		mode_tab = rt5670_dsp_48k_sto_ffp;
++		tab_num = RT5670_DSP_48K_STO_FFP_NUM;
++		break;
++
++	case RT5670_DSP_2MIC_HANDSET:
++		dev_info(codec->dev, "2MIC_HANDSET\n");
++		mode_tab = rt5670_dsp_2mic_handset;
++		tab_num = RT5670_DSP_2MIC_HANDSET_NUM;
++		break;
++
++	case RT5670_DSP_2MIC_HANDSFREE:
++		dev_info(codec->dev, "2MIC_HANDSFREE\n");
++		mode_tab = rt5670_dsp_2mic_handsfree;
++		tab_num = RT5670_DSP_2MIC_HANDSFREE_NUM;
++		break;
++
++	case RT5670_DSP_AEC_HANDSFREE:
++		dev_info(codec->dev, "AEC_HANDSFREE\n");
++		mode_tab = rt5670_dsp_aec_handsfree;
++		tab_num = RT5670_DSP_AEC_HANDSFREE_NUM;
++		break;
++
++	case RT5670_DSP_DIS:
++	default:
++		dev_info(codec->dev, "Disable\n");
++		return 0;
++	}
++
++	for (i = 0; i < tab_num; i++) {
++		ret = rt5670_dsp_write(codec, mode_tab[i][0], mode_tab[i][1]);
++		if (ret < 0)
++			goto mode_err;
++	}
++
++	return 0;
++
++mode_err:
++
++	dev_err(codec->dev, "Fail to set mode %d parameters: %d\n", mode, ret);
++	return ret;
++}
++
++/**
++ * rt5670_dsp_snd_effect - Set DSP sound effect.
++ *
++ * Set parameters of sound effect to DSP.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_dsp_snd_effect(struct snd_soc_codec *codec)
++{
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	int ret;
++
++	snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP,
++		RT5670_RST_DSP);
++	snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP, 0);
++
++	mdelay(10);
++/*	Expend 1.6 seconds
++	ret = rt5670_dsp_do_patch(codec);
++	if (ret < 0)
++		goto effect_err;
++*/
++	ret = rt5670_dsp_rate(codec,
++		rt5670->sysclk ?
++		rt5670->sysclk : 11289600,
++		rt5670->lrck[rt5670->aif_pu] ?
++		rt5670->lrck[rt5670->aif_pu] : 44100);
++	if (ret < 0)
++		goto effect_err;
++
++	ret = rt5670_dsp_conf(codec);
++	if (ret < 0)
++		goto effect_err;
++
++	ret = rt5670_dsp_set_mode(codec, rt5670->dsp_sw);
++	if (ret < 0)
++		goto effect_err;
++
++	return 0;
++
++effect_err:
++
++	return ret;
++}
++
++static int rt5670_dsp_event(struct snd_soc_dapm_widget *w,
++			struct snd_kcontrol *k, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMD:
++		dev_dbg(codec->dev, "%s(): PMD\n", __func__);
++		rt5670_dsp_write(codec, 0x22f9, 1);
++		break;
++
++	case SND_SOC_DAPM_POST_PMU:
++		dev_dbg(codec->dev, "%s(): PMU\n", __func__);
++		rt5670_dsp_snd_effect(codec);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static const struct snd_soc_dapm_widget rt5670_dsp_dapm_widgets[] = {
++	SND_SOC_DAPM_SUPPLY_S("Voice DSP", 1, SND_SOC_NOPM,
++		0, 0, rt5670_dsp_event,
++		SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_PGA("DSP Downstream", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("DSP Upstream", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++};
++
++static const struct snd_soc_dapm_route rt5670_dsp_dapm_routes[] = {
++	{"DSP Downstream", NULL, "Voice DSP"},
++	{"DSP Downstream", NULL, "RxDP Mux"},
++	{"DSP Upstream", NULL, "Voice DSP"},
++	{"DSP Upstream", NULL, "8CH TDM Data"},
++	{"DSP DL Mux", "DSP", "DSP Downstream"},
++	{"DSP UL Mux", "DSP", "DSP Upstream"},
++};
++
++/**
++ * rt5670_dsp_show - Dump DSP registers.
++ * @dev: codec device.
++ * @attr: device attribute.
++ * @buf: buffer for display.
++ *
++ * To show non-zero values of all DSP registers.
++ *
++ * Returns buffer length.
++ */
++static ssize_t rt5670_dsp_show(struct device *dev,
++	struct device_attribute *attr, char *buf)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++	unsigned short (*rt5670_dsp_tab)[2];
++	unsigned int val;
++	int cnt = 0, i, tab_num;
++
++	switch (rt5670->dsp_sw) {
++	case RT5670_DSP_NS:
++		cnt += sprintf(buf, "[ RT5642 DSP 'NS' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_ns;
++		tab_num = RT5670_DSP_NS_NUM;
++		break;
++
++	case RT5670_DSP_AEC:
++		cnt += sprintf(buf, "[ RT5642 DSP 'AEC' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_aec;
++		tab_num = RT5670_DSP_AEC_NUM;
++		break;
++
++	case RT5670_DSP_VT:
++		cnt += sprintf(buf, "[ RT5642 DSP 'VT' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_vt;
++		tab_num = RT5670_DSP_VT_NUM;
++		break;
++
++	case RT5670_DSP_VR:
++		cnt += sprintf(buf, "[ RT5642 DSP 'VR' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_vr;
++		tab_num = RT5670_DSP_VR_NUM;
++		break;
++
++	case RT5670_DSP_FFP_NS:
++		cnt += sprintf(buf, "[ RT5642 DSP 'FFP_NS' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_ffp_ns;
++		tab_num = RT5670_DSP_FFP_NS_NUM;
++		break;
++
++	case RT5670_DSP_48K_STO_FFP:
++		cnt += sprintf(buf, "[ RT5642 DSP '48K_STO_FFP' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_48k_sto_ffp;
++		tab_num = RT5670_DSP_48K_STO_FFP_NUM;
++		break;
++
++	case RT5670_DSP_2MIC_HANDSET:
++		cnt += sprintf(buf, "[ RT5642 DSP '2MIC_HANDSET' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_2mic_handset;
++		tab_num = RT5670_DSP_2MIC_HANDSET_NUM;
++		break;
++
++	case RT5670_DSP_2MIC_HANDSFREE:
++		cnt += sprintf(buf, "[ RT5642 DSP '2MIC_HANDSFREE' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_2mic_handsfree;
++		tab_num = RT5670_DSP_2MIC_HANDSFREE_NUM;
++		break;
++
++	case RT5670_DSP_AEC_HANDSFREE:
++		cnt += sprintf(buf, "[ RT5642 DSP 'AEC_HANDSFREE' ]\n");
++		rt5670_dsp_tab = rt5670_dsp_aec_handsfree;
++		tab_num = RT5670_DSP_AEC_HANDSFREE_NUM;
++		break;
++
++	case RT5670_DSP_DIS:
++	default:
++		cnt += sprintf(buf, "RT5642 DSP Disabled\n");
++		goto dsp_done;
++	}
++
++	for (i = 0; i < tab_num; i++) {
++		if (cnt + RT5670_DSP_REG_DISP_LEN >= PAGE_SIZE)
++			break;
++		val = rt5670_dsp_read(codec, rt5670_dsp_tab[i][0]);
++		if (!val)
++			continue;
++		cnt += snprintf(buf + cnt, RT5670_DSP_REG_DISP_LEN,
++			"%04x: %04x\n", rt5670_dsp_tab[i][0], val);
++	}
++
++	rt5670_dsp_tab = rt5670_dsp_init;
++	tab_num = RT5670_DSP_INIT_NUM;
++	for (i = 0; i < tab_num; i++) {
++		if (cnt + RT5670_DSP_REG_DISP_LEN >= PAGE_SIZE)
++			break;
++		val = rt5670_dsp_read(codec, rt5670_dsp_tab[i][0]);
++		if (!val)
++			continue;
++		cnt += snprintf(buf + cnt, RT5670_DSP_REG_DISP_LEN,
++			"%04x: %04x\n",
++			rt5670_dsp_tab[i][0], val);
++	}
++
++dsp_done:
++
++	if (cnt >= PAGE_SIZE)
++		cnt = PAGE_SIZE - 1;
++
++	return cnt;
++}
++
++static ssize_t dsp_reg_store(struct device *dev,
++	struct device_attribute *attr, const char *buf, size_t count)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++	unsigned int val = 0, addr = 0;
++	int i;
++
++	pr_debug("register \"%s\" count = %d\n", buf, count);
++
++	/* address */
++	for (i = 0; i < count; i++)
++		if (*(buf + i) <= '9' && *(buf + i) >= '0')
++			addr = (addr << 4) | (*(buf + i) - '0');
++		else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
++			addr = (addr << 4) | ((*(buf + i) - 'a') + 0xa);
++		else if (*(buf + i) <= 'A' && *(buf + i) >= 'A')
++			addr = (addr << 4) | ((*(buf + i) - 'A') + 0xa);
++		else
++			break;
++
++	/* Value*/
++	for (i = i + 1; i < count; i++)
++		if (*(buf + i) <= '9' && *(buf + i) >= '0')
++			val = (val << 4) | (*(buf + i) - '0');
++		else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
++			val = (val << 4) | ((*(buf + i) - 'a') + 0xa);
++		else if (*(buf + i) <= 'F' && *(buf + i) >= 'A')
++			val = (val << 4) | ((*(buf + i) - 'A') + 0xa);
++		else
++			break;
++
++	pr_debug("addr=0x%x val=0x%x\n", addr, val);
++	if (i == count)
++		pr_debug("0x%04x = 0x%04x\n",
++			addr, rt5670_dsp_read(codec, addr));
++	else
++		rt5670_dsp_write(codec, addr, val);
++
++	return count;
++}
++static DEVICE_ATTR(dsp_reg, 0666, rt5670_dsp_show, dsp_reg_store);
++
++/**
++ * rt5670_dsp_probe - register DSP for rt5670
++ * @codec: audio codec
++ *
++ * To register DSP function for rt5670.
++ *
++ * Returns 0 for success or negative error code.
++ */
++int rt5670_dsp_probe(struct snd_soc_codec *codec)
++{
++	int ret;
++
++	if (codec == NULL)
++		return -EINVAL;
++
++	snd_soc_update_bits(codec, RT5670_PWR_DIG2,
++		RT5670_PWR_I2S_DSP, RT5670_PWR_I2S_DSP);
++
++	snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP,
++		RT5670_RST_DSP);
++	snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP, 0);
++
++	mdelay(10);
++
++	rt5670_dsp_write(codec, 0x22fb, 0);
++	/* power down DSP*/
++	rt5670_dsp_write(codec, 0x22f9, 1);
++
++	snd_soc_update_bits(codec, RT5670_PWR_DIG2,
++		RT5670_PWR_I2S_DSP, 0);
++
++	snd_soc_add_codec_controls(codec, rt5670_dsp_snd_controls,
++			ARRAY_SIZE(rt5670_dsp_snd_controls));
++	snd_soc_dapm_new_controls(&codec->dapm, rt5670_dsp_dapm_widgets,
++			ARRAY_SIZE(rt5670_dsp_dapm_widgets));
++	snd_soc_dapm_add_routes(&codec->dapm, rt5670_dsp_dapm_routes,
++			ARRAY_SIZE(rt5670_dsp_dapm_routes));
++
++	ret = device_create_file(codec->dev, &dev_attr_dsp_reg);
++	if (ret != 0) {
++		dev_err(codec->dev,
++			"Failed to create index_reg sysfs files: %d\n", ret);
++		return ret;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(rt5670_dsp_probe);
++
++#ifdef RTK_IOCTL
++int rt5670_dsp_ioctl_common(struct snd_hwdep *hw,
++	struct file *file, unsigned int cmd, unsigned long arg)
++{
++	struct rt_codec_cmd rt_codec;
++	int *buf;
++	int *p;
++	int ret;
++
++	struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
++	struct snd_soc_codec *codec = hw->private_data;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
++		dev_err(codec->dev, "copy_from_user faild\n");
++		return -EFAULT;
++	}
++	dev_dbg(codec->dev, "rt_codec.number=%d\n", rt_codec.number);
++	buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
++	if (buf == NULL)
++		return -ENOMEM;
++	if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number))
++		goto err;
++
++	ret = snd_soc_update_bits(codec, RT5670_PWR_DIG2,
++		RT5670_PWR_I2S_DSP, RT5670_PWR_I2S_DSP);
++	if (ret < 0) {
++		dev_err(codec->dev,
++			"Failed to power up DSP IIS interface: %d\n", ret);
++		goto err;
++	}
++
++	switch (cmd) {
++	case RT_READ_CODEC_DSP_IOCTL:
++		for (p = buf; p < buf + rt_codec.number / 2; p++)
++			*(p + rt_codec.number / 2) = rt5670_dsp_read(codec, *p);
++		if (copy_to_user(rt_codec.buf, buf,
++			sizeof(*buf) * rt_codec.number))
++			goto err;
++		break;
++
++	case RT_WRITE_CODEC_DSP_IOCTL:
++		if (codec == NULL) {
++			dev_dbg(codec->dev, "codec is null\n");
++			break;
++		}
++		for (p = buf; p < buf + rt_codec.number / 2; p++)
++			rt5670_dsp_write(codec, *p, *(p + rt_codec.number / 2));
++		break;
++
++	case RT_GET_CODEC_DSP_MODE_IOCTL:
++		*buf = rt5670->dsp_sw;
++		if (copy_to_user(rt_codec.buf, buf,
++			sizeof(*buf) * rt_codec.number))
++			goto err;
++		break;
++
++	default:
++		dev_info(codec->dev, "unsported dsp command\n");
++		break;
++	}
++
++	kfree(buf);
++	return 0;
++
++err:
++	kfree(buf);
++	return -EFAULT;
++}
++EXPORT_SYMBOL_GPL(rt5670_dsp_ioctl_common);
++#endif
++
++#ifdef CONFIG_PM
++int rt5670_dsp_suspend(struct snd_soc_codec *codec)
++{
++	return 0;
++}
++EXPORT_SYMBOL_GPL(rt5670_dsp_suspend);
++
++int rt5670_dsp_resume(struct snd_soc_codec *codec)
++{
++	return 0;
++}
++EXPORT_SYMBOL_GPL(rt5670_dsp_resume);
++#endif
++
+diff --git a/sound/soc/codecs/rt5670-dsp.h b/sound/soc/codecs/rt5670-dsp.h
+new file mode 100644
+index 00000000..18c545a1
+--- /dev/null
++++ b/sound/soc/codecs/rt5670-dsp.h
+@@ -0,0 +1,79 @@
++/*
++ * rt5670-dsp.h  --  RT5670 ALSA SoC DSP driver
++ *
++ * Copyright 2011 Realtek Microelectronics
++ * Author: Johnny Hsu <johnnyhsu@realtek.com>
++ *
++ * 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.
++ */
++
++#ifndef __RT5670_DSP_H__
++#define __RT5670_DSP_H__
++
++#define RT5670_DSP_CTRL1		0xe0
++#define RT5670_DSP_CTRL2		0xe1
++#define RT5670_DSP_CTRL3		0xe2
++#define RT5670_DSP_CTRL4		0xe3
++#define RT5670_DSP_CTRL5		0xe4
++
++/* DSP Control 1 (0xe0) */
++#define RT5670_DSP_CMD_MASK		(0xff << 8)
++#define RT5670_DSP_CMD_PE		(0x0d << 8)	/* Patch Entry */
++#define RT5670_DSP_CMD_MW		(0x3b << 8)	/* Memory Write */
++#define RT5670_DSP_CMD_MR		(0x37 << 8)	/* Memory Read */
++#define RT5670_DSP_CMD_RR		(0x60 << 8)	/* Register Read */
++#define RT5670_DSP_CMD_RW		(0x68 << 8)	/* Register Write */
++#define RT5670_DSP_REG_DATHI		(0x26 << 8)	/* High Data Addr */
++#define RT5670_DSP_REG_DATLO		(0x25 << 8)	/* Low Data Addr */
++#define RT5670_DSP_CLK_MASK		(0x3 << 6)
++#define RT5670_DSP_CLK_SFT		6
++#define RT5670_DSP_CLK_768K		(0x0 << 6)
++#define RT5670_DSP_CLK_384K		(0x1 << 6)
++#define RT5670_DSP_CLK_192K		(0x2 << 6)
++#define RT5670_DSP_CLK_96K		(0x3 << 6)
++#define RT5670_DSP_BUSY_MASK		(0x1 << 5)
++#define RT5670_DSP_RW_MASK		(0x1 << 4)
++#define RT5670_DSP_DL_MASK		(0x3 << 2)
++#define RT5670_DSP_DL_0			(0x0 << 2)
++#define RT5670_DSP_DL_1			(0x1 << 2)
++#define RT5670_DSP_DL_2			(0x2 << 2)
++#define RT5670_DSP_DL_3			(0x3 << 2)
++#define RT5670_DSP_I2C_AL_16		(0x1 << 1)
++#define RT5670_DSP_CMD_EN		(0x1)
++
++/* Debug String Length */
++#define RT5670_DSP_REG_DISP_LEN 25
++
++
++enum {
++	RT5670_DSP_DIS,
++	RT5670_DSP_NS,
++	RT5670_DSP_AEC,
++	RT5670_DSP_VT,
++	RT5670_DSP_VR,
++	RT5670_DSP_FFP_NS,
++	RT5670_DSP_48K_STO_FFP,
++	RT5670_DSP_2MIC_HANDSET,
++	RT5670_DSP_2MIC_HANDSFREE,
++	RT5670_DSP_AEC_HANDSFREE,
++};
++
++struct rt5670_dsp_param {
++	u16 cmd_fmt;
++	u16 addr;
++	u16 data;
++	u8 cmd;
++};
++
++int rt5670_dsp_probe(struct snd_soc_codec *codec);
++int rt5670_dsp_ioctl_common(struct snd_hwdep *hw,
++	struct file *file, unsigned int cmd, unsigned long arg);
++#ifdef CONFIG_PM
++int rt5670_dsp_suspend(struct snd_soc_codec *codec);
++int rt5670_dsp_resume(struct snd_soc_codec *codec);
++#endif
++
++#endif /* __RT5670_DSP_H__ */
++
+diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
+new file mode 100644
+index 00000000..81d7e11f
+--- /dev/null
++++ b/sound/soc/codecs/rt5670.c
+@@ -0,0 +1,3826 @@
++/*
++ * rt5670.c  --  RT5670 ALSA SoC audio codec driver
++ *
++ * Copyright 2012 Realtek Semiconductor Corp.
++ * Author: Bard Liao <bardliao@realtek.com>
++ *
++ * 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.
++ */
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/jack.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++
++#define RTK_IOCTL
++#ifdef RTK_IOCTL
++#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
++#include "rt_codec_ioctl.h"
++#include "rt5670_ioctl.h"
++#endif
++#endif
++
++#include "rt5670.h"
++#include "rt5670-dsp.h"
++
++static int pmu_depop_time = 80;
++module_param(pmu_depop_time, int, 0644);
++
++static int hp_amp_time = 20;
++module_param(hp_amp_time, int, 0644);
++
++#define RT5672
++#define RT5670_DET_EXT_MIC 0
++//#define USE_INT_CLK
++#define JD1_FUNC
++//#define ALC_DRC_FUNC
++//#define USE_ASRC
++//#define USE_TDM
++//#define NVIDIA_DALMORE
++
++#define VERSION "0.0.7 alsa 1.0.25"
++
++struct snd_soc_codec *rt5670_codec;
++
++struct rt5670_init_reg {
++	u8 reg;
++	u16 val;
++};
++
++static struct rt5670_init_reg init_list[] = {
++	{ RT5670_DIG_MISC	, 0xc019 }, /* fa[0]=1, fa[3]=1'b MCLK det, fa[15:14]=11'b for pdm */
++	{ RT5670_ADDA_CLK1	, 0x0000 },
++	{ RT5670_IL_CMD2	, 0x0010 }, /* set Inline Command Window */
++//	{ RT5670_A_JD_CTRL1	, 0x0001 }, /* set JD1 mode 1 (1 port) */
++	{ RT5670_PRIV_INDEX	, 0x0014 },
++	{ RT5670_PRIV_DATA	, 0x9a8a },
++	{ RT5670_PRIV_INDEX	, 0x003d },
++	{ RT5670_PRIV_DATA	, 0x3640 },
++	{ RT5670_GEN_CTRL2  , 0x0030 }, //by walk
++	{ RT5670_CJ_CTRL1	, 0x4021 },  //by walk
++	{ RT5670_CJ_CTRL2	, 0x28a7 },  //by walk
++	/* playback */
++	{ RT5670_STO_DAC_MIXER	, 0x1616 }, /* Dig inf 1 -> Sto DAC mixer -> DACL */
++	{ RT5670_OUT_L1_MIXER	, 0x0072 }, /* DACL1 -> OUTMIXL */
++	{ RT5670_OUT_R1_MIXER	, 0x00d2 }, /* DACR1 -> OUTMIXR */
++	{ RT5670_LOUT_MIXER	, 0xc000 },
++	{ RT5670_HP_VOL		, 0x8888 }, /* OUTMIX -> HPVOL */
++	{ RT5670_HPO_MIXER	, 0xc00a },
++//	{ RT5670_HPO_MIXER	, 0xa000 }, /* DAC1 -> HPOLMIX */
++	{ RT5670_CHARGE_PUMP	, 0x0c00 },
++	{ RT5670_GPIO_CTRL3	, 0x0d00 }, /* for stereo SPK */
++	/* record */
++	{ RT5670_GEN_CTRL3	, 0x0084},
++	{ RT5670_REC_L2_MIXER	, 0x007d }, /* Mic1 -> RECMIXL */
++	{ RT5670_REC_R2_MIXER	, 0x0077 }, /* Mic1 -> RECMIXR */
++#if 0 /* DMIC2 */
++	{ RT5670_STO1_ADC_MIXER	, 0x5940 },
++#else /* AMIC */
++	{ RT5670_STO1_ADC_MIXER	, 0x3820 }, /* ADC -> Sto ADC mixer */
++#endif
++	{ RT5670_STO1_ADC_DIG_VOL, 0xafaf }, /* Mute STO1 ADC for depop */
++	{ RT5670_PDM_OUT_CTRL	, 0xff01 },
++#ifdef JD1_FUNC
++	{ RT5670_GPIO_CTRL2	, 0x0004 },
++	{ RT5670_GPIO_CTRL1	, 0x8000 },
++	{ RT5670_IRQ_CTRL2	, 0x0200 },
++	{ RT5670_JD_CTRL3	, 0x0088 },
++#endif
++#if 0 //DSP
++	{ RT5670_STO_DAC_MIXER	, 0x4646 },
++	{ RT5670_DSP_PATH1	, 0xc000 },
++	//{ RT5670_DSP_PATH1	, 0xc003 }, /* bypass dsp */
++	{ RT5670_DAC_CTRL	, 0x0033 },
++#endif
++
++};
++#define RT5670_INIT_REG_LEN ARRAY_SIZE(init_list)
++
++#ifdef ALC_DRC_FUNC
++static struct rt5670_init_reg alc_drc_list[] = {
++	{ RT5670_ALC_DRC_CTRL1	, 0x0000 },
++	{ RT5670_ALC_DRC_CTRL2	, 0x0000 },
++	{ RT5670_ALC_CTRL_2	, 0x0000 },
++	{ RT5670_ALC_CTRL_3	, 0x0000 },
++	{ RT5670_ALC_CTRL_4	, 0x0000 },
++	{ RT5670_ALC_CTRL_1	, 0x0000 },
++};
++#define RT5670_ALC_DRC_REG_LEN ARRAY_SIZE(alc_drc_list)
++#endif
++
++static int rt5670_reg_init(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for (i = 0; i < RT5670_INIT_REG_LEN; i++)
++		snd_soc_write(codec, init_list[i].reg, init_list[i].val);
++#ifdef ALC_DRC_FUNC
++	for (i = 0; i < RT5670_ALC_DRC_REG_LEN; i++)
++		snd_soc_write(codec, alc_drc_list[i].reg, alc_drc_list[i].val);
++#endif
++
++	return 0;
++}
++
++static int rt5670_index_sync(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for (i = 0; i < RT5670_INIT_REG_LEN; i++)
++		if (RT5670_PRIV_INDEX == init_list[i].reg ||
++			RT5670_PRIV_DATA == init_list[i].reg)
++			snd_soc_write(codec, init_list[i].reg,
++					init_list[i].val);
++	return 0;
++}
++
++static const u16 rt5670_reg[RT5670_VENDOR_ID2 + 1] = {
++	[RT5670_HP_VOL] = 0x8888,
++	[RT5670_LOUT1] = 0x8888,
++	[RT5670_CJ_CTRL1] = 0x0001,
++	[RT5670_CJ_CTRL2] = 0x0827,
++	[RT5670_IN1_IN2] = 0x0008,
++	[RT5670_INL1_INR1_VOL] = 0x0808,
++	[RT5670_DAC1_DIG_VOL] = 0xafaf,
++	[RT5670_DAC2_DIG_VOL] = 0xafaf,
++	[RT5670_DAC_CTRL] = 0x0011,
++	[RT5670_STO1_ADC_DIG_VOL] = 0x2f2f,
++	[RT5670_MONO_ADC_DIG_VOL] = 0x2f2f,
++	[RT5670_STO2_ADC_DIG_VOL] = 0x2f2f,
++	[RT5670_STO2_ADC_MIXER] = 0x7860,
++	[RT5670_STO1_ADC_MIXER] = 0x7860,
++	[RT5670_MONO_ADC_MIXER] = 0x7871,
++	[RT5670_AD_DA_MIXER] = 0x8080,
++	[RT5670_STO_DAC_MIXER] = 0x5656,
++	[RT5670_DD_MIXER] = 0x5454,
++	[RT5670_DIG_MIXER] = 0xaaa0,
++	[RT5670_DSP_PATH2] = 0x2f2f,
++	[RT5670_DIG_INF1_DATA] = 0x1002,
++	[RT5670_PDM_OUT_CTRL] = 0x5f00,
++	[RT5670_REC_L2_MIXER] = 0x007f,
++	[RT5670_REC_R2_MIXER] = 0x007f,
++	[RT5670_HPO_MIXER] = 0xe00f,
++	[RT5670_MONO_MIXER] = 0x5380,
++	[RT5670_OUT_L1_MIXER] = 0x0073,
++	[RT5670_OUT_R1_MIXER] = 0x00d3,
++	[RT5670_LOUT_MIXER] = 0xf0f0,
++	[RT5670_PWR_DIG2] = 0x0001,
++	[RT5670_PWR_ANLG1] = 0x00c3,
++	[RT5670_I2S4_SDP] = 0x8000,
++	[RT5670_I2S1_SDP] = 0x8000,
++	[RT5670_I2S2_SDP] = 0x8000,
++	[RT5670_I2S3_SDP] = 0x8000,
++	[RT5670_ADDA_CLK1] = 0x1110,
++	[RT5670_ADDA_CLK2] = 0x0e00,
++	[RT5670_DMIC_CTRL1] = 0x1505,
++	[RT5670_DMIC_CTRL2] = 0x0015,
++	[RT5670_TDM_CTRL_1] = 0x0c00,
++	[RT5670_TDM_CTRL_2] = 0x4000,
++	[RT5670_TDM_CTRL_3] = 0x0123,
++	[RT5670_DSP_CLK] = 0x1100,
++	[RT5670_ASRC_4] = 0x0008,
++	[RT5670_ASRC_10] = 0x0007,
++	[RT5670_DEPOP_M1] = 0x0004,
++	[RT5670_DEPOP_M2] = 0x1100,
++	[RT5670_DEPOP_M3] = 0x0646,
++	[RT5670_CHARGE_PUMP] = 0x0c06,
++	[RT5670_VAD_CTRL1] = 0x2184,
++	[RT5670_VAD_CTRL2] = 0x010a,
++	[RT5670_VAD_CTRL3] = 0x0aea,
++	[RT5670_VAD_CTRL4] = 0x000c,
++	[RT5670_VAD_CTRL5] = 0x0400,
++	[RT5670_ADC_EQ_CTRL1] = 0x7000,
++	[RT5670_EQ_CTRL1] = 0x6000,
++	[RT5670_ALC_DRC_CTRL2] = 0x001f,
++	[RT5670_ALC_CTRL_1] = 0x2206,
++	[RT5670_ALC_CTRL_2] = 0x1f00,
++	[RT5670_BASE_BACK] = 0x1813,
++	[RT5670_MP3_PLUS1] = 0x0690,
++	[RT5670_MP3_PLUS2] = 0x1c17,
++	[RT5670_ADJ_HPF1] = 0xb320,
++	[RT5670_HP_CALIB_AMP_DET] = 0x0400,
++	[RT5670_SV_ZCD1] = 0x0809,
++	[RT5670_IL_CMD] = 0x0001,
++	[RT5670_IL_CMD2] = 0x0049,
++	[RT5670_IL_CMD3] = 0x0009,
++	[RT5670_DRC_HL_CTRL1] = 0x8000,
++	[RT5670_ADC_MONO_HP_CTRL1] = 0xb300,
++	[RT5670_ADC_STO2_HP_CTRL1] = 0xb300,
++	[RT5670_DIG_MISC] = 0x8010,
++	[RT5670_GEN_CTRL2] = 0x0033,
++	[RT5670_GEN_CTRL3] = 0x0080,
++};
++
++static int rt5670_reset(struct snd_soc_codec *codec)
++{
++	return snd_soc_write(codec, RT5670_RESET, 0);
++}
++
++/**
++ * rt5670_index_write - Write private register.
++ * @codec: SoC audio codec device.
++ * @reg: Private register index.
++ * @value: Private register Data.
++ *
++ * Modify private register for advanced setting. It can be written through
++ * private index (0x6a) and data (0x6c) register.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_index_write(struct snd_soc_codec *codec,
++		unsigned int reg, unsigned int value)
++{
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_PRIV_INDEX, reg);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PRIV_DATA, value);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	return 0;
++
++err:
++	return ret;
++}
++
++/**
++ * rt5670_index_read - Read private register.
++ * @codec: SoC audio codec device.
++ * @reg: Private register index.
++ *
++ * Read advanced setting from private register. It can be read through
++ * private index (0x6a) and data (0x6c) register.
++ *
++ * Returns private register value or negative error code.
++ */
++static unsigned int rt5670_index_read(
++	struct snd_soc_codec *codec, unsigned int reg)
++{
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_PRIV_INDEX, reg);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
++		return ret;
++	}
++	return snd_soc_read(codec, RT5670_PRIV_DATA);
++}
++
++/**
++ * rt5670_index_update_bits - update private register bits
++ * @codec: audio codec
++ * @reg: Private register index.
++ * @mask: register mask
++ * @value: new value
++ *
++ * Writes new register value.
++ *
++ * Returns 1 for change, 0 for no change, or negative error code.
++ */
++static int rt5670_index_update_bits(struct snd_soc_codec *codec,
++	unsigned int reg, unsigned int mask, unsigned int value)
++{
++	unsigned int old, new;
++	int change, ret;
++
++	ret = rt5670_index_read(codec, reg);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to read private reg: %d\n", ret);
++		goto err;
++	}
++
++	old = ret;
++	new = (old & ~mask) | (value & mask);
++	change = old != new;
++	if (change) {
++		ret = rt5670_index_write(codec, reg, new);
++		if (ret < 0) {
++			dev_err(codec->dev,
++				"Failed to write private reg: %d\n", ret);
++			goto err;
++		}
++	}
++	return change;
++
++err:
++	return ret;
++}
++
++static unsigned rt5670_pdm1_read(struct snd_soc_codec *codec,
++		unsigned int reg)
++{
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_PDM1_DATA_CTRL2, reg<<8);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0200);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	do{
++		ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
++	}
++	while(ret & 0x0100);
++	return snd_soc_read(codec, RT5670_PDM1_DATA_CTRL4);
++err:
++	return ret;
++}
++
++static int rt5670_pdm1_write(struct snd_soc_codec *codec,
++		unsigned int reg, unsigned int value)
++{
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_PDM1_DATA_CTRL3, value);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM1_DATA_CTRL2, reg<<8);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0600);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x3600);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	do{
++		ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
++	}
++	while(ret & 0x0100);
++	return 0;
++
++err:
++	return ret;
++}
++
++static unsigned rt5670_pdm2_read(struct snd_soc_codec *codec,
++		unsigned int reg)
++{
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_PDM2_DATA_CTRL2, reg<<8);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0002);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	do{
++		ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
++	}
++	while(ret & 0x0001);
++	return snd_soc_read(codec, RT5670_PDM2_DATA_CTRL4);
++err:
++	return ret;
++}
++
++static int rt5670_pdm2_write(struct snd_soc_codec *codec,
++		unsigned int reg, unsigned int value)
++{
++	int ret;
++
++	ret = snd_soc_write(codec, RT5670_PDM2_DATA_CTRL3, value);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM2_DATA_CTRL2, reg<<8);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0006);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0036);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set private value: %d\n", ret);
++		goto err;
++	}
++	do{
++		ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
++	}
++	while(ret & 0x0001);
++
++	return 0;
++
++err:
++	return ret;
++}
++
++
++static int rt5670_volatile_register(
++	struct snd_soc_codec *codec, unsigned int reg)
++{
++	switch (reg) {
++	case RT5670_RESET:
++	case RT5670_PDM_DATA_CTRL1:
++	case RT5670_PDM1_DATA_CTRL4:
++	case RT5670_PDM2_DATA_CTRL4:
++	case RT5670_PRIV_DATA:
++	case RT5670_ASRC_5:
++	case RT5670_CJ_CTRL1:
++	case RT5670_CJ_CTRL2:
++	case RT5670_CJ_CTRL3:
++	case RT5670_A_JD_CTRL1:
++	case RT5670_A_JD_CTRL2:
++	case RT5670_VAD_CTRL5:
++	case RT5670_ADC_EQ_CTRL1:
++	case RT5670_EQ_CTRL1:
++	case RT5670_ALC_CTRL_1:
++	case RT5670_IRQ_CTRL2:
++	case RT5670_IRQ_CTRL3:
++	case RT5670_INT_IRQ_ST:
++	case RT5670_IL_CMD:
++	case RT5670_DSP_CTRL1:
++	case RT5670_DSP_CTRL2:
++	case RT5670_DSP_CTRL3:
++	case RT5670_DSP_CTRL4:
++	case RT5670_DSP_CTRL5:
++	case RT5670_VENDOR_ID:
++	case RT5670_VENDOR_ID1:
++	case RT5670_VENDOR_ID2:
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++static int rt5670_readable_register(
++	struct snd_soc_codec *codec, unsigned int reg)
++{
++	switch (reg) {
++	case RT5670_RESET:
++	case RT5670_HP_VOL:
++	case RT5670_LOUT1:
++	case RT5670_CJ_CTRL1:
++	case RT5670_CJ_CTRL2:
++	case RT5670_CJ_CTRL3:
++	case RT5670_IN1_IN2:
++	case RT5670_IN3:
++	case RT5670_INL1_INR1_VOL:
++	case RT5670_DAC1_DIG_VOL:
++	case RT5670_DAC2_DIG_VOL:
++	case RT5670_DAC_CTRL:
++	case RT5670_STO1_ADC_DIG_VOL:
++	case RT5670_MONO_ADC_DIG_VOL:
++	case RT5670_STO2_ADC_DIG_VOL:
++	case RT5670_ADC_BST_VOL1:
++	case RT5670_ADC_BST_VOL2:
++	case RT5670_STO2_ADC_MIXER:
++	case RT5670_STO1_ADC_MIXER:
++	case RT5670_MONO_ADC_MIXER:
++	case RT5670_AD_DA_MIXER:
++	case RT5670_STO_DAC_MIXER:
++	case RT5670_DD_MIXER:
++	case RT5670_DIG_MIXER:
++	case RT5670_DSP_PATH1:
++	case RT5670_DSP_PATH2:
++	case RT5670_DIG_INF1_DATA:
++	case RT5670_DIG_INF2_DATA:
++	case RT5670_PDM_OUT_CTRL:
++	case RT5670_PDM_DATA_CTRL1:
++	case RT5670_PDM1_DATA_CTRL2:
++	case RT5670_PDM1_DATA_CTRL3:
++	case RT5670_PDM1_DATA_CTRL4:
++	case RT5670_PDM2_DATA_CTRL2:
++	case RT5670_PDM2_DATA_CTRL3:
++	case RT5670_PDM2_DATA_CTRL4:
++	case RT5670_REC_L1_MIXER:
++	case RT5670_REC_L2_MIXER:
++	case RT5670_REC_R1_MIXER:
++	case RT5670_REC_R2_MIXER:
++	case RT5670_HPO_MIXER:
++	case RT5670_MONO_MIXER:
++	case RT5670_OUT_L1_MIXER:
++	case RT5670_OUT_R1_MIXER:
++	case RT5670_LOUT_MIXER:
++	case RT5670_PWR_DIG1:
++	case RT5670_PWR_DIG2:
++	case RT5670_PWR_ANLG1:
++	case RT5670_PWR_ANLG2:
++	case RT5670_PWR_MIXER:
++	case RT5670_PWR_VOL:
++	case RT5670_PRIV_INDEX:
++	case RT5670_PRIV_DATA:
++	case RT5670_I2S4_SDP:
++	case RT5670_I2S1_SDP:
++	case RT5670_I2S2_SDP:
++	case RT5670_I2S3_SDP:
++	case RT5670_ADDA_CLK1:
++	case RT5670_ADDA_CLK2:
++	case RT5670_DMIC_CTRL1:
++	case RT5670_DMIC_CTRL2:
++	case RT5670_TDM_CTRL_1:
++	case RT5670_TDM_CTRL_2:
++	case RT5670_TDM_CTRL_3:
++	case RT5670_DSP_CLK:
++	case RT5670_GLB_CLK:
++	case RT5670_PLL_CTRL1:
++	case RT5670_PLL_CTRL2:
++	case RT5670_ASRC_1:
++	case RT5670_ASRC_2:
++	case RT5670_ASRC_3:
++	case RT5670_ASRC_4:
++	case RT5670_ASRC_5:
++	case RT5670_ASRC_7:
++	case RT5670_ASRC_8:
++	case RT5670_ASRC_9:
++	case RT5670_ASRC_10:
++	case RT5670_ASRC_11:
++	case RT5670_ASRC_12:
++	case RT5670_ASRC_13:
++	case RT5670_ASRC_14:
++	case RT5670_DEPOP_M1:
++	case RT5670_DEPOP_M2:
++	case RT5670_DEPOP_M3:
++	case RT5670_CHARGE_PUMP:
++	case RT5670_MICBIAS:
++	case RT5670_A_JD_CTRL1:
++	case RT5670_A_JD_CTRL2:
++	case RT5670_VAD_CTRL1:
++	case RT5670_VAD_CTRL2:
++	case RT5670_VAD_CTRL3:
++	case RT5670_VAD_CTRL4:
++	case RT5670_VAD_CTRL5:
++	case RT5670_ADC_EQ_CTRL1:
++	case RT5670_ADC_EQ_CTRL2:
++	case RT5670_EQ_CTRL1:
++	case RT5670_EQ_CTRL2:
++	case RT5670_ALC_DRC_CTRL1:
++	case RT5670_ALC_DRC_CTRL2:
++	case RT5670_ALC_CTRL_1:
++	case RT5670_ALC_CTRL_2:
++	case RT5670_ALC_CTRL_3:
++	case RT5670_JD_CTRL:
++	case RT5670_IRQ_CTRL1:
++	case RT5670_IRQ_CTRL2:
++	case RT5670_IRQ_CTRL3:
++	case RT5670_INT_IRQ_ST:
++	case RT5670_GPIO_CTRL1:
++	case RT5670_GPIO_CTRL2:
++	case RT5670_GPIO_CTRL3:
++	case RT5670_SCRABBLE_FUN:
++	case RT5670_SCRABBLE_CTRL:
++	case RT5670_BASE_BACK:
++	case RT5670_MP3_PLUS1:
++	case RT5670_MP3_PLUS2:
++	case RT5670_ADJ_HPF1:
++	case RT5670_ADJ_HPF2:
++	case RT5670_HP_CALIB_AMP_DET:
++	case RT5670_SV_ZCD1:
++	case RT5670_SV_ZCD2:
++	case RT5670_IL_CMD:
++	case RT5670_IL_CMD2:
++	case RT5670_IL_CMD3:
++	case RT5670_DRC_HL_CTRL1:
++	case RT5670_DRC_HL_CTRL2:
++	case RT5670_ADC_MONO_HP_CTRL1:
++	case RT5670_ADC_MONO_HP_CTRL2:
++	case RT5670_ADC_STO2_HP_CTRL1:
++	case RT5670_ADC_STO2_HP_CTRL2:
++	case RT5670_JD_CTRL3:
++	case RT5670_JD_CTRL4:
++	case RT5670_DIG_MISC:
++	case RT5670_DSP_CTRL1:
++	case RT5670_DSP_CTRL2:
++	case RT5670_DSP_CTRL3:
++	case RT5670_DSP_CTRL4:
++	case RT5670_DSP_CTRL5:
++	case RT5670_GEN_CTRL2:
++	case RT5670_GEN_CTRL3:
++	case RT5670_VENDOR_ID:
++	case RT5670_VENDOR_ID1:
++	case RT5670_VENDOR_ID2:
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++/**
++ * rt5670_headset_detect - Detect headset.
++ * @codec: SoC audio codec device.
++ * @jack_insert: Jack insert or not.
++ *
++ * Detect whether is headset or not when jack inserted.
++ *
++ * Returns detect status.
++ */
++
++int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
++{
++	int jack_type, val;
++
++	if(jack_insert) {
++		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
++		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
++			RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
++			RT5670_CBJ_MN_JD);
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_JD1, RT5670_PWR_JD1);
++		snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x1);
++		snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
++
++		snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
++			RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
++		snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
++		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
++			RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
++		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
++			RT5670_CBJ_MN_JD, 0);
++		msleep(500);
++		val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
++		pr_debug("val=%d\n",val);
++		if (val == 0x1 || val == 0x2) {
++			jack_type = SND_JACK_HEADSET;
++			/* for push button */
++			snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
++			snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
++			snd_soc_read(codec, RT5670_IL_CMD);
++		} else {
++			snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
++			jack_type = SND_JACK_HEADPHONE;
++		}
++	} else {
++		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
++		snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
++		jack_type = 0;
++	}
++
++	pr_debug("jack_type=%d\n",jack_type);
++	return jack_type;
++}
++EXPORT_SYMBOL(rt5670_headset_detect);
++
++int rt5670_button_detect(struct snd_soc_codec *codec)
++{
++	int btn_type, val;
++
++	snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
++
++	val = snd_soc_read(codec, RT5670_IL_CMD);
++	btn_type = val & 0xff80;
++	pr_debug("btn_type=0x%x\n",btn_type);
++	snd_soc_write(codec, RT5670_IL_CMD, val);
++	return btn_type;
++}
++EXPORT_SYMBOL(rt5670_button_detect);
++
++int rt5670_check_interrupt_event(struct snd_soc_codec *codec, int *data)
++{
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	int val, event_type;
++
++	val = snd_soc_read(codec, RT5670_A_JD_CTRL1) & 0x0020;
++	*data = 0;
++	switch (val) {
++	case 0x0:
++		/* jack insert */
++		if (rt5670->jack_type == 0) {
++			snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power");
++			snd_soc_dapm_sync(&codec->dapm);
++			rt5670->jack_type = rt5670_headset_detect(codec, 1);
++			*data = rt5670->jack_type;
++			return RT5670_J_IN_EVENT;
++		}
++		event_type = 0;
++		if (snd_soc_read(codec, RT5670_INT_IRQ_ST) & 0x4) {
++			/* button event */
++			event_type |= RT5670_BTN_EVENT;
++			*data = rt5670_button_detect(codec);
++		}
++		msleep(20);
++		if (*data == 0 ||
++			((snd_soc_read(codec, RT5670_IL_CMD) & 0xff80) == 0)) {
++			pr_debug("button release\n");
++			event_type = RT5670_BR_EVENT;
++			*data = 0;
++		}
++		return (event_type == 0 ? RT5670_UN_EVENT : event_type);
++	case 0x20:
++	default:
++		rt5670->jack_type = rt5670_headset_detect(codec, 0);
++		snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
++		snd_soc_dapm_sync(&codec->dapm);
++		return RT5670_J_OUT_EVENT;
++	}
++
++	return RT5670_UN_EVENT;
++}
++EXPORT_SYMBOL(rt5670_check_interrupt_event);
++
++static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
++static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
++static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
++static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
++static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
++
++/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
++static unsigned int bst_tlv[] = {
++	TLV_DB_RANGE_HEAD(7),
++	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
++	1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
++	2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
++	3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
++	6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
++	7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
++	8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
++};
++
++/* IN1/IN2 Input Type */
++static const char *rt5670_input_mode[] = {
++	"Single ended", "Differential"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_in1_mode_enum, RT5670_IN1_IN2,
++	RT5670_IN_SFT1, rt5670_input_mode);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_in2_mode_enum, RT5670_IN3,
++	RT5670_IN_SFT2, rt5670_input_mode);
++
++/* Interface data select */
++static const char *rt5670_data_select[] = {
++	"Normal", "Swap", "left copy to right", "right copy to left"
++};
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_if2_dac_enum, RT5670_DIG_INF1_DATA,
++				RT5670_IF2_DAC_SEL_SFT, rt5670_data_select);
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_if2_adc_enum, RT5670_DIG_INF1_DATA,
++				RT5670_IF2_ADC_SEL_SFT, rt5670_data_select);
++
++static const char *rt5670_tdm_adc_location_select[] = {
++	"1L/1R/2L/2R/3L/3R/4L/4R", "2L/2R/1L/1R/4L/4R/3L/3R"
++};
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_location_enum,
++				RT5670_TDM_CTRL_1, 9,
++				rt5670_tdm_adc_location_select);
++
++static const char *rt5670_tdm_data_swap_select[] = {
++	"L/R", "R/L", "L/L", "R/R"
++};
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot0_1_enum,
++				RT5670_TDM_CTRL_1, 6,
++				rt5670_tdm_data_swap_select);
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot2_3_enum,
++				RT5670_TDM_CTRL_1, 4,
++				rt5670_tdm_data_swap_select);
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot4_5_enum,
++				RT5670_TDM_CTRL_1, 2,
++				rt5670_tdm_data_swap_select);
++
++static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot6_7_enum,
++				RT5670_TDM_CTRL_1, 0,
++				rt5670_tdm_data_swap_select);
++
++static int rt5670_vol_rescale_get(struct snd_kcontrol *kcontrol,
++		struct snd_ctl_elem_value *ucontrol)
++{
++	struct soc_mixer_control *mc =
++		(struct soc_mixer_control *)kcontrol->private_value;
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned int val = snd_soc_read(codec, mc->reg);
++
++	ucontrol->value.integer.value[0] = RT5670_VOL_RSCL_MAX -
++		((val & RT5670_L_VOL_MASK) >> mc->shift);
++	ucontrol->value.integer.value[1] = RT5670_VOL_RSCL_MAX -
++		(val & RT5670_R_VOL_MASK);
++
++	return 0;
++}
++
++static int rt5670_vol_rescale_put(struct snd_kcontrol *kcontrol,
++		struct snd_ctl_elem_value *ucontrol)
++{
++	struct soc_mixer_control *mc =
++		(struct soc_mixer_control *)kcontrol->private_value;
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	unsigned int val, val2;
++
++	val = RT5670_VOL_RSCL_MAX - ucontrol->value.integer.value[0];
++	val2 = RT5670_VOL_RSCL_MAX - ucontrol->value.integer.value[1];
++	return snd_soc_update_bits_locked(codec, mc->reg, RT5670_L_VOL_MASK |
++			RT5670_R_VOL_MASK, val << mc->shift | val2);
++}
++
++
++static const struct snd_kcontrol_new rt5670_snd_controls[] = {
++	/* Headphone Output Volume */
++	SOC_DOUBLE("HP Playback Switch", RT5670_HP_VOL,
++		RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
++	SOC_DOUBLE_EXT_TLV("HP Playback Volume", RT5670_HP_VOL,
++		RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, RT5670_VOL_RSCL_RANGE, 0,
++		rt5670_vol_rescale_get, rt5670_vol_rescale_put, out_vol_tlv),
++	/* OUTPUT Control */
++	SOC_DOUBLE("OUT Playback Switch", RT5670_LOUT1,
++		RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
++	SOC_DOUBLE("OUT Channel Switch", RT5670_LOUT1,
++		RT5670_VOL_L_SFT, RT5670_VOL_R_SFT, 1, 1),
++	SOC_DOUBLE_TLV("OUT Playback Volume", RT5670_LOUT1,
++		RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, 39, 1, out_vol_tlv),
++	/* DAC Digital Volume */
++	SOC_DOUBLE("DAC2 Playback Switch", RT5670_DAC_CTRL,
++		RT5670_M_DAC_L2_VOL_SFT, RT5670_M_DAC_R2_VOL_SFT, 1, 1),
++	SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5670_DAC1_DIG_VOL,
++			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
++			175, 0, dac_vol_tlv),
++	SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5670_DAC2_DIG_VOL,
++			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
++			175, 0, dac_vol_tlv),
++	/* IN1/IN2 Control */
++	SOC_ENUM("IN1 Mode Control",  rt5670_in1_mode_enum),
++	SOC_SINGLE_TLV("IN1 Boost", RT5670_IN1_IN2,
++		RT5670_BST_SFT1, 8, 0, bst_tlv),
++	SOC_ENUM("IN2 Mode Control", rt5670_in2_mode_enum),
++	SOC_SINGLE_TLV("IN2 Boost", RT5670_IN3,
++		RT5670_BST_SFT2, 8, 0, bst_tlv),
++	/* INL/INR Volume Control */
++	SOC_DOUBLE_TLV("IN Capture Volume", RT5670_INL1_INR1_VOL,
++			RT5670_INL_VOL_SFT, RT5670_INR_VOL_SFT,
++			31, 1, in_vol_tlv),
++	/* ADC Digital Volume Control */
++	SOC_DOUBLE("ADC Capture Switch", RT5670_STO1_ADC_DIG_VOL,
++		RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
++	SOC_DOUBLE_TLV("ADC Capture Volume", RT5670_STO1_ADC_DIG_VOL,
++			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
++			127, 0, adc_vol_tlv),
++
++	SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5670_MONO_ADC_DIG_VOL,
++			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
++			127, 0, adc_vol_tlv),
++
++	/* ADC Boost Volume Control */
++	SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5670_ADC_BST_VOL1,
++			RT5670_STO1_ADC_L_BST_SFT, RT5670_STO1_ADC_R_BST_SFT,
++			3, 0, adc_bst_tlv),
++
++	SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5670_ADC_BST_VOL1,
++			RT5670_STO2_ADC_L_BST_SFT, RT5670_STO2_ADC_R_BST_SFT,
++			3, 0, adc_bst_tlv),
++
++	/* TDM */
++	SOC_ENUM("TDM Adc Location", rt5670_tdm_adc_location_enum),
++	SOC_ENUM("TDM Adc Slot0 1 Data", rt5670_tdm_adc_slot0_1_enum),
++	SOC_ENUM("TDM Adc Slot2 3 Data", rt5670_tdm_adc_slot2_3_enum),
++	SOC_ENUM("TDM Adc Slot4 5 Data", rt5670_tdm_adc_slot4_5_enum),
++	SOC_ENUM("TDM Adc Slot6 7 Data", rt5670_tdm_adc_slot6_7_enum),
++	SOC_SINGLE("TDM IF1_DAC1_L Sel", RT5670_TDM_CTRL_3, 12, 7, 0),
++	SOC_SINGLE("TDM IF1_DAC1_R Sel", RT5670_TDM_CTRL_3, 8, 7, 0),
++	SOC_SINGLE("TDM IF1_DAC2_L Sel", RT5670_TDM_CTRL_3, 4, 7, 0),
++	SOC_SINGLE("TDM IF1_DAC2_R Sel", RT5670_TDM_CTRL_3, 0, 7, 0),
++};
++
++/**
++ * set_dmic_clk - Set parameter of dmic.
++ *
++ * @w: DAPM widget.
++ * @kcontrol: The kcontrol of this widget.
++ * @event: Event id.
++ *
++ * Choose dmic clock between 1MHz and 3MHz.
++ * It is better for clock to approximate 3MHz.
++ */
++static int set_dmic_clk(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL, i;
++	int rate, red, bound, temp;
++
++	rate = rt5670->lrck[rt5670->aif_pu] << 8;
++	red = 2000000 * 12;
++	for (i = 0; i < ARRAY_SIZE(div); i++) {
++		bound = div[i] * 2000000;
++		if (rate > bound)
++			continue;
++		temp = bound - rate;
++		if (temp < red) {
++			red = temp;
++			idx = i;
++		}
++	}
++#ifdef USE_ASRC
++	idx = 5;
++#endif
++	if (idx < 0)
++		dev_err(codec->dev, "Failed to set DMIC clock\n");
++	else
++		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
++			RT5670_DMIC_CLK_MASK, idx << RT5670_DMIC_CLK_SFT);
++	return idx;
++}
++
++static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
++			 struct snd_soc_dapm_widget *sink)
++{
++	unsigned int val;
++
++	val = snd_soc_read(source->codec, RT5670_GLB_CLK);
++	val &= RT5670_SCLK_SRC_MASK;
++	if (val == RT5670_SCLK_SRC_PLL1)
++		return 1;
++	else
++		return 0;
++}
++
++/* Digital Mixer */
++static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
++	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
++			RT5670_M_ADC_L1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO1_ADC_MIXER,
++			RT5670_M_ADC_L2_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_sto1_adc_r_mix[] = {
++	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
++			RT5670_M_ADC_R1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO1_ADC_MIXER,
++			RT5670_M_ADC_R2_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_l_mix[] = {
++	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO2_ADC_MIXER,
++			RT5670_M_ADC_L1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO2_ADC_MIXER,
++			RT5670_M_ADC_L2_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_r_mix[] = {
++	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO2_ADC_MIXER,
++			RT5670_M_ADC_R1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO2_ADC_MIXER,
++			RT5670_M_ADC_R2_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_mono_adc_l_mix[] = {
++	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_MONO_ADC_MIXER,
++			RT5670_M_MONO_ADC_L1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_MONO_ADC_MIXER,
++			RT5670_M_MONO_ADC_L2_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_mono_adc_r_mix[] = {
++	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_MONO_ADC_MIXER,
++			RT5670_M_MONO_ADC_R1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_MONO_ADC_MIXER,
++			RT5670_M_MONO_ADC_R2_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_dac_l_mix[] = {
++	SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER,
++			RT5670_M_ADCMIX_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_AD_DA_MIXER,
++			RT5670_M_DAC1_L_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_dac_r_mix[] = {
++	SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER,
++			RT5670_M_ADCMIX_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_AD_DA_MIXER,
++			RT5670_M_DAC1_R_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_sto_dac_l_mix[] = {
++	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_STO_DAC_MIXER,
++			RT5670_M_DAC_L1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_STO_DAC_MIXER,
++			RT5670_M_DAC_L2_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_STO_DAC_MIXER,
++			RT5670_M_DAC_R1_STO_L_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_sto_dac_r_mix[] = {
++	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_STO_DAC_MIXER,
++			RT5670_M_DAC_R1_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_STO_DAC_MIXER,
++			RT5670_M_DAC_R2_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_STO_DAC_MIXER,
++			RT5670_M_DAC_L1_STO_R_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_mono_dac_l_mix[] = {
++	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_DD_MIXER,
++			RT5670_M_DAC_L1_MONO_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DD_MIXER,
++			RT5670_M_DAC_L2_MONO_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DD_MIXER,
++			RT5670_M_DAC_R2_MONO_L_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_mono_dac_r_mix[] = {
++	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_DD_MIXER,
++			RT5670_M_DAC_R1_MONO_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DD_MIXER,
++			RT5670_M_DAC_R2_MONO_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DD_MIXER,
++			RT5670_M_DAC_L2_MONO_R_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_dig_l_mix[] = {
++	SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5670_DIG_MIXER,
++			RT5670_M_STO_L_DAC_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DIG_MIXER,
++			RT5670_M_DAC_L2_DAC_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DIG_MIXER,
++			RT5670_M_DAC_R2_DAC_L_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_dig_r_mix[] = {
++	SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5670_DIG_MIXER,
++			RT5670_M_STO_R_DAC_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DIG_MIXER,
++			RT5670_M_DAC_R2_DAC_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DIG_MIXER,
++			RT5670_M_DAC_L2_DAC_R_SFT, 1, 1),
++};
++
++/* Analog Input Mixer */
++static const struct snd_kcontrol_new rt5670_rec_l_mix[] = {
++	SOC_DAPM_SINGLE("INL Switch", RT5670_REC_L2_MIXER,
++			RT5670_M_IN_L_RM_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("BST2 Switch", RT5670_REC_L2_MIXER,
++			RT5670_M_BST2_RM_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("BST1 Switch", RT5670_REC_L2_MIXER,
++			RT5670_M_BST1_RM_L_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_rec_r_mix[] = {
++	SOC_DAPM_SINGLE("INR Switch", RT5670_REC_R2_MIXER,
++			RT5670_M_IN_R_RM_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("BST2 Switch", RT5670_REC_R2_MIXER,
++			RT5670_M_BST2_RM_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("BST1 Switch", RT5670_REC_R2_MIXER,
++			RT5670_M_BST1_RM_R_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_out_l_mix[] = {
++	SOC_DAPM_SINGLE("BST1 Switch", RT5670_OUT_L1_MIXER,
++			RT5670_M_BST1_OM_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("INL Switch", RT5670_OUT_L1_MIXER,
++			RT5670_M_IN_L_OM_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_OUT_L1_MIXER,
++			RT5670_M_DAC_L2_OM_L_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_OUT_L1_MIXER,
++			RT5670_M_DAC_L1_OM_L_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_out_r_mix[] = {
++	SOC_DAPM_SINGLE("BST2 Switch", RT5670_OUT_R1_MIXER,
++			RT5670_M_BST2_OM_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("INR Switch", RT5670_OUT_R1_MIXER,
++			RT5670_M_IN_R_OM_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_OUT_R1_MIXER,
++			RT5670_M_DAC_R2_OM_R_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_OUT_R1_MIXER,
++			RT5670_M_DAC_R1_OM_R_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_hpo_mix[] = {
++	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_DAC1_HM_SFT, 1, 1),
++	SOC_DAPM_SINGLE("HPVOL Switch", RT5670_HPO_MIXER,
++			RT5670_M_HPVOL_HM_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_hpvoll_mix[] = {
++	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_DACL1_HML_SFT, 1, 1),
++	SOC_DAPM_SINGLE("INL Switch", RT5670_HPO_MIXER,
++			RT5670_M_INL1_HML_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_hpvolr_mix[] = {
++	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_DACR1_HMR_SFT, 1, 1),
++	SOC_DAPM_SINGLE("INR Switch", RT5670_HPO_MIXER,
++			RT5670_M_INR1_HMR_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_lout_mix[] = {
++	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_LOUT_MIXER,
++			RT5670_M_DAC_L1_LM_SFT, 1, 1),
++	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_LOUT_MIXER,
++			RT5670_M_DAC_R1_LM_SFT, 1, 1),
++	SOC_DAPM_SINGLE("OUTMIX L Switch", RT5670_LOUT_MIXER,
++			RT5670_M_OV_L_LM_SFT, 1, 1),
++	SOC_DAPM_SINGLE("OUTMIX R Switch", RT5670_LOUT_MIXER,
++			RT5670_M_OV_R_LM_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_monoamp_mix[] = {
++	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_MONO_MIXER,
++			RT5670_M_DAC_L2_MA_SFT, 1, 1),
++	SOC_DAPM_SINGLE("MONOVOL Switch", RT5670_MONO_MIXER,
++			RT5670_M_OV_L_MM_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_hpl_mix[] = {
++	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_DACL1_HML_SFT, 1, 1),
++	SOC_DAPM_SINGLE("INL1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_INL1_HML_SFT, 1, 1),
++};
++
++static const struct snd_kcontrol_new rt5670_hpr_mix[] = {
++	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_DACR1_HMR_SFT, 1, 1),
++	SOC_DAPM_SINGLE("INR1 Switch", RT5670_HPO_MIXER,
++			RT5670_M_INR1_HMR_SFT, 1, 1),
++};
++
++/* DAC1 L/R source */ /* MX-29 [9:8] [11:10] */
++static const char *rt5670_dac1_src[] = {
++	"IF1 DAC", "IF2 DAC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_dac1l_enum, RT5670_AD_DA_MIXER,
++	RT5670_DAC1_L_SEL_SFT, rt5670_dac1_src);
++
++static const struct snd_kcontrol_new rt5670_dac1l_mux =
++	SOC_DAPM_ENUM("DAC1 L source", rt5670_dac1l_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_dac1r_enum, RT5670_AD_DA_MIXER,
++	RT5670_DAC1_R_SEL_SFT, rt5670_dac1_src);
++
++static const struct snd_kcontrol_new rt5670_dac1r_mux =
++	SOC_DAPM_ENUM("DAC1 R source", rt5670_dac1r_enum);
++
++/*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */\
++/* TODO Use SOC_VALUE_ENUM_SINGLE_DECL */
++static const char *rt5670_dac12_src[] = {
++	"IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "Bass", "VAD_ADC", "IF4 DAC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_dac2l_enum, RT5670_DAC_CTRL,
++	RT5670_DAC2_L_SEL_SFT, rt5670_dac12_src);
++
++static const struct snd_kcontrol_new rt5670_dac_l2_mux =
++	SOC_DAPM_ENUM("DAC2 L source", rt5670_dac2l_enum);
++
++static const char *rt5670_dacr2_src[] = {
++	"IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "TxDP ADC", "IF4 DAC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_dac2r_enum, RT5670_DAC_CTRL,
++	RT5670_DAC2_R_SEL_SFT, rt5670_dacr2_src);
++
++static const struct snd_kcontrol_new rt5670_dac_r2_mux =
++	SOC_DAPM_ENUM("DAC2 R source", rt5670_dac2r_enum);
++
++/*RxDP source*/ /* MX-2D [15:13] */
++static const char *rt5670_rxdp_src[] = {
++	"IF2 DAC", "IF1 DAC", "STO1 ADC Mixer", "STO2 ADC Mixer",
++	"Mono ADC Mixer L", "Mono ADC Mixer R", "DAC1"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_rxdp_enum, RT5670_DSP_PATH1,
++	RT5670_RXDP_SEL_SFT, rt5670_rxdp_src);
++
++static const struct snd_kcontrol_new rt5670_rxdp_mux =
++	SOC_DAPM_ENUM("DAC2 L source", rt5670_rxdp_enum);
++
++/* MX-2D [1] [0] */
++static const char *rt5670_dsp_bypass_src[] = {
++	"DSP", "Bypass"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_dsp_ul_enum, RT5670_DSP_PATH1,
++	RT5670_DSP_UL_SFT, rt5670_dsp_bypass_src);
++
++static const struct snd_kcontrol_new rt5670_dsp_ul_mux =
++	SOC_DAPM_ENUM("DSP UL source", rt5670_dsp_ul_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_dsp_dl_enum, RT5670_DSP_PATH1,
++	RT5670_DSP_DL_SFT, rt5670_dsp_bypass_src);
++
++static const struct snd_kcontrol_new rt5670_dsp_dl_mux =
++	SOC_DAPM_ENUM("DSP DL source", rt5670_dsp_dl_enum);
++
++
++/* INL/R source */
++static const char *rt5670_inl_src[] = {
++	"IN2P", "MonoP"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_inl_enum, RT5670_INL1_INR1_VOL,
++	RT5670_INL_SEL_SFT, rt5670_inl_src);
++
++static const struct snd_kcontrol_new rt5670_inl_mux =
++	SOC_DAPM_ENUM("INL source", rt5670_inl_enum);
++
++static const char *rt5670_inr_src[] = {
++	"IN2N", "MonoN"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_inr_enum, RT5670_INL1_INR1_VOL,
++	RT5670_INR_SEL_SFT, rt5670_inr_src);
++
++static const struct snd_kcontrol_new rt5670_inr_mux =
++	SOC_DAPM_ENUM("INR source", rt5670_inr_enum);
++
++/* Stereo2 ADC source */
++/* MX-26 [15] */
++static const char *rt5670_stereo2_adc_lr_src[] = {
++	"L", "LR"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo2_adc_lr_enum, RT5670_STO2_ADC_MIXER,
++	RT5670_STO2_ADC_SRC_SFT, rt5670_stereo2_adc_lr_src);
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_lr_mux =
++	SOC_DAPM_ENUM("Stereo2 ADC LR source", rt5670_stereo2_adc_lr_enum);
++
++/* Stereo1 ADC source */
++/* MX-27 MX-26 [12] */
++static const char *rt5670_stereo_adc1_src[] = {
++	"DAC MIX", "ADC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER,
++	RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src);
++
++static const struct snd_kcontrol_new rt5670_sto_adc_l1_mux =
++	SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5670_stereo1_adc1_enum);
++
++static const struct snd_kcontrol_new rt5670_sto_adc_r1_mux =
++	SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5670_stereo1_adc1_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER,
++	RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src);
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_l1_mux =
++	SOC_DAPM_ENUM("Stereo2 ADC L1 source", rt5670_stereo2_adc1_enum);
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_r1_mux =
++	SOC_DAPM_ENUM("Stereo2 ADC R1 source", rt5670_stereo2_adc1_enum);
++
++/* MX-27 MX-26 [11] */
++static const char *rt5670_stereo_adc2_src[] = {
++	"DAC MIX", "DMIC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER,
++	RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src);
++
++static const struct snd_kcontrol_new rt5670_sto_adc_l2_mux =
++	SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5670_stereo1_adc2_enum);
++
++static const struct snd_kcontrol_new rt5670_sto_adc_r2_mux =
++	SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5670_stereo1_adc2_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER,
++	RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src);
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_l2_mux =
++	SOC_DAPM_ENUM("Stereo2 ADC L2 source", rt5670_stereo2_adc2_enum);
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_r2_mux =
++	SOC_DAPM_ENUM("Stereo2 ADC R2 source", rt5670_stereo2_adc2_enum);
++
++/* MX-27 MX26 [10] */
++static const char *rt5670_stereo_adc_src[] = {
++	"ADC1L ADC2R", "ADC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo1_adc_enum, RT5670_STO1_ADC_MIXER,
++	RT5670_ADC_SRC_SFT, rt5670_stereo_adc_src);
++
++static const struct snd_kcontrol_new rt5670_sto_adc_mux =
++	SOC_DAPM_ENUM("Stereo1 ADC source", rt5670_stereo1_adc_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo2_adc_enum, RT5670_STO2_ADC_MIXER,
++	RT5670_ADC_SRC_SFT, rt5670_stereo_adc_src);
++
++static const struct snd_kcontrol_new rt5670_sto2_adc_mux =
++	SOC_DAPM_ENUM("Stereo2 ADC source", rt5670_stereo2_adc_enum);
++
++/* MX-27 MX-26 [9:8] */
++static const char *rt5670_stereo_dmic_src[] = {
++	"DMIC1", "DMIC2", "DMIC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo1_dmic_enum, RT5670_STO1_ADC_MIXER,
++	RT5670_DMIC_SRC_SFT, rt5670_stereo_dmic_src);
++
++static const struct snd_kcontrol_new rt5670_sto1_dmic_mux =
++	SOC_DAPM_ENUM("Stereo1 DMIC source", rt5670_stereo1_dmic_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo2_dmic_enum, RT5670_STO2_ADC_MIXER,
++	RT5670_DMIC_SRC_SFT, rt5670_stereo_dmic_src);
++
++static const struct snd_kcontrol_new rt5670_sto2_dmic_mux =
++	SOC_DAPM_ENUM("Stereo2 DMIC source", rt5670_stereo2_dmic_enum);
++
++/* MX-27 [0] */
++static const char *rt5670_stereo_dmic3_src[] = {
++	"DMIC3", "PDM ADC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_stereo_dmic3_enum, RT5670_STO1_ADC_MIXER,
++	RT5670_DMIC3_SRC_SFT, rt5670_stereo_dmic3_src);
++
++static const struct snd_kcontrol_new rt5670_sto_dmic3_mux =
++	SOC_DAPM_ENUM("Stereo DMIC3 source", rt5670_stereo_dmic3_enum);
++
++/* Mono ADC source */
++/* MX-28 [12] */
++static const char *rt5670_mono_adc_l1_src[] = {
++	"Mono DAC MIXL", "ADC1"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_adc_l1_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_ADC_L1_SRC_SFT, rt5670_mono_adc_l1_src);
++
++static const struct snd_kcontrol_new rt5670_mono_adc_l1_mux =
++	SOC_DAPM_ENUM("Mono ADC1 left source", rt5670_mono_adc_l1_enum);
++/* MX-28 [11] */
++static const char *rt5670_mono_adc_l2_src[] = {
++	"Mono DAC MIXL", "DMIC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_adc_l2_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_ADC_L2_SRC_SFT, rt5670_mono_adc_l2_src);
++
++static const struct snd_kcontrol_new rt5670_mono_adc_l2_mux =
++	SOC_DAPM_ENUM("Mono ADC2 left source", rt5670_mono_adc_l2_enum);
++
++/* MX-28 [10] */
++static const char *rt5670_mono_adc_l_src[] = {
++	"ADC1", "ADC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_adc_l_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_ADC_L_SRC_SFT, rt5670_mono_adc_l_src);
++
++static const struct snd_kcontrol_new rt5670_mono_adc_l_mux =
++	SOC_DAPM_ENUM("Mono ADC left source", rt5670_mono_adc_l_enum);
++
++/* MX-28 [9:8] */
++static const char *rt5670_mono_dmic_src[] = {
++	"DMIC1", "DMIC2", "DMIC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_dmic_l_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_DMIC_L_SRC_SFT, rt5670_mono_dmic_src);
++
++static const struct snd_kcontrol_new rt5670_mono_dmic_l_mux =
++	SOC_DAPM_ENUM("Mono DMIC left source", rt5670_mono_dmic_l_enum);
++/* MX-28 [1:0] */
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_dmic_r_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_DMIC_R_SRC_SFT, rt5670_mono_dmic_src);
++
++static const struct snd_kcontrol_new rt5670_mono_dmic_r_mux =
++	SOC_DAPM_ENUM("Mono DMIC Right source", rt5670_mono_dmic_r_enum);
++/* MX-28 [4] */
++static const char *rt5670_mono_adc_r1_src[] = {
++	"Mono DAC MIXR", "ADC2"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_adc_r1_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_ADC_R1_SRC_SFT, rt5670_mono_adc_r1_src);
++
++static const struct snd_kcontrol_new rt5670_mono_adc_r1_mux =
++	SOC_DAPM_ENUM("Mono ADC1 right source", rt5670_mono_adc_r1_enum);
++/* MX-28 [3] */
++static const char *rt5670_mono_adc_r2_src[] = {
++	"Mono DAC MIXR", "DMIC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_adc_r2_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_ADC_R2_SRC_SFT, rt5670_mono_adc_r2_src);
++
++static const struct snd_kcontrol_new rt5670_mono_adc_r2_mux =
++	SOC_DAPM_ENUM("Mono ADC2 right source", rt5670_mono_adc_r2_enum);
++
++/* MX-28 [2] */
++static const char *rt5670_mono_adc_r_src[] = {
++	"ADC2", "ADC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_mono_adc_r_enum, RT5670_MONO_ADC_MIXER,
++	RT5670_MONO_ADC_R_SRC_SFT, rt5670_mono_adc_r_src);
++
++static const struct snd_kcontrol_new rt5670_mono_adc_r_mux =
++	SOC_DAPM_ENUM("Mono ADC Right source", rt5670_mono_adc_r_enum);
++
++/* MX-2F [15] */
++static const char *rt5670_if1_adc2_in_src[] = {
++	"IF_ADC2", "VAD_ADC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_if1_adc2_in_enum, RT5670_DIG_INF1_DATA,
++	RT5670_IF1_ADC2_IN_SFT, rt5670_if1_adc2_in_src);
++
++static const struct snd_kcontrol_new rt5670_if1_adc2_in_mux =
++	SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5670_if1_adc2_in_enum);
++
++/* MX-2F [14:12] */
++static const char *rt5670_if2_adc_in_src[] = {
++	"IF_ADC1", "IF_ADC2", "IF_ADC3", "TxDC_DAC", "TxDP_ADC", "VAD_ADC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_if2_adc_in_enum, RT5670_DIG_INF1_DATA,
++	RT5670_IF2_ADC_IN_SFT, rt5670_if2_adc_in_src);
++
++static const struct snd_kcontrol_new rt5670_if2_adc_in_mux =
++	SOC_DAPM_ENUM("IF2 ADC IN source", rt5670_if2_adc_in_enum);
++
++/* MX-30 [5:4] */
++static const char *rt5670_if4_adc_in_src[] = {
++	"IF_ADC1", "IF_ADC2", "IF_ADC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_if4_adc_in_enum, RT5670_DIG_INF2_DATA,
++	RT5670_IF4_ADC_IN_SFT, rt5670_if4_adc_in_src);
++
++static const struct snd_kcontrol_new rt5670_if4_adc_in_mux =
++	SOC_DAPM_ENUM("IF4 ADC IN source", rt5670_if4_adc_in_enum);
++
++/* MX-31 [15] [13] [11] [9] */
++static const char *rt5670_pdm_src[] = {
++	"Mono DAC", "Stereo DAC"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_pdm1_l_enum, RT5670_PDM_OUT_CTRL,
++	RT5670_PDM1_L_SFT, rt5670_pdm_src);
++
++static const struct snd_kcontrol_new rt5670_pdm1_l_mux =
++	SOC_DAPM_ENUM("PDM1 L source", rt5670_pdm1_l_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_pdm1_r_enum, RT5670_PDM_OUT_CTRL,
++	RT5670_PDM1_R_SFT, rt5670_pdm_src);
++
++static const struct snd_kcontrol_new rt5670_pdm1_r_mux =
++	SOC_DAPM_ENUM("PDM1 R source", rt5670_pdm1_r_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_pdm2_l_enum, RT5670_PDM_OUT_CTRL,
++	RT5670_PDM2_L_SFT, rt5670_pdm_src);
++
++static const struct snd_kcontrol_new rt5670_pdm2_l_mux =
++	SOC_DAPM_ENUM("PDM2 L source", rt5670_pdm2_l_enum);
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_pdm2_r_enum, RT5670_PDM_OUT_CTRL,
++	RT5670_PDM2_R_SFT, rt5670_pdm_src);
++
++static const struct snd_kcontrol_new rt5670_pdm2_r_mux =
++	SOC_DAPM_ENUM("PDM2 R source", rt5670_pdm2_r_enum);
++
++/* MX-FA [12] */
++static const char *rt5670_if1_adc1_in1_src[] = {
++	"IF_ADC1", "IF1_ADC3"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_if1_adc1_in1_enum, RT5670_DIG_MISC,
++	RT5670_IF1_ADC1_IN1_SFT, rt5670_if1_adc1_in1_src);
++
++static const struct snd_kcontrol_new rt5670_if1_adc1_in1_mux =
++	SOC_DAPM_ENUM("IF1 ADC1 IN1 source", rt5670_if1_adc1_in1_enum);
++
++/* MX-FA [11] */
++static const char *rt5670_if1_adc1_in2_src[] = {
++	"IF1_ADC1_IN1", "IF1_ADC4"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_if1_adc1_in2_enum, RT5670_DIG_MISC,
++	RT5670_IF1_ADC1_IN2_SFT, rt5670_if1_adc1_in2_src);
++
++static const struct snd_kcontrol_new rt5670_if1_adc1_in2_mux =
++	SOC_DAPM_ENUM("IF1 ADC1 IN2 source", rt5670_if1_adc1_in2_enum);
++
++/* MX-FA [10] */
++static const char *rt5670_if1_adc2_in1_src[] = {
++	"IF1_ADC2_IN", "IF1_ADC4"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_if1_adc2_in1_enum, RT5670_DIG_MISC,
++	RT5670_IF1_ADC2_IN1_SFT, rt5670_if1_adc2_in1_src);
++
++static const struct snd_kcontrol_new rt5670_if1_adc2_in1_mux =
++	SOC_DAPM_ENUM("IF1 ADC2 IN1 source", rt5670_if1_adc2_in1_enum);
++
++/* MX-9D [9:8] */
++static const char *rt5670_vad_adc_src[] = {
++	"Sto1 ADC L", "Mono ADC L", "Mono ADC R", "Sto2 ADC L"
++};
++
++static const SOC_ENUM_SINGLE_DECL(
++	rt5670_vad_adc_enum, RT5670_VAD_CTRL4,
++	RT5670_VAD_SEL_SFT, rt5670_vad_adc_src);
++
++static const struct snd_kcontrol_new rt5670_vad_adc_mux =
++	SOC_DAPM_ENUM("VAD ADC source", rt5670_vad_adc_enum);
++
++static int rt5670_adc_clk_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		rt5670_index_update_bits(codec,
++			RT5670_CHOP_DAC_ADC, 0x1000, 0x1000);
++		break;
++
++	case SND_SOC_DAPM_POST_PMD:
++		rt5670_index_update_bits(codec,
++			RT5670_CHOP_DAC_ADC, 0x1000, 0x0000);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_sto1_adcl_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
++			RT5670_L_MUTE, 0);
++		break;
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
++			RT5670_L_MUTE,
++			RT5670_L_MUTE);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_sto1_adcr_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
++			RT5670_R_MUTE, 0);
++		break;
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
++			RT5670_R_MUTE,
++			RT5670_R_MUTE);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_mono_adcl_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
++			RT5670_L_MUTE, 0);
++		break;
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
++			RT5670_L_MUTE,
++			RT5670_L_MUTE);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_mono_adcr_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
++			RT5670_R_MUTE, 0);
++		break;
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
++			RT5670_R_MUTE,
++			RT5670_R_MUTE);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++void hp_amp_power(struct snd_soc_codec *codec, int on)
++{
++	if(on) {
++		snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
++			RT5670_PM_HP_MASK, RT5670_PM_HP_HV);
++		snd_soc_update_bits(codec, RT5670_GEN_CTRL2,
++			0x0400, 0x0400);
++		/* headphone amp power on */
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++			RT5670_PWR_HA |	RT5670_PWR_FV1 |
++			RT5670_PWR_FV2,	RT5670_PWR_HA |
++			RT5670_PWR_FV1 | RT5670_PWR_FV2);
++		/* depop parameters */
++		snd_soc_write(codec, RT5670_DEPOP_M2, 0x3100);
++		snd_soc_write(codec, RT5670_DEPOP_M1, 0x8009);
++		rt5670_index_write(codec, RT5670_HP_DCC_INT1, 0x9f00);
++		pr_debug("hp_amp_time=%d\n",hp_amp_time);
++		mdelay(hp_amp_time);
++		snd_soc_write(codec, RT5670_DEPOP_M1, 0x8019);
++	}
++}
++
++static void rt5670_pmu_depop(struct snd_soc_codec *codec)
++{
++	/* headphone unmute sequence */
++	rt5670_index_write(codec, RT5670_MAMP_INT_REG2, 0xb400);
++	snd_soc_write(codec, RT5670_DEPOP_M3, 0x0772);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x805d);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x831d);
++	snd_soc_update_bits(codec, RT5670_GEN_CTRL2,
++				0x0300, 0x0300);
++	snd_soc_update_bits(codec, RT5670_HP_VOL,
++		RT5670_L_MUTE | RT5670_R_MUTE, 0);
++	pr_debug("pmu_depop_time=%d\n",pmu_depop_time);
++	msleep(pmu_depop_time);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x8019);
++}
++
++static void rt5670_pmd_depop(struct snd_soc_codec *codec)
++{
++	/* headphone mute sequence */
++	rt5670_index_write(codec, RT5670_MAMP_INT_REG2, 0xb400);
++	snd_soc_write(codec, RT5670_DEPOP_M3, 0x0772);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x803d);
++	mdelay(10);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x831d);
++	mdelay(10);
++	snd_soc_update_bits(codec, RT5670_HP_VOL,
++		RT5670_L_MUTE | RT5670_R_MUTE, RT5670_L_MUTE | RT5670_R_MUTE);
++	msleep(20);
++	snd_soc_update_bits(codec, RT5670_GEN_CTRL2, 0x0300, 0x0);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x8019);
++	snd_soc_write(codec, RT5670_DEPOP_M3, 0x0707);
++	rt5670_index_write(codec, RT5670_MAMP_INT_REG2, 0xfc00);
++	snd_soc_write(codec, RT5670_DEPOP_M1, 0x0004);
++	msleep(30);
++}
++
++static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
++			   struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		printk("%s SND_SOC_DAPM_POST_PMU\n",__func__);
++		hp_amp_power(codec, 1);
++		break;
++	case SND_SOC_DAPM_PRE_PMD:
++		printk("%s SND_SOC_DAPM_PRE_PMD\n",__func__);
++		hp_amp_power(codec, 0);
++		break;
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		rt5670_pmu_depop(codec);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		rt5670_pmd_depop(codec);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_lout_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
++			RT5670_PM_HP_MASK, RT5670_PM_HP_HV);
++		snd_soc_update_bits(codec, RT5670_LOUT1,
++			RT5670_L_MUTE | RT5670_R_MUTE, 0);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_LOUT1,
++			RT5670_L_MUTE | RT5670_R_MUTE,
++			RT5670_L_MUTE | RT5670_R_MUTE);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_set_dmic1_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_PRE_PMU:
++#ifdef NVIDIA_DALMORE
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_BST1 | RT5670_PWR_BST1_P,
++			RT5670_PWR_BST1 | RT5670_PWR_BST1_P);
++		snd_soc_update_bits(codec, RT5670_CJ_CTRL2, RT5670_CBJ_DET_MODE,
++			RT5670_CBJ_DET_MODE);
++#endif
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_GP2_PIN_MASK | RT5670_GP6_PIN_MASK |
++			RT5670_I2S2_PIN_MASK,
++			RT5670_GP2_PIN_DMIC1_SCL | RT5670_GP6_PIN_DMIC1_SDA |
++			RT5670_I2S2_PIN_GPIO);
++		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
++			RT5670_DMIC_1L_LH_MASK | RT5670_DMIC_1R_LH_MASK |
++			RT5670_DMIC_1_DP_MASK,
++			RT5670_DMIC_1L_LH_FALLING | RT5670_DMIC_1R_LH_RISING |
++			RT5670_DMIC_1_DP_IN2P);
++		break;
++	case SND_SOC_DAPM_POST_PMD:
++#ifdef NVIDIA_DALMORE
++		snd_soc_update_bits(codec, RT5670_CJ_CTRL2, RT5670_CBJ_DET_MODE,
++			0);
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_BST1 | RT5670_PWR_BST1_P, 0);
++#endif
++		break;
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_set_dmic2_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_PRE_PMU:
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_GP2_PIN_MASK | RT5670_GP4_PIN_MASK,
++			RT5670_GP2_PIN_DMIC1_SCL | RT5670_GP4_PIN_DMIC2_SDA);
++		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
++			RT5670_DMIC_2L_LH_MASK | RT5670_DMIC_2R_LH_MASK |
++			RT5670_DMIC_2_DP_MASK,
++			RT5670_DMIC_2L_LH_FALLING | RT5670_DMIC_2R_LH_RISING |
++			RT5670_DMIC_2_DP_IN1N);
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_set_dmic3_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_PRE_PMU:
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_GP2_PIN_MASK | RT5670_GP4_PIN_MASK,
++			RT5670_GP2_PIN_DMIC1_SCL | RT5670_GP4_PIN_DMIC2_SDA);
++		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
++			RT5670_DMIC_2L_LH_MASK | RT5670_DMIC_2R_LH_MASK |
++			RT5670_DMIC_2_DP_MASK,
++			RT5670_DMIC_2L_LH_FALLING | RT5670_DMIC_2R_LH_RISING |
++			RT5670_DMIC_2_DP_IN1N);
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		printk("%s SND_SOC_DAPM_POST_PMU\n",__func__);
++		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
++		snd_soc_update_bits(codec,RT5670_CHARGE_PUMP,
++			RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
++			RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
++
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_BST1_P, RT5670_PWR_BST1_P);
++		if(rt5670->combo_jack_en) {
++			snd_soc_update_bits(codec, RT5670_PWR_VOL,
++				RT5670_PWR_MIC_DET, RT5670_PWR_MIC_DET);
++		}
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		printk("%s SND_SOC_DAPM_POST_PMD\n",__func__);
++		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_BST1_P, 0);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		printk("%s SND_SOC_DAPM_POST_PMU\n",__func__);
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_BST2_P, RT5670_PWR_BST2_P);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		printk("%s SND_SOC_DAPM_POST_PMD\n",__func__);
++		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_BST2_P, 0);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_pdm1_l_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM1_L, 0);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM1_L, RT5670_M_PDM1_L);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_pdm1_r_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM1_R, 0);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM1_R, RT5670_M_PDM1_R);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_pdm2_l_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM2_L, 0);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM2_L, RT5670_M_PDM2_L);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_pdm2_r_event(struct snd_soc_dapm_widget *w,
++	struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM2_R, 0);
++		break;
++
++	case SND_SOC_DAPM_PRE_PMD:
++		snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
++			RT5670_M_PDM2_R, RT5670_M_PDM2_R);
++		break;
++
++	default:
++		return 0;
++	}
++
++	return 0;
++}
++
++static int rt5670_asrc_event(struct snd_soc_dapm_widget *w,
++        struct snd_kcontrol *kcontrol, int event)
++{
++
++        pr_debug("%s\n",__func__);
++        switch (event) {
++		case SND_SOC_DAPM_POST_PMU:
++			snd_soc_write(w->codec, RT5670_ASRC_1, 0xffff);
++			snd_soc_write(w->codec, RT5670_ASRC_2, 0x1221);
++			snd_soc_write(w->codec, RT5670_ASRC_3, 0x0022);
++			break;
++		case SND_SOC_DAPM_PRE_PMD:
++			snd_soc_write(w->codec, RT5670_ASRC_1, 0);
++			snd_soc_write(w->codec, RT5670_ASRC_2, 0);
++			snd_soc_write(w->codec, RT5670_ASRC_3, 0);
++		default:
++			return 0;
++		}
++        return 0;
++}
++
++static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = {
++	SND_SOC_DAPM_SUPPLY("ASRC enable", SND_SOC_NOPM, 0, 0,
++		rt5670_asrc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
++	SND_SOC_DAPM_SUPPLY("PLL1", RT5670_PWR_ANLG2,
++		RT5670_PWR_PLL_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("I2S DSP", RT5670_PWR_DIG2,
++		RT5670_PWR_I2S_DSP_BIT, 0, NULL, 0),
++#ifdef JD1_FUNC
++	SND_SOC_DAPM_SUPPLY("JD Power", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5670_PWR_VOL,
++		RT5670_PWR_MIC_DET_BIT, 0, NULL, 0),
++#else
++	SND_SOC_DAPM_SUPPLY("JD Power", RT5670_PWR_ANLG2,
++		RT5670_PWR_JD1_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("Mic Det Power", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++#endif
++
++	/* Input Side */
++	/* micbias */
++	SND_SOC_DAPM_MICBIAS("micbias1", RT5670_PWR_ANLG2,
++			RT5670_PWR_MB1_BIT, 0),
++	SND_SOC_DAPM_MICBIAS("micbias2", RT5670_PWR_ANLG2,
++			RT5670_PWR_MB2_BIT, 0),
++
++	/* Input Lines */
++	SND_SOC_DAPM_INPUT("DMIC L1"),
++	SND_SOC_DAPM_INPUT("DMIC R1"),
++	SND_SOC_DAPM_INPUT("DMIC L2"),
++	SND_SOC_DAPM_INPUT("DMIC R2"),
++	SND_SOC_DAPM_INPUT("DMIC L3"),
++	SND_SOC_DAPM_INPUT("DMIC R3"),
++
++	SND_SOC_DAPM_INPUT("IN1P"),
++	SND_SOC_DAPM_INPUT("IN1N"),
++	SND_SOC_DAPM_INPUT("IN2P"),
++	SND_SOC_DAPM_INPUT("IN2N"),
++
++	SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("DMIC3", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
++		set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
++	SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5670_DMIC_CTRL1,
++		RT5670_DMIC_1_EN_SFT, 0, rt5670_set_dmic1_event,
++		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5670_DMIC_CTRL1,
++		RT5670_DMIC_2_EN_SFT, 0, rt5670_set_dmic2_event,
++		SND_SOC_DAPM_PRE_PMU),
++	SND_SOC_DAPM_SUPPLY("DMIC3 Power", RT5670_DMIC_CTRL1,
++		RT5670_DMIC_3_EN_SFT, 0, rt5670_set_dmic3_event,
++		SND_SOC_DAPM_PRE_PMU),
++	/* Boost */
++	SND_SOC_DAPM_PGA_E("BST1", RT5670_PWR_ANLG2,
++		RT5670_PWR_BST1_BIT, 0, NULL, 0, rt5670_bst1_event,
++		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_PGA_E("BST2", RT5670_PWR_ANLG2,
++		RT5670_PWR_BST2_BIT, 0, NULL, 0, rt5670_bst2_event,
++		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
++	/* Input Volume */
++	SND_SOC_DAPM_PGA("INL VOL", RT5670_PWR_VOL,
++		RT5670_PWR_IN_L_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("INR VOL", RT5670_PWR_VOL,
++		RT5670_PWR_IN_R_BIT, 0, NULL, 0),
++	/* IN Mux */
++	SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt5670_inl_mux),
++	SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt5670_inr_mux),
++	/* REC Mixer */
++	SND_SOC_DAPM_MIXER("RECMIXL", RT5670_PWR_MIXER, RT5670_PWR_RM_L_BIT, 0,
++			rt5670_rec_l_mix, ARRAY_SIZE(rt5670_rec_l_mix)),
++	SND_SOC_DAPM_MIXER("RECMIXR", RT5670_PWR_MIXER, RT5670_PWR_RM_R_BIT, 0,
++			rt5670_rec_r_mix, ARRAY_SIZE(rt5670_rec_r_mix)),
++	/* ADCs */
++	SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM,
++		0, 0),
++	SND_SOC_DAPM_ADC("ADC 2", NULL, SND_SOC_NOPM,
++		0, 0),
++
++	SND_SOC_DAPM_PGA("ADC 1_2", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	SND_SOC_DAPM_SUPPLY("ADC 1 power",RT5670_PWR_DIG1,
++			RT5670_PWR_ADC_L_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("ADC 2 power",RT5670_PWR_DIG1,
++			RT5670_PWR_ADC_R_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("ADC clock",SND_SOC_NOPM, 0, 0,
++		rt5670_adc_clk_event, SND_SOC_DAPM_POST_PMD |
++		SND_SOC_DAPM_POST_PMU),
++	/* ADC Mux */
++	SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto1_dmic_mux),
++	SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto_adc_l2_mux),
++	SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto_adc_r2_mux),
++	SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto_adc_l1_mux),
++	SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto_adc_r1_mux),
++	SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto2_dmic_mux),
++	SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto2_adc_l2_mux),
++	SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto2_adc_r2_mux),
++	SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto2_adc_l1_mux),
++	SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto2_adc_r1_mux),
++	SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_sto2_adc_lr_mux),
++	SND_SOC_DAPM_MUX("Mono ADC L Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_adc_l_mux),
++	SND_SOC_DAPM_MUX("Mono ADC R Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_adc_r_mux),
++	SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_dmic_l_mux),
++	SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_dmic_r_mux),
++	SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_adc_l2_mux),
++	SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_adc_l1_mux),
++	SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_adc_r1_mux),
++	SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_mono_adc_r2_mux),
++	/* ADC Mixer */
++	SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_ADC_S1F_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY_S("adc stereo2 filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_ADC_S2F_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_sto1_adc_l_mix, ARRAY_SIZE(rt5670_sto1_adc_l_mix),
++		rt5670_sto1_adcl_event, SND_SOC_DAPM_PRE_PMD |
++		SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_sto1_adc_r_mix, ARRAY_SIZE(rt5670_sto1_adc_r_mix),
++		rt5670_sto1_adcr_event, SND_SOC_DAPM_PRE_PMD |
++		SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_sto2_adc_l_mix, ARRAY_SIZE(rt5670_sto2_adc_l_mix)),
++	SND_SOC_DAPM_MIXER("Sto2 ADC MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_sto2_adc_r_mix, ARRAY_SIZE(rt5670_sto2_adc_r_mix)),
++	SND_SOC_DAPM_SUPPLY_S("adc mono left filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_ADC_MF_L_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_mono_adc_l_mix, ARRAY_SIZE(rt5670_mono_adc_l_mix),
++		rt5670_mono_adcl_event, SND_SOC_DAPM_PRE_PMD |
++		SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_SUPPLY_S("adc mono right filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_ADC_MF_R_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_mono_adc_r_mix, ARRAY_SIZE(rt5670_mono_adc_r_mix),
++		rt5670_mono_adcr_event, SND_SOC_DAPM_PRE_PMD |
++		SND_SOC_DAPM_POST_PMU),
++
++	/* ADC PGA */
++	SND_SOC_DAPM_PGA("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Stereo2 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Stereo2 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Stereo2 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("VAD_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	/* DSP */
++	SND_SOC_DAPM_PGA("TxDP_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("TxDP_ADC_L", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("TxDP_ADC_R", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("TxDC_DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	SND_SOC_DAPM_PGA("8CH TDM Data", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	SND_SOC_DAPM_MUX("DSP UL Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_dsp_ul_mux),
++	SND_SOC_DAPM_MUX("DSP DL Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_dsp_dl_mux),
++
++	SND_SOC_DAPM_MUX("RxDP Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_rxdp_mux),
++
++	/* IF2 Mux */
++	SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_if2_adc_in_mux),
++
++	/* Digital Interface */
++	SND_SOC_DAPM_SUPPLY("I2S1", RT5670_PWR_DIG1,
++		RT5670_PWR_I2S1_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("I2S2", RT5670_PWR_DIG1,
++		RT5670_PWR_I2S2_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	/* Digital Interface Select */
++	SND_SOC_DAPM_MUX("IF1 ADC1 IN1 Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_if1_adc1_in1_mux),
++	SND_SOC_DAPM_MUX("IF1 ADC1 IN2 Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_if1_adc1_in2_mux),
++	SND_SOC_DAPM_MUX("IF1 ADC2 IN Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_if1_adc2_in_mux),
++	SND_SOC_DAPM_MUX("IF1 ADC2 IN1 Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_if1_adc2_in1_mux),
++	SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0,
++			&rt5670_vad_adc_mux),
++
++	/* Audio Interface */
++	SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
++
++	/* Audio DSP */
++	SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	/* Output Side */
++	/* DAC mixer before sound effect  */
++	SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_dac_l_mix, ARRAY_SIZE(rt5670_dac_l_mix)),
++	SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_dac_r_mix, ARRAY_SIZE(rt5670_dac_r_mix)),
++	SND_SOC_DAPM_PGA("DAC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++	/* DAC2 channel Mux */
++	SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_dac_l2_mux),
++	SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_dac_r2_mux),
++	SND_SOC_DAPM_PGA("DAC L2 Volume", RT5670_PWR_DIG1,
++			RT5670_PWR_DAC_L2_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("DAC R2 Volume", RT5670_PWR_DIG1,
++			RT5670_PWR_DAC_R2_BIT, 0, NULL, 0),
++
++	SND_SOC_DAPM_MUX("DAC1 L Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_dac1l_mux),
++	SND_SOC_DAPM_MUX("DAC1 R Mux", SND_SOC_NOPM, 0, 0,
++				&rt5670_dac1r_mux),
++
++	/* DAC Mixer */
++	SND_SOC_DAPM_SUPPLY_S("dac stereo1 filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_DAC_S1F_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY_S("dac mono left filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_DAC_MF_L_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY_S("dac mono right filter", 1, RT5670_PWR_DIG2,
++		RT5670_PWR_DAC_MF_R_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_sto_dac_l_mix, ARRAY_SIZE(rt5670_sto_dac_l_mix)),
++	SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_sto_dac_r_mix, ARRAY_SIZE(rt5670_sto_dac_r_mix)),
++	SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_mono_dac_l_mix, ARRAY_SIZE(rt5670_mono_dac_l_mix)),
++	SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_mono_dac_r_mix, ARRAY_SIZE(rt5670_mono_dac_r_mix)),
++	SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
++		rt5670_dig_l_mix, ARRAY_SIZE(rt5670_dig_l_mix)),
++	SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
++		rt5670_dig_r_mix, ARRAY_SIZE(rt5670_dig_r_mix)),
++
++	/* DACs */
++	SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5670_PWR_DIG1,
++		RT5670_PWR_DAC_L1_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5670_PWR_DIG1,
++		RT5670_PWR_DAC_R1_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_DAC("DAC L2", NULL, RT5670_PWR_DIG1,
++			RT5670_PWR_DAC_L2_BIT, 0),
++
++	SND_SOC_DAPM_DAC("DAC R2", NULL, RT5670_PWR_DIG1,
++			RT5670_PWR_DAC_R2_BIT, 0),
++	/* OUT Mixer */
++
++	SND_SOC_DAPM_MIXER("OUT MIXL", RT5670_PWR_MIXER, RT5670_PWR_OM_L_BIT,
++		0, rt5670_out_l_mix, ARRAY_SIZE(rt5670_out_l_mix)),
++	SND_SOC_DAPM_MIXER("OUT MIXR", RT5670_PWR_MIXER, RT5670_PWR_OM_R_BIT,
++		0, rt5670_out_r_mix, ARRAY_SIZE(rt5670_out_r_mix)),
++	/* Ouput Volume */
++	SND_SOC_DAPM_MIXER("HPOVOL MIXL", RT5670_PWR_VOL, RT5670_PWR_HV_L_BIT,
++		0, rt5670_hpvoll_mix, ARRAY_SIZE(rt5670_hpvoll_mix)),
++	SND_SOC_DAPM_MIXER("HPOVOL MIXR", RT5670_PWR_VOL, RT5670_PWR_HV_R_BIT,
++		0, rt5670_hpvolr_mix, ARRAY_SIZE(rt5670_hpvolr_mix)),
++	SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,
++		0, 0, NULL, 0),
++
++	/* HPO/LOUT/Mono Mixer */
++	SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
++		rt5670_hpo_mix, ARRAY_SIZE(rt5670_hpo_mix)),
++	SND_SOC_DAPM_MIXER("LOUT MIX", RT5670_PWR_ANLG1, RT5670_PWR_LM_BIT,
++		0, rt5670_lout_mix, ARRAY_SIZE(rt5670_lout_mix)),
++	SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
++		0, 0, rt5670_hp_power_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
++	SND_SOC_DAPM_SUPPLY("HP L Amp", RT5670_PWR_ANLG1,
++		RT5670_PWR_HP_L_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("HP R Amp", RT5670_PWR_ANLG1,
++		RT5670_PWR_HP_R_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
++		rt5670_hp_event, SND_SOC_DAPM_PRE_PMD |
++		SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_PGA_S("LOUT Amp", 1, SND_SOC_NOPM, 0, 0,
++		rt5670_lout_event, SND_SOC_DAPM_PRE_PMD |
++		SND_SOC_DAPM_POST_PMU),
++#ifdef RT5672
++	SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
++#endif
++
++	/* PDM */
++	SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5670_PWR_DIG2,
++		RT5670_PWR_PDM1_BIT, 0, NULL, 0),
++	SND_SOC_DAPM_SUPPLY("PDM2 Power", RT5670_PWR_DIG2,
++		RT5670_PWR_PDM2_BIT, 0, NULL, 0),
++
++	SND_SOC_DAPM_MUX_E("PDM1 L Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm1_l_mux,
++		rt5670_pdm1_l_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_MUX_E("PDM1 R Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm1_r_mux,
++		rt5670_pdm1_r_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_MUX_E("PDM2 L Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm2_l_mux,
++		rt5670_pdm2_l_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
++	SND_SOC_DAPM_MUX_E("PDM2 R Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm2_r_mux,
++		rt5670_pdm2_r_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
++
++	/* Output Lines */
++	SND_SOC_DAPM_OUTPUT("HPOL"),
++	SND_SOC_DAPM_OUTPUT("HPOR"),
++	SND_SOC_DAPM_OUTPUT("LOUTL"),
++	SND_SOC_DAPM_OUTPUT("LOUTR"),
++	SND_SOC_DAPM_OUTPUT("PDM2L"),
++	SND_SOC_DAPM_OUTPUT("PDM2R"),
++#ifdef RT5672
++	SND_SOC_DAPM_OUTPUT("SPOL"),
++	SND_SOC_DAPM_OUTPUT("SPOR"),
++#else
++	SND_SOC_DAPM_OUTPUT("PDM1L"),
++	SND_SOC_DAPM_OUTPUT("PDM1R"),
++#endif
++};
++
++static const struct snd_soc_dapm_route rt5670_dapm_routes[] = {
++#ifdef USE_ASRC
++	{"I2S1", NULL, "ASRC enable"},
++	{"I2S2", NULL, "ASRC enable"},
++#endif
++//	{ "micbias1", NULL, "DAC L1 Power" },
++//	{ "micbias1", NULL, "DAC R1 Power" },
++
++	{ "DMIC1", NULL, "DMIC L1" },
++	{ "DMIC1", NULL, "DMIC R1" },
++	{ "DMIC2", NULL, "DMIC L2" },
++	{ "DMIC2", NULL, "DMIC R2" },
++	{ "DMIC3", NULL, "DMIC L3" },
++	{ "DMIC3", NULL, "DMIC R3" },
++
++	{ "BST1", NULL, "IN1P" },
++	{ "BST1", NULL, "IN1N" },
++//	{ "BST1", NULL, "JD Power" },
++//	{ "BST1", NULL, "Mic Det Power" },
++	{ "BST2", NULL, "IN2P" },
++	{ "BST2", NULL, "IN2N" },
++
++	{ "INL VOL", NULL, "IN2P" },
++	{ "INR VOL", NULL, "IN2N" },
++
++	{ "RECMIXL", "INL Switch", "INL VOL" },
++	{ "RECMIXL", "BST2 Switch", "BST2" },
++	{ "RECMIXL", "BST1 Switch", "BST1" },
++
++	{ "RECMIXR", "INR Switch", "INR VOL" },
++	{ "RECMIXR", "BST2 Switch", "BST2" },
++	{ "RECMIXR", "BST1 Switch", "BST1" },
++
++	{ "ADC 1", NULL, "RECMIXL" },
++	{ "ADC 1", NULL, "ADC 1 power" },
++	{ "ADC 1", NULL, "ADC clock" },
++	{ "ADC 2", NULL, "RECMIXR" },
++	{ "ADC 2", NULL, "ADC 2 power" },
++	{ "ADC 2", NULL, "ADC clock" },
++
++	{ "DMIC L1", NULL, "DMIC CLK" },
++	{ "DMIC L1", NULL, "DMIC1 Power" },
++	{ "DMIC R1", NULL, "DMIC CLK" },
++	{ "DMIC R1", NULL, "DMIC1 Power" },
++	{ "DMIC L2", NULL, "DMIC CLK" },
++	{ "DMIC L2", NULL, "DMIC2 Power" },
++	{ "DMIC R2", NULL, "DMIC CLK" },
++	{ "DMIC R2", NULL, "DMIC2 Power" },
++	{ "DMIC L3", NULL, "DMIC CLK" },
++	{ "DMIC L3", NULL, "DMIC3 Power" },
++	{ "DMIC R3", NULL, "DMIC CLK" },
++	{ "DMIC R3", NULL, "DMIC3 Power" },
++
++	{ "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
++	{ "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
++	{ "Stereo1 DMIC Mux", "DMIC3", "DMIC3" },
++
++	{ "Stereo2 DMIC Mux", "DMIC1", "DMIC1" },
++	{ "Stereo2 DMIC Mux", "DMIC2", "DMIC2" },
++	{ "Stereo2 DMIC Mux", "DMIC3", "DMIC3" },
++
++	{ "Mono DMIC L Mux", "DMIC1", "DMIC L1" },
++	{ "Mono DMIC L Mux", "DMIC2", "DMIC L2" },
++	{ "Mono DMIC L Mux", "DMIC3", "DMIC L3" },
++
++	{ "Mono DMIC R Mux", "DMIC1", "DMIC R1" },
++	{ "Mono DMIC R Mux", "DMIC2", "DMIC R2" },
++	{ "Mono DMIC R Mux", "DMIC3", "DMIC R3" },
++
++	{ "ADC 1_2", NULL, "ADC 1" },
++	{ "ADC 1_2", NULL, "ADC 2" },
++
++	{ "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" },
++	{ "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
++	{ "Stereo1 ADC L1 Mux", "ADC", "ADC 1_2" },
++	{ "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
++
++	{ "Stereo1 ADC R1 Mux", "ADC", "ADC 1_2" },
++	{ "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
++	{ "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC Mux" },
++	{ "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
++
++	{ "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
++	{ "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
++	{ "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
++	{ "Mono ADC L1 Mux", "ADC1",  "ADC 1" },
++
++	{ "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
++	{ "Mono ADC R1 Mux", "ADC2", "ADC 2" },
++	{ "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
++	{ "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
++
++	{ "Sto1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" },
++	{ "Sto1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" },
++	{ "Sto1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" },
++	{ "Sto1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" },
++
++	{ "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
++	{ "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
++	{ "adc stereo1 filter", NULL, "PLL1", check_sysclk1_source },
++
++	{ "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
++	{ "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
++	{ "adc stereo1 filter", NULL, "PLL1", check_sysclk1_source },
++
++	{ "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
++	{ "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
++	{ "Mono ADC MIXL", NULL, "adc mono left filter" },
++	{ "adc mono left filter", NULL, "PLL1", check_sysclk1_source },
++
++	{ "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
++	{ "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
++	{ "Mono ADC MIXR", NULL, "adc mono right filter" },
++	{ "adc mono right filter", NULL, "PLL1", check_sysclk1_source },
++
++	{ "Stereo2 ADC L2 Mux", "DMIC", "Stereo2 DMIC Mux" },
++	{ "Stereo2 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
++	{ "Stereo2 ADC L1 Mux", "ADC", "ADC 1_2" },
++	{ "Stereo2 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
++
++	{ "Stereo2 ADC R1 Mux", "ADC", "ADC 1_2" },
++	{ "Stereo2 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
++	{ "Stereo2 ADC R2 Mux", "DMIC", "Stereo2 DMIC Mux" },
++	{ "Stereo2 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
++
++	{ "Sto2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux" },
++	{ "Sto2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux" },
++	{ "Sto2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux" },
++	{ "Sto2 ADC MIXR", "ADC2 Switch", "Stereo2 ADC R2 Mux" },
++
++	{ "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXL" },
++	{ "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXR" },
++
++	{ "Stereo2 ADC LR Mux", "L", "Sto2 ADC MIXL" },
++	{ "Stereo2 ADC LR Mux", "LR", "Sto2 ADC LR MIX" },
++
++	{ "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" },
++	{ "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" },
++	{ "adc stereo2 filter", NULL, "PLL1", check_sysclk1_source },
++
++	{ "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
++	{ "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" },
++	{ "adc stereo2 filter", NULL, "PLL1", check_sysclk1_source },
++
++	{ "VAD ADC Mux", "Sto1 ADC L", "Stereo1 ADC MIXL" },
++	{ "VAD ADC Mux", "Mono ADC L", "Mono ADC MIXL" },
++	{ "VAD ADC Mux", "Mono ADC R", "Mono ADC MIXR" },
++	{ "VAD ADC Mux", "Sto2 ADC L", "Sto2 ADC MIXL" },
++
++	{ "VAD_ADC", NULL, "VAD ADC Mux" },
++
++	{ "IF_ADC1", NULL, "Stereo1 ADC MIXL" },
++	{ "IF_ADC1", NULL, "Stereo1 ADC MIXR" },
++	{ "IF_ADC2", NULL, "Mono ADC MIXL" },
++	{ "IF_ADC2", NULL, "Mono ADC MIXR" },
++	{ "IF_ADC3", NULL, "Stereo2 ADC MIXL" },
++	{ "IF_ADC3", NULL, "Stereo2 ADC MIXR" },
++
++	{ "IF1 ADC1 IN1 Mux", "IF_ADC1", "IF_ADC1" },
++	{ "IF1 ADC1 IN1 Mux", "IF1_ADC3", "IF1_ADC3" },
++
++	{ "IF1 ADC1 IN2 Mux", "IF1_ADC1_IN1", "IF1 ADC1 IN1 Mux" },
++	{ "IF1 ADC1 IN2 Mux", "IF1_ADC4", "IF1_ADC4" },
++
++	{ "IF1 ADC2 IN Mux", "IF_ADC2", "IF_ADC2" },
++	{ "IF1 ADC2 IN Mux", "VAD_ADC", "VAD_ADC" },
++
++	{ "IF1 ADC2 IN1 Mux", "IF1_ADC2_IN", "IF1 ADC2 IN Mux" },
++	{ "IF1 ADC2 IN1 Mux", "IF1_ADC4", "IF1_ADC4" },
++
++	{ "IF1_ADC1" , NULL, "IF1 ADC1 IN2 Mux" },
++	{ "IF1_ADC2" , NULL, "IF1 ADC2 IN1 Mux" },
++
++	{ "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL" },
++	{ "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" },
++	{ "Stereo2 ADC MIX", NULL, "Sto2 ADC MIXL" },
++	{ "Stereo2 ADC MIX", NULL, "Sto2 ADC MIXR" },
++
++	{ "RxDP Mux", "IF2 DAC", "IF2 DAC" },
++	{ "RxDP Mux", "IF1 DAC", "IF1 DAC2" },
++	{ "RxDP Mux", "STO1 ADC Mixer", "Stereo1 ADC MIX" },
++	{ "RxDP Mux", "STO2 ADC Mixer", "Stereo2 ADC MIX" },
++	{ "RxDP Mux", "Mono ADC Mixer L", "Mono ADC MIXL" },
++	{ "RxDP Mux", "Mono ADC Mixer R", "Mono ADC MIXR" },
++	{ "RxDP Mux", "DAC1", "DAC MIX" },
++
++	{ "8CH TDM Data", NULL, "Stereo1 ADC MIXL" },
++	{ "8CH TDM Data", NULL, "Stereo1 ADC MIXR" },
++	{ "8CH TDM Data", NULL, "Mono ADC MIXL" },
++	{ "8CH TDM Data", NULL, "Mono ADC MIXR" },
++	{ "8CH TDM Data", NULL, "Sto2 ADC MIXL" },
++	{ "8CH TDM Data", NULL, "Sto2 ADC MIXR" },
++	{ "8CH TDM Data", NULL, "IF2 DAC L" },
++	{ "8CH TDM Data", NULL, "IF2 DAC R" },
++
++	{ "DSP UL Mux", "Bypass", "8CH TDM Data" },
++	{ "DSP UL Mux", NULL, "I2S DSP" },
++	{ "DSP DL Mux", "Bypass", "RxDP Mux" },
++	{ "DSP DL Mux", NULL, "I2S DSP" },
++
++	{ "TxDP_ADC_L", NULL, "DSP UL Mux" },
++	{ "TxDP_ADC_R", NULL, "DSP UL Mux" },
++	{ "TxDC_DAC", NULL, "DSP DL Mux" },
++
++	{ "TxDP_ADC", NULL, "TxDP_ADC_L" },
++	{ "TxDP_ADC", NULL, "TxDP_ADC_R" },
++
++	{ "IF1 ADC", NULL, "I2S1" },
++	{ "IF1 ADC", NULL, "IF1_ADC1" },
++#ifdef USE_TDM
++	{ "IF1 ADC", NULL, "IF1_ADC2" },
++	{ "IF1 ADC", NULL, "IF_ADC3" },
++	{ "IF1 ADC", NULL, "TxDP_ADC" },
++#endif
++
++	{ "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
++	{ "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
++	{ "IF2 ADC Mux", "IF_ADC3", "IF_ADC3" },
++	{ "IF2 ADC Mux", "TxDC_DAC", "TxDC_DAC" },
++	{ "IF2 ADC Mux", "TxDP_ADC", "TxDP_ADC" },
++	{ "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" },
++
++	{ "IF2 ADC L", NULL, "IF2 ADC Mux" },
++	{ "IF2 ADC R", NULL, "IF2 ADC Mux" },
++
++	{ "IF2 ADC", NULL, "I2S2" },
++	{ "IF2 ADC", NULL, "IF2 ADC L" },
++	{ "IF2 ADC", NULL, "IF2 ADC R" },
++
++	{ "AIF1TX", NULL, "IF1 ADC" },
++	{ "AIF2TX", NULL, "IF2 ADC" },
++
++	{ "IF1 DAC1", NULL, "AIF1RX" },
++#ifdef USE_TDM
++	{ "IF1 DAC2", NULL, "AIF1RX" },
++#endif
++	{ "IF2 DAC", NULL, "AIF2RX" },
++
++	{ "IF1 DAC1", NULL, "I2S1" },
++	{ "IF1 DAC2", NULL, "I2S1" },
++	{ "IF2 DAC", NULL, "I2S2" },
++
++	{ "IF1 DAC2 L", NULL, "IF1 DAC2" },
++	{ "IF1 DAC2 R", NULL, "IF1 DAC2" },
++	{ "IF1 DAC1 L", NULL, "IF1 DAC1" },
++	{ "IF1 DAC1 R", NULL, "IF1 DAC1" },
++	{ "IF2 DAC L", NULL, "IF2 DAC" },
++	{ "IF2 DAC R", NULL, "IF2 DAC" },
++
++	{ "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" },
++	{ "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" },
++
++	{ "DAC1 R Mux", "IF1 DAC", "IF1 DAC1 R" },
++	{ "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" },
++
++	{ "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
++	{ "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" },
++	{ "DAC1 MIXL", NULL, "dac stereo1 filter" },
++	{ "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" },
++	{ "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" },
++	{ "DAC1 MIXR", NULL, "dac stereo1 filter" },
++
++	{ "DAC MIX", NULL, "DAC1 MIXL" },
++	{ "DAC MIX", NULL, "DAC1 MIXR" },
++
++	{ "Audio DSP", NULL, "DAC1 MIXL" },
++	{ "Audio DSP", NULL, "DAC1 MIXR" },
++
++	{ "DAC L2 Mux", "IF1 DAC", "IF1 DAC1 L" },
++	{ "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
++	{ "DAC L2 Mux", "TxDC DAC", "TxDC_DAC" },
++	{ "DAC L2 Mux", "VAD_ADC", "VAD_ADC" },
++	{ "DAC L2 Volume", NULL, "DAC L2 Mux" },
++	{ "DAC L2 Volume", NULL, "dac mono left filter" },
++
++	{ "DAC R2 Mux", "IF1 DAC", "IF1 DAC1 R" },
++	{ "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
++	{ "DAC R2 Mux", "TxDC DAC", "TxDC_DAC" },
++	{ "DAC R2 Mux", "TxDP ADC", "TxDP_ADC" },
++	{ "DAC R2 Volume", NULL, "DAC R2 Mux" },
++	{ "DAC R2 Volume", NULL, "dac mono right filter" },
++
++	{ "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
++	{ "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
++	{ "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
++	{ "Stereo DAC MIXL", NULL, "dac stereo1 filter" },
++	{ "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
++	{ "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
++	{ "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
++	{ "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
++
++	{ "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
++	{ "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
++	{ "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
++	{ "Mono DAC MIXL", NULL, "dac mono left filter" },
++	{ "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
++	{ "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
++	{ "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
++	{ "Mono DAC MIXR", NULL, "dac mono right filter" },
++
++	{ "DAC MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
++	{ "DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
++	{ "DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
++	{ "DAC MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
++	{ "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
++	{ "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
++
++	{ "DAC L1", NULL, "DAC L1 Power" },
++	{ "DAC L1", NULL, "Stereo DAC MIXL" },
++	{ "DAC L1", NULL, "PLL1", check_sysclk1_source },
++	{ "DAC R1", NULL, "DAC R1 Power" },
++	{ "DAC R1", NULL, "Stereo DAC MIXR" },
++	{ "DAC R1", NULL, "PLL1", check_sysclk1_source },
++	{ "DAC L2", NULL, "Mono DAC MIXL" },
++	{ "DAC L2", NULL, "PLL1", check_sysclk1_source },
++	{ "DAC R2", NULL, "Mono DAC MIXR" },
++	{ "DAC R2", NULL, "PLL1", check_sysclk1_source },
++
++	{ "OUT MIXL", "BST1 Switch", "BST1" },
++	{ "OUT MIXL", "INL Switch", "INL VOL" },
++	{ "OUT MIXL", "DAC L2 Switch", "DAC L2" },
++	{ "OUT MIXL", "DAC L1 Switch", "DAC L1" },
++
++	{ "OUT MIXR", "BST2 Switch", "BST2" },
++	{ "OUT MIXR", "INR Switch", "INR VOL" },
++	{ "OUT MIXR", "DAC R2 Switch", "DAC R2" },
++	{ "OUT MIXR", "DAC R1 Switch", "DAC R1" },
++
++	{ "HPOVOL MIXL", "DAC1 Switch", "DAC L1" },
++	{ "HPOVOL MIXL", "INL Switch", "INL VOL" },
++	{ "HPOVOL MIXR", "DAC1 Switch", "DAC R1" },
++	{ "HPOVOL MIXR", "INR Switch", "INR VOL" },
++
++	{ "DAC 2", NULL, "DAC L2" },
++	{ "DAC 2", NULL, "DAC R2" },
++	{ "DAC 1", NULL, "DAC L1" },
++	{ "DAC 1", NULL, "DAC R1" },
++	{ "HPOVOL", NULL, "HPOVOL MIXL" },
++	{ "HPOVOL", NULL, "HPOVOL MIXR" },
++	{ "HPO MIX", "DAC1 Switch", "DAC 1" },
++	{ "HPO MIX", "HPVOL Switch", "HPOVOL" },
++
++	{ "LOUT MIX", "DAC L1 Switch", "DAC L1" },
++	{ "LOUT MIX", "DAC R1 Switch", "DAC R1" },
++	{ "LOUT MIX", "OUTMIX L Switch", "OUT MIXL" },
++	{ "LOUT MIX", "OUTMIX R Switch", "OUT MIXR" },
++
++	{ "PDM1 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
++	{ "PDM1 L Mux", "Mono DAC", "Mono DAC MIXL" },
++	{ "PDM1 L Mux", NULL, "PDM1 Power" },
++	{ "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
++	{ "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" },
++	{ "PDM1 R Mux", NULL, "PDM1 Power" },
++	{ "PDM2 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
++	{ "PDM2 L Mux", "Mono DAC", "Mono DAC MIXL" },
++	{ "PDM2 L Mux", NULL, "PDM2 Power" },
++	{ "PDM2 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
++	{ "PDM2 R Mux", "Mono DAC", "Mono DAC MIXR" },
++	{ "PDM2 R Mux", NULL, "PDM2 Power" },
++
++	{ "HP Amp", NULL, "HPO MIX" },
++	{ "HP Amp", NULL, "JD Power" },
++	{ "HP Amp", NULL, "Mic Det Power" },
++	{ "HPOL", NULL, "HP Amp" },
++	{ "HPOL", NULL, "HP L Amp" },
++	{ "HPOL", NULL, "Improve HP Amp Drv" },
++	{ "HPOR", NULL, "HP Amp" },
++	{ "HPOR", NULL, "HP R Amp" },
++	{ "HPOR", NULL, "Improve HP Amp Drv" },
++
++	{ "LOUT Amp", NULL, "LOUT MIX" },
++	{ "LOUTL", NULL, "LOUT Amp" },
++	{ "LOUTR", NULL, "LOUT Amp" },
++#ifndef RT5672
++	{ "PDM1L", NULL, "PDM1 L Mux" },
++	{ "PDM1R", NULL, "PDM1 R Mux" },
++	{ "PDM2L", NULL, "PDM2 L Mux" },
++	{ "PDM2R", NULL, "PDM2 R Mux" },
++#else
++	{ "SPO Amp", NULL, "PDM1 L Mux" },
++	{ "SPO Amp", NULL, "PDM1 R Mux" },
++	{ "SPOL", NULL, "SPO Amp" },
++	{ "SPOR", NULL, "SPO Amp" },
++#endif
++};
++
++static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
++{
++	int ret = 0, val;
++
++	if(codec == NULL)
++		return -EINVAL;
++
++	val = snd_soc_read(codec, RT5670_I2S1_SDP);
++	val = (val & RT5670_I2S_IF_MASK) >> RT5670_I2S_IF_SFT;
++	switch (dai_id) {
++	case RT5670_AIF1:
++		ret |= RT5670_U_IF1;
++		break;
++
++	case RT5670_AIF2:
++		ret |= RT5670_U_IF2;
++		break;
++
++	default:
++		ret = -EINVAL;
++		break;
++	}
++
++	return ret;
++}
++
++static int get_clk_info(int sclk, int rate)
++{
++	int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
++
++#ifdef USE_ASRC
++	return 0;
++#endif
++	if (sclk <= 0 || rate <= 0)
++		return -EINVAL;
++
++	rate = rate << 8;
++	for (i = 0; i < ARRAY_SIZE(pd); i++)
++		if (sclk == rate * pd[i])
++			return i;
++
++	return -EINVAL;
++}
++
++static int rt5670_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	unsigned int val_len = 0, val_clk, mask_clk, dai_sel;
++	int pre_div, bclk_ms, frame_size;
++
++	if (RT5670_AIF2 == dai->id) {
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_I2S2_PIN_MASK, RT5670_I2S2_PIN_I2S);
++	}
++	rt5670->lrck[dai->id] = params_rate(params);
++	pre_div = get_clk_info(rt5670->sysclk, rt5670->lrck[dai->id]);
++	if (pre_div < 0) {
++		dev_err(codec->dev, "Unsupported clock setting\n");
++		return -EINVAL;
++	}
++	frame_size = snd_soc_params_to_frame_size(params);
++	if (frame_size < 0) {
++		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
++		return -EINVAL;
++	}
++	bclk_ms = frame_size > 32 ? 1 : 0;
++	rt5670->bclk[dai->id] = rt5670->lrck[dai->id] * (32 << bclk_ms);
++
++	dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
++		rt5670->bclk[dai->id], rt5670->lrck[dai->id]);
++	dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
++				bclk_ms, pre_div, dai->id);
++
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		val_len |= RT5670_I2S_DL_20;
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		val_len |= RT5670_I2S_DL_24;
++		break;
++	case SNDRV_PCM_FORMAT_S8:
++		val_len |= RT5670_I2S_DL_8;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	dai_sel = get_sdp_info(codec, dai->id);
++	if (dai_sel < 0) {
++		dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
++		return -EINVAL;
++	}
++	if (dai_sel & RT5670_U_IF1) {
++		mask_clk = RT5670_I2S_BCLK_MS1_MASK | RT5670_I2S_PD1_MASK;
++		val_clk = bclk_ms << RT5670_I2S_BCLK_MS1_SFT |
++			pre_div << RT5670_I2S_PD1_SFT;
++		snd_soc_update_bits(codec, RT5670_I2S1_SDP,
++			RT5670_I2S_DL_MASK, val_len);
++		snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
++	}
++	if (dai_sel & RT5670_U_IF2) {
++		mask_clk = RT5670_I2S_BCLK_MS2_MASK | RT5670_I2S_PD2_MASK;
++		val_clk = bclk_ms << RT5670_I2S_BCLK_MS2_SFT |
++			pre_div << RT5670_I2S_PD2_SFT;
++		snd_soc_update_bits(codec, RT5670_I2S2_SDP,
++			RT5670_I2S_DL_MASK, val_len);
++		snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
++	}
++
++
++	return 0;
++}
++
++static int rt5670_hw_free(struct snd_pcm_substream *substream,
++	struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++
++	if (RT5670_AIF2 == dai->id) {
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_I2S2_PIN_MASK, RT5670_I2S2_PIN_GPIO);
++	}
++
++	return 0;
++}
++
++
++static int rt5670_prepare(struct snd_pcm_substream *substream,
++				struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	rt5670->aif_pu = dai->id;
++	return 0;
++}
++
++static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	unsigned int reg_val = 0, dai_sel;
++
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		rt5670->master[dai->id] = 1;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		reg_val |= RT5670_I2S_MS_S;
++		rt5670->master[dai->id] = 0;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		reg_val |= RT5670_I2S_BP_INV;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		reg_val |= RT5670_I2S_DF_LEFT;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		reg_val |= RT5670_I2S_DF_PCM_A;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		reg_val |= RT5670_I2S_DF_PCM_B;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	dai_sel = get_sdp_info(codec, dai->id);
++	if (dai_sel < 0) {
++		dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
++		return -EINVAL;
++	}
++	if (dai_sel & RT5670_U_IF1) {
++		snd_soc_update_bits(codec, RT5670_I2S1_SDP,
++			RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
++			RT5670_I2S_DF_MASK, reg_val);
++	}
++	if (dai_sel & RT5670_U_IF2) {
++		snd_soc_update_bits(codec, RT5670_I2S2_SDP,
++			RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
++			RT5670_I2S_DF_MASK, reg_val);
++	}
++
++
++	return 0;
++}
++
++static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	unsigned int reg_val = 0;
++
++	printk("\n=========[rt5670] %s(%d),CLK id is %d freq = %d \n",__FUNCTION__,__LINE__, clk_id, freq);
++
++	if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
++		return 0;
++
++	switch (clk_id) {
++	case RT5670_SCLK_S_MCLK:
++		reg_val |= RT5670_SCLK_SRC_MCLK;
++		break;
++	case RT5670_SCLK_S_PLL1:
++		reg_val |= RT5670_SCLK_SRC_PLL1;
++		break;
++	case RT5670_SCLK_S_RCCLK:
++		reg_val |= RT5670_SCLK_SRC_RCCLK;
++		break;
++	default:
++		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
++		return -EINVAL;
++	}
++	snd_soc_update_bits(codec, RT5670_GLB_CLK,
++		RT5670_SCLK_SRC_MASK, reg_val);
++	rt5670->sysclk = freq;
++	rt5670->sysclk_src = clk_id;
++
++	dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
++
++	return 0;
++}
++
++/**
++ * rt5670_pll_calc - Calcualte PLL M/N/K code.
++ * @freq_in: external clock provided to codec.
++ * @freq_out: target clock which codec works on.
++ * @pll_code: Pointer to structure with M, N, K and bypass flag.
++ *
++ * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2
++ * which make calculation more efficiently.
++ *
++ * Returns 0 for success or negative error code.
++ */
++static int rt5670_pll_calc(const unsigned int freq_in,
++	const unsigned int freq_out, struct rt5670_pll_code *pll_code)
++{
++	int max_n = RT5670_PLL_N_MAX, max_m = RT5670_PLL_M_MAX;
++	int k, n = 0, m = 0, red, n_t, m_t, pll_out, in_t;
++	int out_t, red_t = abs(freq_out - freq_in);
++	bool bypass = false;
++
++	if (RT5670_PLL_INP_MAX < freq_in || RT5670_PLL_INP_MIN > freq_in)
++		return -EINVAL;
++
++	k = 100000000 / freq_out - 2;
++	if (k > RT5670_PLL_K_MAX)
++		k = RT5670_PLL_K_MAX;
++	for (n_t = 0; n_t <= max_n; n_t++) {
++		in_t = freq_in / (k + 2);
++		pll_out = freq_out / (n_t + 2);
++		if (in_t < 0)
++			continue;
++		if (in_t == pll_out) {
++			bypass = true;
++			n = n_t;
++			goto code_find;
++		}
++		red = abs(in_t - pll_out);
++		if (red < red_t) {
++			bypass = true;
++			n = n_t;
++			m = m_t;
++			if (red == 0)
++				goto code_find;
++			red_t = red;
++		}
++		for (m_t = 0; m_t <= max_m; m_t++) {
++			out_t = in_t / (m_t + 2);
++			red = abs(out_t - pll_out);
++			if (red < red_t) {
++				bypass = false;
++				n = n_t;
++				m = m_t;
++				if (red == 0)
++					goto code_find;
++				red_t = red;
++			}
++		}
++	}
++	pr_debug("Only get approximation about PLL\n");
++
++code_find:
++
++	pll_code->m_bp = bypass;
++	pll_code->m_code = m;
++	pll_code->n_code = n;
++	pll_code->k_code = k;
++	return 0;
++}
++
++static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
++			unsigned int freq_in, unsigned int freq_out)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++	struct rt5670_pll_code pll_code;
++	int ret, dai_sel;
++
++	if (source == rt5670->pll_src && freq_in == rt5670->pll_in &&
++	    freq_out == rt5670->pll_out)
++		return 0;
++
++	if (!freq_in || !freq_out) {
++		dev_dbg(codec->dev, "PLL disabled\n");
++
++		rt5670->pll_in = 0;
++		rt5670->pll_out = 0;
++		snd_soc_update_bits(codec, RT5670_GLB_CLK,
++			RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_MCLK);
++		return 0;
++	}
++
++	switch (source) {
++	case RT5670_PLL1_S_MCLK:
++		snd_soc_update_bits(codec, RT5670_GLB_CLK,
++			RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_MCLK);
++		break;
++	case RT5670_PLL1_S_BCLK1:
++	case RT5670_PLL1_S_BCLK2:
++	case RT5670_PLL1_S_BCLK3:
++	case RT5670_PLL1_S_BCLK4:
++		dai_sel = get_sdp_info(codec, dai->id);
++		if (dai_sel < 0) {
++			dev_err(codec->dev,
++				"Failed to get sdp info: %d\n", dai_sel);
++			return -EINVAL;
++		}
++		if (dai_sel & RT5670_U_IF1) {
++			snd_soc_update_bits(codec, RT5670_GLB_CLK,
++				RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK1);
++		}
++		if (dai_sel & RT5670_U_IF2) {
++			snd_soc_update_bits(codec, RT5670_GLB_CLK,
++				RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK2);
++		}
++		break;
++	default:
++		dev_err(codec->dev, "Unknown PLL source %d\n", source);
++		return -EINVAL;
++	}
++
++	ret = rt5670_pll_calc(freq_in, freq_out, &pll_code);
++	if (ret < 0) {
++		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
++		return ret;
++	}
++
++	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
++		(pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code, pll_code.k_code);
++
++	snd_soc_write(codec, RT5670_PLL_CTRL1,
++		pll_code.n_code << RT5670_PLL_N_SFT | pll_code.k_code);
++	snd_soc_write(codec, RT5670_PLL_CTRL2,
++		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT |
++		pll_code.m_bp << RT5670_PLL_M_BP_SFT);
++
++	rt5670->pll_in = freq_in;
++	rt5670->pll_out = freq_out;
++	rt5670->pll_src = source;
++
++	return 0;
++}
++
++static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
++			unsigned int rx_mask, int slots, int slot_width)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	unsigned int val = 0;
++
++	if (rx_mask || tx_mask)
++		val |= (1 << 14);
++
++	switch (slots) {
++	case 4:
++		val |= (1 << 12);
++		break;
++	case 6:
++		val |= (2 << 12);
++		break;
++	case 8:
++		val |= (3 << 12);
++		break;
++	case 2:
++	default:
++		break;
++	}
++
++	switch (slot_width) {
++	case 20:
++		val |= (1 << 10);
++		break;
++	case 24:
++		val |= (2 << 10);
++		break;
++	case 32:
++		val |= (3 << 10);
++		break;
++	case 16:
++	default:
++		break;
++	}
++
++	snd_soc_update_bits(codec, RT5670_TDM_CTRL_1, 0x7c00, val);
++
++	return 0;
++}
++
++
++/**
++ * rt5670_index_show - Dump private registers.
++ * @dev: codec device.
++ * @attr: device attribute.
++ * @buf: buffer for display.
++ *
++ * To show non-zero values of all private registers.
++ *
++ * Returns buffer length.
++ */
++static ssize_t rt5670_index_show(struct device *dev,
++	struct device_attribute *attr, char *buf)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++	unsigned int val;
++	int cnt = 0, i;
++
++	codec->cache_bypass = 1;
++	cnt += sprintf(buf, "RT5670 index register\n");
++	for (i = 0; i < 0xff; i++) {
++		if (cnt + RT5670_REG_DISP_LEN >= PAGE_SIZE)
++			break;
++		val = rt5670_index_read(codec, i);
++		if (!val)
++			continue;
++		cnt += snprintf(buf + cnt, RT5670_REG_DISP_LEN,
++				"%02x: %04x\n", i, val);
++	}
++	codec->cache_bypass = 0;
++
++	if (cnt >= PAGE_SIZE)
++		cnt = PAGE_SIZE - 1;
++
++	return cnt;
++}
++
++static ssize_t rt5670_index_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++	unsigned int val=0,addr=0;
++	int i;
++
++	for(i=0;i<count;i++)
++	{
++		if(*(buf+i) <= '9' && *(buf+i)>='0')
++		{
++			addr = (addr << 4) | (*(buf+i)-'0');
++		}
++		else if(*(buf+i) <= 'f' && *(buf+i)>='a')
++		{
++			addr = (addr << 4) | ((*(buf+i)-'a')+0xa);
++		}
++		else if(*(buf+i) <= 'F' && *(buf+i)>='A')
++		{
++			addr = (addr << 4) | ((*(buf+i)-'A')+0xa);
++		}
++		else
++		{
++			break;
++		}
++	}
++
++	for(i=i+1 ;i<count;i++)
++	{
++		if(*(buf+i) <= '9' && *(buf+i)>='0')
++		{
++			val = (val << 4) | (*(buf+i)-'0');
++		}
++		else if(*(buf+i) <= 'f' && *(buf+i)>='a')
++		{
++			val = (val << 4) | ((*(buf+i)-'a')+0xa);
++		}
++		else if(*(buf+i) <= 'F' && *(buf+i)>='A')
++		{
++			val = (val << 4) | ((*(buf+i)-'A')+0xa);
++
++		}
++		else
++		{
++			break;
++		}
++	}
++	printk("addr=0x%x val=0x%x\n",addr,val);
++	if(addr > RT5670_VENDOR_ID2 || val > 0xffff || val < 0)
++		return count;
++
++	if(i==count)
++	{
++		printk("0x%02x = 0x%04x\n",addr,rt5670_index_read(codec, addr));
++	}
++	else
++	{
++		rt5670_index_write(codec, addr, val);
++	}
++
++
++	return count;
++}
++static DEVICE_ATTR(index_reg, 0666, rt5670_index_show, rt5670_index_store);
++
++static ssize_t rt5670_codec_show(struct device *dev,
++	struct device_attribute *attr, char *buf)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++	unsigned int val;
++	int cnt = 0, i;
++
++	for (i = 0; i <= RT5670_VENDOR_ID2; i++) {
++		if (cnt + RT5670_REG_DISP_LEN >= PAGE_SIZE)
++			break;
++		val = snd_soc_read(codec, i);
++		if (!val)
++			continue;
++		cnt += snprintf(buf + cnt, RT5670_REG_DISP_LEN,
++				"#rng%02x  #rv%04x  #rd0\n", i, val);
++	}
++
++	if (cnt >= PAGE_SIZE)
++		cnt = PAGE_SIZE - 1;
++
++	return cnt;
++}
++
++static ssize_t rt5670_codec_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++	unsigned int val=0,addr=0;
++	int i;
++
++	printk("register \"%s\" count=%d\n",buf,count);
++	for(i=0;i<count;i++)
++	{
++		if(*(buf+i) <= '9' && *(buf+i)>='0')
++		{
++			addr = (addr << 4) | (*(buf+i)-'0');
++		}
++		else if(*(buf+i) <= 'f' && *(buf+i)>='a')
++		{
++			addr = (addr << 4) | ((*(buf+i)-'a')+0xa);
++		}
++		else if(*(buf+i) <= 'F' && *(buf+i)>='A')
++		{
++			addr = (addr << 4) | ((*(buf+i)-'A')+0xa);
++		}
++		else
++		{
++			break;
++		}
++	}
++
++	for(i=i+1 ;i<count;i++)
++	{
++		if(*(buf+i) <= '9' && *(buf+i)>='0')
++		{
++			val = (val << 4) | (*(buf+i)-'0');
++		}
++		else if(*(buf+i) <= 'f' && *(buf+i)>='a')
++		{
++			val = (val << 4) | ((*(buf+i)-'a')+0xa);
++		}
++		else if(*(buf+i) <= 'F' && *(buf+i)>='A')
++		{
++			val = (val << 4) | ((*(buf+i)-'A')+0xa);
++
++		}
++		else
++		{
++			break;
++		}
++	}
++	printk("addr=0x%x val=0x%x\n",addr,val);
++	if(addr > RT5670_VENDOR_ID2 || val > 0xffff || val < 0)
++		return count;
++
++	if(i==count)
++	{
++		printk("0x%02x = 0x%04x\n",addr,codec->hw_read(codec, addr));
++	}
++	else
++	{
++		snd_soc_write(codec, addr, val);
++	}
++
++
++	return count;
++}
++
++static DEVICE_ATTR(codec_reg, 0666, rt5670_codec_show, rt5670_codec_store);
++
++static int rt5670_set_bias_level(struct snd_soc_codec *codec,
++			enum snd_soc_bias_level level)
++{
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++		break;
++
++	case SND_SOC_BIAS_PREPARE:
++		if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
++			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++				RT5670_PWR_VREF1 | RT5670_PWR_MB |
++				RT5670_PWR_BG | RT5670_PWR_VREF2,
++				RT5670_PWR_VREF1 | RT5670_PWR_MB |
++				RT5670_PWR_BG | RT5670_PWR_VREF2);
++			mdelay(10);
++			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++				RT5670_PWR_FV1 | RT5670_PWR_FV2,
++				RT5670_PWR_FV1 | RT5670_PWR_FV2);
++			snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
++				RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
++				RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
++			snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x1);
++			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++				RT5670_LDO_SEL_MASK, 0x3);
++		}
++		break;
++
++	case SND_SOC_BIAS_STANDBY:
++		break;
++
++	case SND_SOC_BIAS_OFF:
++		snd_soc_write(codec, RT5670_PWR_DIG1, 0x0000);
++		snd_soc_write(codec, RT5670_PWR_DIG2, 0x0001);
++		snd_soc_write(codec, RT5670_PWR_VOL, 0x0000);
++		snd_soc_write(codec, RT5670_PWR_MIXER, 0x0001);
++#ifdef JD1_FUNC
++		snd_soc_write(codec, RT5670_PWR_ANLG1, 0x2800);
++		snd_soc_write(codec, RT5670_PWR_ANLG2, 0x0004);
++#else
++		snd_soc_write(codec, RT5670_PWR_ANLG1, 0x0000);
++		snd_soc_write(codec, RT5670_PWR_ANLG2, 0x0000);
++#endif
++		if (rt5670->jack_type == SND_JACK_HEADSET) {
++			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++				0x0003, 0x0003);
++			snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++				0x0c00, 0x0c00);
++			snd_soc_update_bits(codec, RT5670_PWR_DIG1,
++				0x1800, 0x1800);
++			snd_soc_update_bits(codec, RT5670_PWR_VOL,
++				0x0020, 0x0020);
++		}
++		break;
++
++	default:
++		break;
++	}
++	codec->dapm.bias_level = level;
++
++	return 0;
++}
++
++static int rt5670_probe(struct snd_soc_codec *codec)
++{
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++#ifdef RTK_IOCTL
++#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
++	struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
++#endif
++#endif
++	int ret;
++
++	printk("dbg: %s line %d\n",__func__,__LINE__);
++	pr_info("Codec driver version %s\n", VERSION);
++
++	codec->dapm.idle_bias_off = 1;
++
++	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++	rt5670_reset(codec);
++	snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++		RT5670_PWR_HP_L | RT5670_PWR_HP_R |
++		RT5670_PWR_VREF2, RT5670_PWR_VREF2);
++	msleep(1000);
++
++	rt5670_reset(codec);
++	snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++		RT5670_PWR_VREF1 | RT5670_PWR_MB |
++		RT5670_PWR_BG | RT5670_PWR_VREF2,
++		RT5670_PWR_VREF1 | RT5670_PWR_MB |
++		RT5670_PWR_BG | RT5670_PWR_VREF2);
++	msleep(10);
++	snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++		RT5670_PWR_FV1 | RT5670_PWR_FV2,
++		RT5670_PWR_FV1 | RT5670_PWR_FV2);
++	/* DMIC */
++	if (rt5670->dmic_en == RT5670_DMIC1) {
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_GP2_PIN_MASK, RT5670_GP2_PIN_DMIC1_SCL);
++		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
++			RT5670_DMIC_1L_LH_MASK | RT5670_DMIC_1R_LH_MASK,
++			RT5670_DMIC_1L_LH_FALLING | RT5670_DMIC_1R_LH_RISING);
++	} else if (rt5670->dmic_en == RT5670_DMIC2) {
++		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_GP2_PIN_MASK, RT5670_GP2_PIN_DMIC1_SCL);
++		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
++			RT5670_DMIC_2L_LH_MASK | RT5670_DMIC_2R_LH_MASK,
++			RT5670_DMIC_2L_LH_FALLING | RT5670_DMIC_2R_LH_RISING);
++	}
++
++	rt5670_reg_init(codec);
++#ifdef JD1_FUNC
++	snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
++			RT5670_PWR_MB | RT5670_PWR_BG,
++			RT5670_PWR_MB | RT5670_PWR_BG);
++	snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
++			RT5670_PWR_JD1,
++			RT5670_PWR_JD1);
++#endif
++
++	snd_soc_update_bits(codec, RT5670_PWR_ANLG1, RT5670_LDO_SEL_MASK, 0x0);
++	snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
++			RT5670_I2S2_PIN_MASK, RT5670_I2S2_PIN_GPIO);
++
++	rt5670->codec = codec;
++	rt5670->combo_jack_en = true; /* enable combo jack */
++
++	snd_soc_add_codec_controls(codec, rt5670_snd_controls,
++			ARRAY_SIZE(rt5670_snd_controls));
++	snd_soc_dapm_new_controls(&codec->dapm, rt5670_dapm_widgets,
++			ARRAY_SIZE(rt5670_dapm_widgets));
++	snd_soc_dapm_add_routes(&codec->dapm, rt5670_dapm_routes,
++			ARRAY_SIZE(rt5670_dapm_routes));
++
++	rt5670->dsp_sw = RT5670_DSP_NS;
++	rt5670_dsp_probe(codec);
++
++#ifdef RTK_IOCTL
++#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
++	ioctl_ops->index_write = rt5670_index_write;
++	ioctl_ops->index_read = rt5670_index_read;
++	ioctl_ops->index_update_bits = rt5670_index_update_bits;
++	ioctl_ops->ioctl_common = rt5670_ioctl_common;
++	realtek_ce_init_hwdep(codec);
++#endif
++#endif
++
++	ret = device_create_file(codec->dev, &dev_attr_index_reg);
++	if (ret != 0) {
++		dev_err(codec->dev,
++			"Failed to create index_reg sysfs files: %d\n", ret);
++		return ret;
++	}
++
++	ret = device_create_file(codec->dev, &dev_attr_codec_reg);
++	if (ret != 0) {
++		dev_err(codec->dev,
++			"Failed to create codex_reg sysfs files: %d\n", ret);
++		return ret;
++	}
++
++	rt5670_codec = codec;
++	rt5670->jack_type = 0;
++
++	return 0;
++}
++
++static int rt5670_remove(struct snd_soc_codec *codec)
++{
++	rt5670_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int rt5670_suspend(struct snd_soc_codec *codec)
++{
++	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
++
++	rt5670_dsp_suspend(codec);
++	rt5670->jack_type = 0;
++	return 0;
++}
++
++static int rt5670_resume(struct snd_soc_codec *codec)
++{
++	codec->cache_only = false;
++	codec->cache_sync = 1;
++	snd_soc_cache_sync(codec);
++	rt5670_index_sync(codec);
++	rt5670_dsp_resume(codec);
++	return 0;
++}
++#else
++#define rt5670_suspend NULL
++#define rt5670_resume NULL
++#endif
++
++static void rt5670_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
++{
++	printk("enter %s\n",__func__);
++}
++
++#define RT5670_STEREO_RATES SNDRV_PCM_RATE_8000_96000
++#define RT5670_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
++			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
++
++struct snd_soc_dai_ops rt5670_aif_dai_ops = {
++	.hw_params = rt5670_hw_params,
++	.hw_free = rt5670_hw_free,
++	.prepare = rt5670_prepare,
++	.set_fmt = rt5670_set_dai_fmt,
++	.set_sysclk = rt5670_set_dai_sysclk,
++	.set_tdm_slot = rt5670_set_tdm_slot,
++	.set_pll = rt5670_set_dai_pll,
++	.shutdown = rt5670_shutdown,
++};
++
++struct snd_soc_dai_driver rt5670_dai[] = {
++	{
++		.name = "rt5670-aif1",
++		.id = RT5670_AIF1,
++		.playback = {
++			.stream_name = "AIF1 Playback",
++			.channels_min = 1,
++			.channels_max = 2,
++			.rates = RT5670_STEREO_RATES,
++			.formats = RT5670_FORMATS,
++		},
++		.capture = {
++			.stream_name = "AIF1 Capture",
++			.channels_min = 1,
++			.channels_max = 2,
++			.rates = RT5670_STEREO_RATES,
++			.formats = RT5670_FORMATS,
++		},
++		.ops = &rt5670_aif_dai_ops,
++	},
++	{
++		.name = "rt5670-aif2",
++		.id = RT5670_AIF2,
++		.playback = {
++			.stream_name = "AIF2 Playback",
++			.channels_min = 1,
++			.channels_max = 2,
++			.rates = RT5670_STEREO_RATES,
++			.formats = RT5670_FORMATS,
++		},
++		.capture = {
++			.stream_name = "AIF2 Capture",
++			.channels_min = 1,
++			.channels_max = 2,
++			.rates = RT5670_STEREO_RATES,
++			.formats = RT5670_FORMATS,
++		},
++		.ops = &rt5670_aif_dai_ops,
++	},
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_rt5670 = {
++	.probe = rt5670_probe,
++	.remove = rt5670_remove,
++	.suspend = rt5670_suspend,
++	.resume = rt5670_resume,
++	.set_bias_level = rt5670_set_bias_level,
++	.reg_cache_size = RT5670_VENDOR_ID2 + 1,
++	.reg_word_size = sizeof(u16),
++	.reg_cache_default = rt5670_reg,
++	.volatile_register = rt5670_volatile_register,
++	.readable_register = rt5670_readable_register,
++	.reg_cache_step = 1,
++};
++
++static const struct i2c_device_id rt5670_i2c_id[] = {
++	{ "rt5670", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id);
++
++static int rt5670_i2c_probe(struct i2c_client *i2c,
++		    const struct i2c_device_id *id)
++{
++	struct rt5670_priv *rt5670;
++	int ret;
++
++	printk("dbg: %s line %d\n",__func__,__LINE__);
++	rt5670 = kzalloc(sizeof(struct rt5670_priv), GFP_KERNEL);
++	if (NULL == rt5670)
++		return -ENOMEM;
++
++	i2c_set_clientdata(i2c, rt5670);
++
++	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
++			rt5670_dai, ARRAY_SIZE(rt5670_dai));
++	if (ret < 0)
++		kfree(rt5670);
++
++	return ret;
++}
++
++static int rt5670_i2c_remove(struct i2c_client *i2c)
++{
++	snd_soc_unregister_codec(&i2c->dev);
++	kfree(i2c_get_clientdata(i2c));
++	return 0;
++}
++
++void rt5670_i2c_shutdown(struct i2c_client *client)
++{
++	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = rt5670->codec;
++
++	printk("enter %s\n",__func__);
++	if (codec != NULL)
++		rt5670_set_bias_level(codec, SND_SOC_BIAS_OFF);
++}
++
++static struct of_device_id rt5670_of_match[] = {
++	{ .compatible = "ambarella,rt5670",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, rt5670_of_match);
++
++struct i2c_driver rt5670_i2c_driver = {
++	.driver = {
++		.name = "rt5670",
++		.owner = THIS_MODULE,
++		.of_match_table = rt5670_of_match,
++	},
++	.probe = rt5670_i2c_probe,
++	.remove   = rt5670_i2c_remove,
++	.shutdown = rt5670_i2c_shutdown,
++	.id_table = rt5670_i2c_id,
++};
++
++static int __init rt5670_modinit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	return i2c_add_driver(&rt5670_i2c_driver);
++#endif
++}
++module_init(rt5670_modinit);
++
++static void __exit rt5670_modexit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	i2c_del_driver(&rt5670_i2c_driver);
++#endif
++}
++module_exit(rt5670_modexit);
++
++MODULE_DESCRIPTION("ASoC RT5670 driver");
++MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
+new file mode 100644
+index 00000000..4bfb55ca
+--- /dev/null
++++ b/sound/soc/codecs/rt5670.h
+@@ -0,0 +1,2001 @@
++/*
++ * rt5670.h  --  RT5670 ALSA SoC audio driver
++ *
++ * Copyright 2011 Realtek Microelectronics
++ * Author: Johnny Hsu <johnnyhsu@realtek.com>
++ *
++ * 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.
++ */
++
++#ifndef __RT5670_H__
++#define __RT5670_H__
++
++/* Info */
++#define RT5670_RESET				0x00
++#define RT5670_VENDOR_ID			0xfd
++#define RT5670_VENDOR_ID1			0xfe
++#define RT5670_VENDOR_ID2			0xff
++/*  I/O - Output */
++#define RT5670_HP_VOL				0x02
++#define RT5670_LOUT1				0x03
++/* I/O - Input */
++#define RT5670_CJ_CTRL1				0x0a
++#define RT5670_CJ_CTRL2				0x0b
++#define RT5670_CJ_CTRL3				0x0c
++#define RT5670_IN1_IN2				0x0d
++#define RT5670_IN3				0x0e
++#define RT5670_INL1_INR1_VOL			0x0f
++/* I/O - ADC/DAC/DMIC */
++#define RT5670_DAC1_DIG_VOL			0x19
++#define RT5670_DAC2_DIG_VOL			0x1a
++#define RT5670_DAC_CTRL				0x1b
++#define RT5670_STO1_ADC_DIG_VOL			0x1c
++#define RT5670_MONO_ADC_DIG_VOL			0x1d
++#define RT5670_ADC_BST_VOL1			0x1e
++#define RT5670_STO2_ADC_DIG_VOL			0x1f
++/* Mixer - D-D */
++#define RT5670_ADC_BST_VOL2			0x20
++#define RT5670_STO2_ADC_MIXER			0x26
++#define RT5670_STO1_ADC_MIXER			0x27
++#define RT5670_MONO_ADC_MIXER			0x28
++#define RT5670_AD_DA_MIXER			0x29
++#define RT5670_STO_DAC_MIXER			0x2a
++#define RT5670_DD_MIXER				0x2b
++#define RT5670_DIG_MIXER			0x2c
++#define RT5670_DSP_PATH1			0x2d
++#define RT5670_DSP_PATH2			0x2e
++#define RT5670_DIG_INF1_DATA			0x2f
++#define RT5670_DIG_INF2_DATA			0x30
++/* Mixer - PDM */
++#define RT5670_PDM_OUT_CTRL			0x31
++#define RT5670_PDM_DATA_CTRL1			0x32
++#define RT5670_PDM1_DATA_CTRL2			0x33
++#define RT5670_PDM1_DATA_CTRL3			0x34
++#define RT5670_PDM1_DATA_CTRL4			0x35
++#define RT5670_PDM2_DATA_CTRL2			0x36
++#define RT5670_PDM2_DATA_CTRL3			0x37
++#define RT5670_PDM2_DATA_CTRL4			0x38
++/* Mixer - ADC */
++#define RT5670_REC_L1_MIXER			0x3b
++#define RT5670_REC_L2_MIXER			0x3c
++#define RT5670_REC_R1_MIXER			0x3d
++#define RT5670_REC_R2_MIXER			0x3e
++/* Mixer - DAC */
++#define RT5670_HPO_MIXER			0x45
++#define RT5670_MONO_MIXER			0x4c
++#define RT5670_OUT_L1_MIXER			0x4f
++#define RT5670_OUT_R1_MIXER			0x52
++#define RT5670_LOUT_MIXER			0x53
++/* Power */
++#define RT5670_PWR_DIG1				0x61
++#define RT5670_PWR_DIG2				0x62
++#define RT5670_PWR_ANLG1			0x63
++#define RT5670_PWR_ANLG2			0x64
++#define RT5670_PWR_MIXER			0x65
++#define RT5670_PWR_VOL				0x66
++/* Private Register Control */
++#define RT5670_PRIV_INDEX			0x6a
++#define RT5670_PRIV_DATA			0x6c
++/* Format - ADC/DAC */
++#define RT5670_I2S4_SDP				0x6f
++#define RT5670_I2S1_SDP				0x70
++#define RT5670_I2S2_SDP				0x71
++#define RT5670_I2S3_SDP				0x72
++#define RT5670_ADDA_CLK1			0x73
++#define RT5670_ADDA_CLK2			0x74
++#define RT5670_DMIC_CTRL1			0x75
++#define RT5670_DMIC_CTRL2			0x76
++/* Format - TDM Control */
++#define RT5670_TDM_CTRL_1			0x77
++#define RT5670_TDM_CTRL_2			0x78
++#define RT5670_TDM_CTRL_3			0x79
++
++/* Function - Analog */
++#define RT5670_DSP_CLK				0x7f
++#define RT5670_GLB_CLK				0x80
++#define RT5670_PLL_CTRL1			0x81
++#define RT5670_PLL_CTRL2			0x82
++#define RT5670_ASRC_1				0x83
++#define RT5670_ASRC_2				0x84
++#define RT5670_ASRC_3				0x85
++#define RT5670_ASRC_4				0x86
++#define RT5670_ASRC_5				0x87
++#define RT5670_ASRC_7				0x89
++#define RT5670_ASRC_8				0x8a
++#define RT5670_ASRC_9				0x8b
++#define RT5670_ASRC_10				0x8c
++#define RT5670_ASRC_11				0x8d
++#define RT5670_DEPOP_M1				0x8e
++#define RT5670_DEPOP_M2				0x8f
++#define RT5670_DEPOP_M3				0x90
++#define RT5670_CHARGE_PUMP			0x91
++#define RT5670_MICBIAS				0x93
++#define RT5670_A_JD_CTRL1			0x94
++#define RT5670_A_JD_CTRL2			0x95
++#define RT5670_ASRC_12				0x97
++#define RT5670_ASRC_13				0x98
++#define RT5670_ASRC_14				0x99
++#define RT5670_VAD_CTRL1			0x9a
++#define RT5670_VAD_CTRL2			0x9b
++#define RT5670_VAD_CTRL3			0x9c
++#define RT5670_VAD_CTRL4			0x9d
++#define RT5670_VAD_CTRL5			0x9e
++/* Function - Digital */
++#define RT5670_ADC_EQ_CTRL1			0xae
++#define RT5670_ADC_EQ_CTRL2			0xaf
++#define RT5670_EQ_CTRL1				0xb0
++#define RT5670_EQ_CTRL2				0xb1
++#define RT5670_ALC_DRC_CTRL1			0xb2
++#define RT5670_ALC_DRC_CTRL2			0xb3
++#define RT5670_ALC_CTRL_1			0xb4
++#define RT5670_ALC_CTRL_2			0xb5
++#define RT5670_ALC_CTRL_3			0xb6
++#define RT5670_ALC_CTRL_4			0xb7
++#define RT5670_JD_CTRL				0xbb
++#define RT5670_IRQ_CTRL1			0xbc
++#define RT5670_IRQ_CTRL2			0xbd
++#define RT5670_IRQ_CTRL3			0xbe
++#define RT5670_INT_IRQ_ST			0xbf
++#define RT5670_GPIO_CTRL1			0xc0
++#define RT5670_GPIO_CTRL2			0xc1
++#define RT5670_GPIO_CTRL3			0xc2
++#define RT5670_SCRABBLE_FUN			0xcd
++#define RT5670_SCRABBLE_CTRL			0xce
++#define RT5670_BASE_BACK			0xcf
++#define RT5670_MP3_PLUS1			0xd0
++#define RT5670_MP3_PLUS2			0xd1
++#define RT5670_ADJ_HPF1				0xd3
++#define RT5670_ADJ_HPF2				0xd4
++#define RT5670_HP_CALIB_AMP_DET			0xd6
++#define RT5670_SV_ZCD1				0xd9
++#define RT5670_SV_ZCD2				0xda
++#define RT5670_IL_CMD				0xdb
++#define RT5670_IL_CMD2				0xdc
++#define RT5670_IL_CMD3				0xdd
++#define RT5670_DRC_HL_CTRL1			0xe6
++#define RT5670_DRC_HL_CTRL2			0xe7
++#define RT5670_ADC_MONO_HP_CTRL1		0xec
++#define RT5670_ADC_MONO_HP_CTRL2		0xed
++#define RT5670_ADC_STO2_HP_CTRL1		0xee
++#define RT5670_ADC_STO2_HP_CTRL2		0xef
++#define RT5670_JD_CTRL3				0xf8
++#define RT5670_JD_CTRL4				0xf9
++/* General Control */
++#define RT5670_DIG_MISC				0xfa
++#define RT5670_GEN_CTRL2			0xfb
++#define RT5670_GEN_CTRL3			0xfc
++
++
++/* Index of Codec Private Register definition */
++#define RT5670_DIG_VOL				0x00
++#define RT5670_PR_ALC_CTRL_1			0x01
++#define RT5670_PR_ALC_CTRL_2			0x02
++#define RT5670_PR_ALC_CTRL_3			0x03
++#define RT5670_PR_ALC_CTRL_4			0x04
++#define RT5670_PR_ALC_CTRL_5			0x05
++#define RT5670_PR_ALC_CTRL_6			0x06
++#define RT5670_BIAS_CUR1			0x12
++#define RT5670_BIAS_CUR3			0x14
++#define RT5670_CLSD_INT_REG1			0x1c
++#define RT5670_MAMP_INT_REG2			0x37
++#define RT5670_CHOP_DAC_ADC			0x3d
++#define RT5670_MIXER_INT_REG			0x3f
++#define RT5670_3D_SPK				0x63
++#define RT5670_WND_1				0x6c
++#define RT5670_WND_2				0x6d
++#define RT5670_WND_3				0x6e
++#define RT5670_WND_4				0x6f
++#define RT5670_WND_5				0x70
++#define RT5670_WND_8				0x73
++#define RT5670_DIP_SPK_INF			0x75
++#define RT5670_HP_DCC_INT1			0x77
++#define RT5670_EQ_BW_LOP			0xa0
++#define RT5670_EQ_GN_LOP			0xa1
++#define RT5670_EQ_FC_BP1			0xa2
++#define RT5670_EQ_BW_BP1			0xa3
++#define RT5670_EQ_GN_BP1			0xa4
++#define RT5670_EQ_FC_BP2			0xa5
++#define RT5670_EQ_BW_BP2			0xa6
++#define RT5670_EQ_GN_BP2			0xa7
++#define RT5670_EQ_FC_BP3			0xa8
++#define RT5670_EQ_BW_BP3			0xa9
++#define RT5670_EQ_GN_BP3			0xaa
++#define RT5670_EQ_FC_BP4			0xab
++#define RT5670_EQ_BW_BP4			0xac
++#define RT5670_EQ_GN_BP4			0xad
++#define RT5670_EQ_FC_HIP1			0xae
++#define RT5670_EQ_GN_HIP1			0xaf
++#define RT5670_EQ_FC_HIP2			0xb0
++#define RT5670_EQ_BW_HIP2			0xb1
++#define RT5670_EQ_GN_HIP2			0xb2
++#define RT5670_EQ_PRE_VOL			0xb3
++#define RT5670_EQ_PST_VOL			0xb4
++
++
++/* global definition */
++#define RT5670_L_MUTE				(0x1 << 15)
++#define RT5670_L_MUTE_SFT			15
++#define RT5670_VOL_L_MUTE			(0x1 << 14)
++#define RT5670_VOL_L_SFT			14
++#define RT5670_R_MUTE				(0x1 << 7)
++#define RT5670_R_MUTE_SFT			7
++#define RT5670_VOL_R_MUTE			(0x1 << 6)
++#define RT5670_VOL_R_SFT			6
++#define RT5670_L_VOL_MASK			(0x3f << 8)
++#define RT5670_L_VOL_SFT			8
++#define RT5670_R_VOL_MASK			(0x3f)
++#define RT5670_R_VOL_SFT			0
++
++/* Combo Jack Control 1 (0x0a) */
++#define RT5670_CBJ_BST1_MASK			(0xf << 12)
++#define RT5670_CBJ_BST1_SFT			(12)
++#define RT5670_CBJ_JD_HP_EN			(0x1 << 9)
++#define RT5670_CBJ_JD_MIC_EN			(0x1 << 8)
++#define RT5670_CBJ_BST1_EN			(0x1 << 2)
++
++/* Combo Jack Control 1 (0x0b) */
++#define RT5670_CBJ_MN_JD			(0x1 << 12)
++#define RT5670_CAPLESS_EN			(0x1 << 11)
++#define RT5670_CBJ_DET_MODE			(0x1 << 7)
++
++/* IN1 and IN2 Control (0x0d) */
++/* IN3 and IN4 Control (0x0e) */
++#define RT5670_BST_MASK1			(0xf<<12)
++#define RT5670_BST_SFT1				12
++#define RT5670_BST_MASK2			(0xf<<8)
++#define RT5670_BST_SFT2				8
++#define RT5670_IN_DF1				(0x1 << 7)
++#define RT5670_IN_SFT1				7
++#define RT5670_IN_DF2				(0x1 << 6)
++#define RT5670_IN_SFT2				6
++
++/* INL and INR Volume Control (0x0f) */
++#define RT5670_INL_SEL_MASK			(0x1 << 15)
++#define RT5670_INL_SEL_SFT			15
++#define RT5670_INL_SEL_IN4P			(0x0 << 15)
++#define RT5670_INL_SEL_MONOP			(0x1 << 15)
++#define RT5670_INL_VOL_MASK			(0x1f << 8)
++#define RT5670_INL_VOL_SFT			8
++#define RT5670_INR_SEL_MASK			(0x1 << 7)
++#define RT5670_INR_SEL_SFT			7
++#define RT5670_INR_SEL_IN4N			(0x0 << 7)
++#define RT5670_INR_SEL_MONON			(0x1 << 7)
++#define RT5670_INR_VOL_MASK			(0x1f)
++#define RT5670_INR_VOL_SFT			0
++
++/* Sidetone Control (0x18) */
++#define RT5670_ST_SEL_MASK			(0x7 << 9)
++#define RT5670_ST_SEL_SFT			9
++#define RT5670_M_ST_DACR2			(0x1 << 8)
++#define RT5670_M_ST_DACR2_SFT			8
++#define RT5670_M_ST_DACL2			(0x1 << 7)
++#define RT5670_M_ST_DACL2_SFT			7
++#define RT5670_ST_EN				(0x1 << 6)
++#define RT5670_ST_EN_SFT			6
++
++/* DAC1 Digital Volume (0x19) */
++#define RT5670_DAC_L1_VOL_MASK			(0xff << 8)
++#define RT5670_DAC_L1_VOL_SFT			8
++#define RT5670_DAC_R1_VOL_MASK			(0xff)
++#define RT5670_DAC_R1_VOL_SFT			0
++
++/* DAC2 Digital Volume (0x1a) */
++#define RT5670_DAC_L2_VOL_MASK			(0xff << 8)
++#define RT5670_DAC_L2_VOL_SFT			8
++#define RT5670_DAC_R2_VOL_MASK			(0xff)
++#define RT5670_DAC_R2_VOL_SFT			0
++
++/* DAC2 Control (0x1b) */
++#define RT5670_M_DAC_L2_VOL			(0x1 << 13)
++#define RT5670_M_DAC_L2_VOL_SFT			13
++#define RT5670_M_DAC_R2_VOL			(0x1 << 12)
++#define RT5670_M_DAC_R2_VOL_SFT			12
++#define RT5670_DAC2_L_SEL_MASK			(0x7 << 4)
++#define RT5670_DAC2_L_SEL_SFT			4
++#define RT5670_DAC2_R_SEL_MASK			(0x7 << 0)
++#define RT5670_DAC2_R_SEL_SFT			0
++
++/* ADC Digital Volume Control (0x1c) */
++#define RT5670_ADC_L_VOL_MASK			(0x7f << 8)
++#define RT5670_ADC_L_VOL_SFT			8
++#define RT5670_ADC_R_VOL_MASK			(0x7f)
++#define RT5670_ADC_R_VOL_SFT			0
++
++/* Mono ADC Digital Volume Control (0x1d) */
++#define RT5670_MONO_ADC_L_VOL_MASK		(0x7f << 8)
++#define RT5670_MONO_ADC_L_VOL_SFT		8
++#define RT5670_MONO_ADC_R_VOL_MASK		(0x7f)
++#define RT5670_MONO_ADC_R_VOL_SFT		0
++
++/* ADC Boost Volume Control (0x1e) */
++#define RT5670_STO1_ADC_L_BST_MASK		(0x3 << 14)
++#define RT5670_STO1_ADC_L_BST_SFT		14
++#define RT5670_STO1_ADC_R_BST_MASK		(0x3 << 12)
++#define RT5670_STO1_ADC_R_BST_SFT		12
++#define RT5670_STO1_ADC_COMP_MASK		(0x3 << 10)
++#define RT5670_STO1_ADC_COMP_SFT		10
++#define RT5670_STO2_ADC_L_BST_MASK		(0x3 << 8)
++#define RT5670_STO2_ADC_L_BST_SFT		8
++#define RT5670_STO2_ADC_R_BST_MASK		(0x3 << 6)
++#define RT5670_STO2_ADC_R_BST_SFT		6
++#define RT5670_STO2_ADC_COMP_MASK		(0x3 << 4)
++#define RT5670_STO2_ADC_COMP_SFT		4
++
++/* Stereo2 ADC Mixer Control (0x26) */
++#define RT5670_STO2_ADC_SRC_MASK		(0x1 << 15)
++#define RT5670_STO2_ADC_SRC_SFT			15
++
++/* Stereo ADC Mixer Control (0x26 0x27) */
++#define RT5670_M_ADC_L1				(0x1 << 14)
++#define RT5670_M_ADC_L1_SFT			14
++#define RT5670_M_ADC_L2				(0x1 << 13)
++#define RT5670_M_ADC_L2_SFT			13
++#define RT5670_ADC_1_SRC_MASK			(0x1 << 12)
++#define RT5670_ADC_1_SRC_SFT			12
++#define RT5670_ADC_1_SRC_ADC			(0x1 << 12)
++#define RT5670_ADC_1_SRC_DACMIX			(0x0 << 12)
++#define RT5670_ADC_2_SRC_MASK			(0x1 << 11)
++#define RT5670_ADC_2_SRC_SFT			11
++#define RT5670_ADC_SRC_MASK			(0x1 << 10)
++#define RT5670_ADC_SRC_SFT			10
++#define RT5670_DMIC_SRC_MASK			(0x3 << 8)
++#define RT5670_DMIC_SRC_SFT			8
++#define RT5670_M_ADC_R1				(0x1 << 6)
++#define RT5670_M_ADC_R1_SFT			6
++#define RT5670_M_ADC_R2				(0x1 << 5)
++#define RT5670_M_ADC_R2_SFT			5
++#define RT5670_DMIC3_SRC_MASK			(0x1 << 1)
++#define RT5670_DMIC3_SRC_SFT			0
++
++/* Mono ADC Mixer Control (0x28) */
++#define RT5670_M_MONO_ADC_L1			(0x1 << 14)
++#define RT5670_M_MONO_ADC_L1_SFT		14
++#define RT5670_M_MONO_ADC_L2			(0x1 << 13)
++#define RT5670_M_MONO_ADC_L2_SFT		13
++#define RT5670_MONO_ADC_L1_SRC_MASK		(0x1 << 12)
++#define RT5670_MONO_ADC_L1_SRC_SFT		12
++#define RT5670_MONO_ADC_L1_SRC_DACMIXL		(0x0 << 12)
++#define RT5670_MONO_ADC_L1_SRC_ADCL		(0x1 << 12)
++#define RT5670_MONO_ADC_L2_SRC_MASK		(0x1 << 11)
++#define RT5670_MONO_ADC_L2_SRC_SFT		11
++#define RT5670_MONO_ADC_L_SRC_MASK		(0x1 << 10)
++#define RT5670_MONO_ADC_L_SRC_SFT		10
++#define RT5670_MONO_DMIC_L_SRC_MASK		(0x3 << 8)
++#define RT5670_MONO_DMIC_L_SRC_SFT		8
++#define RT5670_M_MONO_ADC_R1			(0x1 << 6)
++#define RT5670_M_MONO_ADC_R1_SFT		6
++#define RT5670_M_MONO_ADC_R2			(0x1 << 5)
++#define RT5670_M_MONO_ADC_R2_SFT		5
++#define RT5670_MONO_ADC_R1_SRC_MASK		(0x1 << 4)
++#define RT5670_MONO_ADC_R1_SRC_SFT		4
++#define RT5670_MONO_ADC_R1_SRC_ADCR		(0x1 << 4)
++#define RT5670_MONO_ADC_R1_SRC_DACMIXR		(0x0 << 4)
++#define RT5670_MONO_ADC_R2_SRC_MASK		(0x1 << 3)
++#define RT5670_MONO_ADC_R2_SRC_SFT		3
++#define RT5670_MONO_ADC_R_SRC_MASK		(0x1 << 2)
++#define RT5670_MONO_ADC_R_SRC_SFT		2
++#define RT5670_MONO_DMIC_R_SRC_MASK		(0x3)
++#define RT5670_MONO_DMIC_R_SRC_SFT		0
++
++/* ADC Mixer to DAC Mixer Control (0x29) */
++#define RT5670_M_ADCMIX_L			(0x1 << 15)
++#define RT5670_M_ADCMIX_L_SFT			15
++#define RT5670_M_DAC1_L				(0x1 << 14)
++#define RT5670_M_DAC1_L_SFT			14
++#define RT5670_DAC1_R_SEL_MASK			(0x3 << 10)
++#define RT5670_DAC1_R_SEL_SFT			10
++#define RT5670_DAC1_R_SEL_IF1			(0x0 << 10)
++#define RT5670_DAC1_R_SEL_IF2			(0x1 << 10)
++#define RT5670_DAC1_R_SEL_IF3			(0x2 << 10)
++#define RT5670_DAC1_R_SEL_IF4			(0x3 << 10)
++#define RT5670_DAC1_L_SEL_MASK			(0x3 << 8)
++#define RT5670_DAC1_L_SEL_SFT			8
++#define RT5670_DAC1_L_SEL_IF1			(0x0 << 8)
++#define RT5670_DAC1_L_SEL_IF2			(0x1 << 8)
++#define RT5670_DAC1_L_SEL_IF3			(0x2 << 8)
++#define RT5670_DAC1_L_SEL_IF4			(0x3 << 8)
++#define RT5670_M_ADCMIX_R			(0x1 << 7)
++#define RT5670_M_ADCMIX_R_SFT			7
++#define RT5670_M_DAC1_R				(0x1 << 6)
++#define RT5670_M_DAC1_R_SFT			6
++
++/* Stereo DAC Mixer Control (0x2a) */
++#define RT5670_M_DAC_L1				(0x1 << 14)
++#define RT5670_M_DAC_L1_SFT			14
++#define RT5670_DAC_L1_STO_L_VOL_MASK		(0x1 << 13)
++#define RT5670_DAC_L1_STO_L_VOL_SFT		13
++#define RT5670_M_DAC_L2				(0x1 << 12)
++#define RT5670_M_DAC_L2_SFT			12
++#define RT5670_DAC_L2_STO_L_VOL_MASK		(0x1 << 11)
++#define RT5670_DAC_L2_STO_L_VOL_SFT		11
++#define RT5670_M_DAC_R1_STO_L			(0x1 << 9)
++#define RT5670_M_DAC_R1_STO_L_SFT		9
++#define RT5670_DAC_R1_STO_L_VOL_MASK		(0x1 << 8)
++#define RT5670_DAC_R1_STO_L_VOL_SFT		8
++#define RT5670_M_DAC_R1				(0x1 << 6)
++#define RT5670_M_DAC_R1_SFT			6
++#define RT5670_DAC_R1_STO_R_VOL_MASK		(0x1 << 5)
++#define RT5670_DAC_R1_STO_R_VOL_SFT		5
++#define RT5670_M_DAC_R2				(0x1 << 4)
++#define RT5670_M_DAC_R2_SFT			4
++#define RT5670_DAC_R2_STO_R_VOL_MASK		(0x1 << 3)
++#define RT5670_DAC_R2_STO_R_VOL_SFT		3
++#define RT5670_M_DAC_L1_STO_R			(0x1 << 1)
++#define RT5670_M_DAC_L1_STO_R_SFT		1
++#define RT5670_DAC_L1_STO_R_VOL_MASK		(0x1)
++#define RT5670_DAC_L1_STO_R_VOL_SFT		0
++
++/* Mono DAC Mixer Control (0x2b) */
++#define RT5670_M_DAC_L1_MONO_L			(0x1 << 14)
++#define RT5670_M_DAC_L1_MONO_L_SFT		14
++#define RT5670_DAC_L1_MONO_L_VOL_MASK		(0x1 << 13)
++#define RT5670_DAC_L1_MONO_L_VOL_SFT		13
++#define RT5670_M_DAC_L2_MONO_L			(0x1 << 12)
++#define RT5670_M_DAC_L2_MONO_L_SFT		12
++#define RT5670_DAC_L2_MONO_L_VOL_MASK		(0x1 << 11)
++#define RT5670_DAC_L2_MONO_L_VOL_SFT		11
++#define RT5670_M_DAC_R2_MONO_L			(0x1 << 10)
++#define RT5670_M_DAC_R2_MONO_L_SFT		10
++#define RT5670_DAC_R2_MONO_L_VOL_MASK		(0x1 << 9)
++#define RT5670_DAC_R2_MONO_L_VOL_SFT		9
++#define RT5670_M_DAC_R1_MONO_R			(0x1 << 6)
++#define RT5670_M_DAC_R1_MONO_R_SFT		6
++#define RT5670_DAC_R1_MONO_R_VOL_MASK		(0x1 << 5)
++#define RT5670_DAC_R1_MONO_R_VOL_SFT		5
++#define RT5670_M_DAC_R2_MONO_R			(0x1 << 4)
++#define RT5670_M_DAC_R2_MONO_R_SFT		4
++#define RT5670_DAC_R2_MONO_R_VOL_MASK		(0x1 << 3)
++#define RT5670_DAC_R2_MONO_R_VOL_SFT		3
++#define RT5670_M_DAC_L2_MONO_R			(0x1 << 2)
++#define RT5670_M_DAC_L2_MONO_R_SFT		2
++#define RT5670_DAC_L2_MONO_R_VOL_MASK		(0x1 << 1)
++#define RT5670_DAC_L2_MONO_R_VOL_SFT		1
++
++/* Digital Mixer Control (0x2c) */
++#define RT5670_M_STO_L_DAC_L			(0x1 << 15)
++#define RT5670_M_STO_L_DAC_L_SFT		15
++#define RT5670_STO_L_DAC_L_VOL_MASK		(0x1 << 14)
++#define RT5670_STO_L_DAC_L_VOL_SFT		14
++#define RT5670_M_DAC_L2_DAC_L			(0x1 << 13)
++#define RT5670_M_DAC_L2_DAC_L_SFT		13
++#define RT5670_DAC_L2_DAC_L_VOL_MASK		(0x1 << 12)
++#define RT5670_DAC_L2_DAC_L_VOL_SFT		12
++#define RT5670_M_STO_R_DAC_R			(0x1 << 11)
++#define RT5670_M_STO_R_DAC_R_SFT		11
++#define RT5670_STO_R_DAC_R_VOL_MASK		(0x1 << 10)
++#define RT5670_STO_R_DAC_R_VOL_SFT		10
++#define RT5670_M_DAC_R2_DAC_R			(0x1 << 9)
++#define RT5670_M_DAC_R2_DAC_R_SFT		9
++#define RT5670_DAC_R2_DAC_R_VOL_MASK		(0x1 << 8)
++#define RT5670_DAC_R2_DAC_R_VOL_SFT		8
++#define RT5670_M_DAC_R2_DAC_L			(0x1 << 7)
++#define RT5670_M_DAC_R2_DAC_L_SFT		7
++#define RT5670_DAC_R2_DAC_L_VOL_MASK		(0x1 << 6)
++#define RT5670_DAC_R2_DAC_L_VOL_SFT		6
++#define RT5670_M_DAC_L2_DAC_R			(0x1 << 5)
++#define RT5670_M_DAC_L2_DAC_R_SFT		5
++#define RT5670_DAC_L2_DAC_R_VOL_MASK		(0x1 << 4)
++#define RT5670_DAC_L2_DAC_R_VOL_SFT		4
++
++/* DSP Path Control 1 (0x2d) */
++#define RT5670_RXDP_SEL_MASK			(0x7 << 13)
++#define RT5670_RXDP_SEL_SFT			13
++#define RT5670_RXDP_SRC_MASK			(0x1 << 15)
++#define RT5670_RXDP_SRC_SFT			15
++#define RT5670_RXDP_SRC_NOR			(0x0 << 15)
++#define RT5670_RXDP_SRC_DIV3			(0x1 << 15)
++#define RT5670_TXDP_SRC_MASK			(0x1 << 14)
++#define RT5670_TXDP_SRC_SFT			14
++#define RT5670_TXDP_SRC_NOR			(0x0 << 14)
++#define RT5670_TXDP_SRC_DIV3			(0x1 << 14)
++#define RT5670_DSP_UL_SEL			(0x1 << 1)
++#define RT5670_DSP_UL_SFT			1
++#define RT5670_DSP_DL_SEL			0x1
++#define RT5670_DSP_DL_SFT			0
++
++/* DSP Path Control 2 (0x2e) */
++#define RT5670_TXDP_L_VOL_MASK			(0x7f << 8)
++#define RT5670_TXDP_L_VOL_SFT			8
++#define RT5670_TXDP_R_VOL_MASK			(0x7f)
++#define RT5670_TXDP_R_VOL_SFT			0
++
++/* Digital Interface Data Control (0x2f) */
++#define RT5670_IF1_ADC2_IN_SEL			(0x1 << 15)
++#define RT5670_IF1_ADC2_IN_SFT			15
++#define RT5670_IF2_ADC_IN_MASK			(0x7 << 12)
++#define RT5670_IF2_ADC_IN_SFT			12
++#define RT5670_IF2_DAC_SEL_MASK			(0x3 << 10)
++#define RT5670_IF2_DAC_SEL_SFT			10
++#define RT5670_IF2_ADC_SEL_MASK			(0x3 << 8)
++#define RT5670_IF2_ADC_SEL_SFT			8
++
++/* Digital Interface Data Control (0x30) */
++#define RT5670_IF4_ADC_IN_MASK			(0x3 << 4)
++#define RT5670_IF4_ADC_IN_SFT			4
++
++/* PDM Output Control (0x31) */
++#define RT5670_PDM1_L_MASK			(0x1 << 15)
++#define RT5670_PDM1_L_SFT			15
++#define RT5670_M_PDM1_L				(0x1 << 14)
++#define RT5670_M_PDM1_L_SFT			14
++#define RT5670_PDM1_R_MASK			(0x1 << 13)
++#define RT5670_PDM1_R_SFT			13
++#define RT5670_M_PDM1_R				(0x1 << 12)
++#define RT5670_M_PDM1_R_SFT			12
++#define RT5670_PDM2_L_MASK			(0x1 << 11)
++#define RT5670_PDM2_L_SFT			11
++#define RT5670_M_PDM2_L				(0x1 << 10)
++#define RT5670_M_PDM2_L_SFT			10
++#define RT5670_PDM2_R_MASK			(0x1 << 9)
++#define RT5670_PDM2_R_SFT			9
++#define RT5670_M_PDM2_R				(0x1 << 8)
++#define RT5670_M_PDM2_R_SFT			8
++#define RT5670_PDM2_BUSY			(0x1 << 7)
++#define RT5670_PDM1_BUSY			(0x1 << 6)
++#define RT5670_PDM_PATTERN			(0x1 << 5)
++#define RT5670_PDM_GAIN				(0x1 << 4)
++#define RT5670_PDM_DIV_MASK			(0x3)
++
++/* REC Left Mixer Control 1 (0x3b) */
++#define RT5670_G_HP_L_RM_L_MASK			(0x7 << 13)
++#define RT5670_G_HP_L_RM_L_SFT			13
++#define RT5670_G_IN_L_RM_L_MASK			(0x7 << 10)
++#define RT5670_G_IN_L_RM_L_SFT			10
++#define RT5670_G_BST4_RM_L_MASK			(0x7 << 7)
++#define RT5670_G_BST4_RM_L_SFT			7
++#define RT5670_G_BST3_RM_L_MASK			(0x7 << 4)
++#define RT5670_G_BST3_RM_L_SFT			4
++#define RT5670_G_BST2_RM_L_MASK			(0x7 << 1)
++#define RT5670_G_BST2_RM_L_SFT			1
++
++/* REC Left Mixer Control 2 (0x3c) */
++#define RT5670_G_BST1_RM_L_MASK			(0x7 << 13)
++#define RT5670_G_BST1_RM_L_SFT			13
++#define RT5670_M_IN_L_RM_L			(0x1 << 5)
++#define RT5670_M_IN_L_RM_L_SFT			5
++#define RT5670_M_BST2_RM_L			(0x1 << 3)
++#define RT5670_M_BST2_RM_L_SFT			3
++#define RT5670_M_BST1_RM_L			(0x1 << 1)
++#define RT5670_M_BST1_RM_L_SFT			1
++
++/* REC Right Mixer Control 1 (0x3d) */
++#define RT5670_G_HP_R_RM_R_MASK			(0x7 << 13)
++#define RT5670_G_HP_R_RM_R_SFT			13
++#define RT5670_G_IN_R_RM_R_MASK			(0x7 << 10)
++#define RT5670_G_IN_R_RM_R_SFT			10
++#define RT5670_G_BST4_RM_R_MASK			(0x7 << 7)
++#define RT5670_G_BST4_RM_R_SFT			7
++#define RT5670_G_BST3_RM_R_MASK			(0x7 << 4)
++#define RT5670_G_BST3_RM_R_SFT			4
++#define RT5670_G_BST2_RM_R_MASK			(0x7 << 1)
++#define RT5670_G_BST2_RM_R_SFT			1
++
++/* REC Right Mixer Control 2 (0x3e) */
++#define RT5670_G_BST1_RM_R_MASK			(0x7 << 13)
++#define RT5670_G_BST1_RM_R_SFT			13
++#define RT5670_M_IN_R_RM_R			(0x1 << 5)
++#define RT5670_M_IN_R_RM_R_SFT			5
++#define RT5670_M_BST2_RM_R			(0x1 << 3)
++#define RT5670_M_BST2_RM_R_SFT			3
++#define RT5670_M_BST1_RM_R			(0x1 << 1)
++#define RT5670_M_BST1_RM_R_SFT			1
++
++/* HPMIX Control (0x45) */
++#define RT5670_M_DAC2_HM			(0x1 << 15)
++#define RT5670_M_DAC2_HM_SFT			15
++#define RT5670_M_HPVOL_HM			(0x1 << 14)
++#define RT5670_M_HPVOL_HM_SFT			14
++#define RT5670_M_DAC1_HM			(0x1 << 13)
++#define RT5670_M_DAC1_HM_SFT			13
++#define RT5670_G_HPOMIX_MASK			(0x1 << 12)
++#define RT5670_G_HPOMIX_SFT			12
++#define RT5670_M_INR1_HMR			(0x1 << 3)
++#define RT5670_M_INR1_HMR_SFT			3
++#define RT5670_M_DACR1_HMR			(0x1 << 2)
++#define RT5670_M_DACR1_HMR_SFT			2
++#define RT5670_M_INL1_HML			(0x1 << 1)
++#define RT5670_M_INL1_HML_SFT			1
++#define RT5670_M_DACL1_HML			(0x1)
++#define RT5670_M_DACL1_HML_SFT			0
++
++/* Mono Output Mixer Control (0x4c) */
++#define RT5670_M_DAC_R2_MA			(0x1 << 15)
++#define RT5670_M_DAC_R2_MA_SFT			15
++#define RT5670_M_DAC_L2_MA			(0x1 << 14)
++#define RT5670_M_DAC_L2_MA_SFT			14
++#define RT5670_M_OV_R_MM			(0x1 << 13)
++#define RT5670_M_OV_R_MM_SFT			13
++#define RT5670_M_OV_L_MM			(0x1 << 12)
++#define RT5670_M_OV_L_MM_SFT			12
++#define RT5670_G_MONOMIX_MASK			(0x1 << 10)
++#define RT5670_G_MONOMIX_SFT			10
++#define RT5670_M_DAC_R2_MM			(0x1 << 9)
++#define RT5670_M_DAC_R2_MM_SFT			9
++#define RT5670_M_DAC_L2_MM			(0x1 << 8)
++#define RT5670_M_DAC_L2_MM_SFT			8
++#define RT5670_M_BST4_MM			(0x1 << 7)
++#define RT5670_M_BST4_MM_SFT			7
++
++/* Output Left Mixer Control 1 (0x4d) */
++#define RT5670_G_BST3_OM_L_MASK			(0x7 << 13)
++#define RT5670_G_BST3_OM_L_SFT			13
++#define RT5670_G_BST2_OM_L_MASK			(0x7 << 10)
++#define RT5670_G_BST2_OM_L_SFT			10
++#define RT5670_G_BST1_OM_L_MASK			(0x7 << 7)
++#define RT5670_G_BST1_OM_L_SFT			7
++#define RT5670_G_IN_L_OM_L_MASK			(0x7 << 4)
++#define RT5670_G_IN_L_OM_L_SFT			4
++#define RT5670_G_RM_L_OM_L_MASK			(0x7 << 1)
++#define RT5670_G_RM_L_OM_L_SFT			1
++
++/* Output Left Mixer Control 2 (0x4e) */
++#define RT5670_G_DAC_R2_OM_L_MASK		(0x7 << 13)
++#define RT5670_G_DAC_R2_OM_L_SFT		13
++#define RT5670_G_DAC_L2_OM_L_MASK		(0x7 << 10)
++#define RT5670_G_DAC_L2_OM_L_SFT		10
++#define RT5670_G_DAC_L1_OM_L_MASK		(0x7 << 7)
++#define RT5670_G_DAC_L1_OM_L_SFT		7
++
++/* Output Left Mixer Control 3 (0x4f) */
++#define RT5670_M_BST1_OM_L			(0x1 << 5)
++#define RT5670_M_BST1_OM_L_SFT			5
++#define RT5670_M_IN_L_OM_L			(0x1 << 4)
++#define RT5670_M_IN_L_OM_L_SFT			4
++#define RT5670_M_DAC_L2_OM_L			(0x1 << 1)
++#define RT5670_M_DAC_L2_OM_L_SFT		1
++#define RT5670_M_DAC_L1_OM_L			(0x1)
++#define RT5670_M_DAC_L1_OM_L_SFT		0
++
++/* Output Right Mixer Control 1 (0x50) */
++#define RT5670_G_BST4_OM_R_MASK			(0x7 << 13)
++#define RT5670_G_BST4_OM_R_SFT			13
++#define RT5670_G_BST2_OM_R_MASK			(0x7 << 10)
++#define RT5670_G_BST2_OM_R_SFT			10
++#define RT5670_G_BST1_OM_R_MASK			(0x7 << 7)
++#define RT5670_G_BST1_OM_R_SFT			7
++#define RT5670_G_IN_R_OM_R_MASK			(0x7 << 4)
++#define RT5670_G_IN_R_OM_R_SFT			4
++#define RT5670_G_RM_R_OM_R_MASK			(0x7 << 1)
++#define RT5670_G_RM_R_OM_R_SFT			1
++
++/* Output Right Mixer Control 2 (0x51) */
++#define RT5670_G_DAC_L2_OM_R_MASK		(0x7 << 13)
++#define RT5670_G_DAC_L2_OM_R_SFT		13
++#define RT5670_G_DAC_R2_OM_R_MASK		(0x7 << 10)
++#define RT5670_G_DAC_R2_OM_R_SFT		10
++#define RT5670_G_DAC_R1_OM_R_MASK		(0x7 << 7)
++#define RT5670_G_DAC_R1_OM_R_SFT		7
++
++/* Output Right Mixer Control 3 (0x52) */
++#define RT5670_M_BST2_OM_R			(0x1 << 6)
++#define RT5670_M_BST2_OM_R_SFT			6
++#define RT5670_M_IN_R_OM_R			(0x1 << 4)
++#define RT5670_M_IN_R_OM_R_SFT			4
++#define RT5670_M_DAC_R2_OM_R			(0x1 << 1)
++#define RT5670_M_DAC_R2_OM_R_SFT		1
++#define RT5670_M_DAC_R1_OM_R			(0x1)
++#define RT5670_M_DAC_R1_OM_R_SFT		0
++
++/* LOUT Mixer Control (0x53) */
++#define RT5670_M_DAC_L1_LM			(0x1 << 15)
++#define RT5670_M_DAC_L1_LM_SFT			15
++#define RT5670_M_DAC_R1_LM			(0x1 << 14)
++#define RT5670_M_DAC_R1_LM_SFT			14
++#define RT5670_M_OV_L_LM			(0x1 << 13)
++#define RT5670_M_OV_L_LM_SFT			13
++#define RT5670_M_OV_R_LM			(0x1 << 12)
++#define RT5670_M_OV_R_LM_SFT			12
++#define RT5670_G_LOUTMIX_MASK			(0x1 << 11)
++#define RT5670_G_LOUTMIX_SFT			11
++
++/* Power Management for Digital 1 (0x61) */
++#define RT5670_PWR_I2S1				(0x1 << 15)
++#define RT5670_PWR_I2S1_BIT			15
++#define RT5670_PWR_I2S2				(0x1 << 14)
++#define RT5670_PWR_I2S2_BIT			14
++#define RT5670_PWR_DAC_L1			(0x1 << 12)
++#define RT5670_PWR_DAC_L1_BIT			12
++#define RT5670_PWR_DAC_R1			(0x1 << 11)
++#define RT5670_PWR_DAC_R1_BIT			11
++#define RT5670_PWR_DAC_L2			(0x1 << 7)
++#define RT5670_PWR_DAC_L2_BIT			7
++#define RT5670_PWR_DAC_R2			(0x1 << 6)
++#define RT5670_PWR_DAC_R2_BIT			6
++#define RT5670_PWR_ADC_L			(0x1 << 2)
++#define RT5670_PWR_ADC_L_BIT			2
++#define RT5670_PWR_ADC_R			(0x1 << 1)
++#define RT5670_PWR_ADC_R_BIT			1
++#define RT5670_PWR_CLS_D			(0x1)
++#define RT5670_PWR_CLS_D_BIT			0
++
++/* Power Management for Digital 2 (0x62) */
++#define RT5670_PWR_ADC_S1F			(0x1 << 15)
++#define RT5670_PWR_ADC_S1F_BIT			15
++#define RT5670_PWR_ADC_MF_L			(0x1 << 14)
++#define RT5670_PWR_ADC_MF_L_BIT			14
++#define RT5670_PWR_ADC_MF_R			(0x1 << 13)
++#define RT5670_PWR_ADC_MF_R_BIT			13
++#define RT5670_PWR_I2S_DSP			(0x1 << 12)
++#define RT5670_PWR_I2S_DSP_BIT			12
++#define RT5670_PWR_DAC_S1F			(0x1 << 11)
++#define RT5670_PWR_DAC_S1F_BIT			11
++#define RT5670_PWR_DAC_MF_L			(0x1 << 10)
++#define RT5670_PWR_DAC_MF_L_BIT			10
++#define RT5670_PWR_DAC_MF_R			(0x1 << 9)
++#define RT5670_PWR_DAC_MF_R_BIT			9
++#define RT5670_PWR_ADC_S2F			(0x1 << 8)
++#define RT5670_PWR_ADC_S2F_BIT			8
++#define RT5670_PWR_PDM1				(0x1 << 7)
++#define RT5670_PWR_PDM1_BIT			7
++#define RT5670_PWR_PDM2				(0x1 << 6)
++#define RT5670_PWR_PDM2_BIT			6
++
++/* Power Management for Analog 1 (0x63) */
++#define RT5670_PWR_VREF1			(0x1 << 15)
++#define RT5670_PWR_VREF1_BIT			15
++#define RT5670_PWR_FV1				(0x1 << 14)
++#define RT5670_PWR_FV1_BIT			14
++#define RT5670_PWR_MB				(0x1 << 13)
++#define RT5670_PWR_MB_BIT			13
++#define RT5670_PWR_LM				(0x1 << 12)
++#define RT5670_PWR_LM_BIT			12
++#define RT5670_PWR_BG				(0x1 << 11)
++#define RT5670_PWR_BG_BIT			11
++#define RT5670_PWR_HP_L				(0x1 << 7)
++#define RT5670_PWR_HP_L_BIT			7
++#define RT5670_PWR_HP_R				(0x1 << 6)
++#define RT5670_PWR_HP_R_BIT			6
++#define RT5670_PWR_HA				(0x1 << 5)
++#define RT5670_PWR_HA_BIT			5
++#define RT5670_PWR_VREF2			(0x1 << 4)
++#define RT5670_PWR_VREF2_BIT			4
++#define RT5670_PWR_FV2				(0x1 << 3)
++#define RT5670_PWR_FV2_BIT			3
++#define RT5670_LDO_SEL_MASK			(0x3)
++#define RT5670_LDO_SEL_SFT			0
++
++/* Power Management for Analog 2 (0x64) */
++#define RT5670_PWR_BST1				(0x1 << 15)
++#define RT5670_PWR_BST1_BIT			15
++#define RT5670_PWR_BST2				(0x1 << 13)
++#define RT5670_PWR_BST2_BIT			13
++#define RT5670_PWR_MB1				(0x1 << 11)
++#define RT5670_PWR_MB1_BIT			11
++#define RT5670_PWR_MB2				(0x1 << 10)
++#define RT5670_PWR_MB2_BIT			10
++#define RT5670_PWR_PLL				(0x1 << 9)
++#define RT5670_PWR_PLL_BIT			9
++#define RT5670_PWR_BST1_P			(0x1 << 6)
++#define RT5670_PWR_BST1_P_BIT			6
++#define RT5670_PWR_BST2_P			(0x1 << 4)
++#define RT5670_PWR_BST2_P_BIT			4
++#define RT5670_PWR_JD1				(0x1 << 2)
++#define RT5670_PWR_JD1_BIT			2
++#define RT5670_PWR_JD				(0x1 << 1)
++#define RT5670_PWR_JD_BIT			1
++
++/* Power Management for Mixer (0x65) */
++#define RT5670_PWR_OM_L				(0x1 << 15)
++#define RT5670_PWR_OM_L_BIT			15
++#define RT5670_PWR_OM_R				(0x1 << 14)
++#define RT5670_PWR_OM_R_BIT			14
++#define RT5670_PWR_RM_L				(0x1 << 11)
++#define RT5670_PWR_RM_L_BIT			11
++#define RT5670_PWR_RM_R				(0x1 << 10)
++#define RT5670_PWR_RM_R_BIT			10
++
++/* Power Management for Volume (0x66) */
++#define RT5670_PWR_HV_L				(0x1 << 11)
++#define RT5670_PWR_HV_L_BIT			11
++#define RT5670_PWR_HV_R				(0x1 << 10)
++#define RT5670_PWR_HV_R_BIT			10
++#define RT5670_PWR_IN_L				(0x1 << 9)
++#define RT5670_PWR_IN_L_BIT			9
++#define RT5670_PWR_IN_R				(0x1 << 8)
++#define RT5670_PWR_IN_R_BIT			8
++#define RT5670_PWR_MIC_DET			(0x1 << 5)
++#define RT5670_PWR_MIC_DET_BIT			5
++
++/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71 0x72) */
++#define RT5670_I2S_MS_MASK			(0x1 << 15)
++#define RT5670_I2S_MS_SFT			15
++#define RT5670_I2S_MS_M				(0x0 << 15)
++#define RT5670_I2S_MS_S				(0x1 << 15)
++#define RT5670_I2S_IF_MASK			(0x7 << 12)
++#define RT5670_I2S_IF_SFT			12
++#define RT5670_I2S_O_CP_MASK			(0x3 << 10)
++#define RT5670_I2S_O_CP_SFT			10
++#define RT5670_I2S_O_CP_OFF			(0x0 << 10)
++#define RT5670_I2S_O_CP_U_LAW			(0x1 << 10)
++#define RT5670_I2S_O_CP_A_LAW			(0x2 << 10)
++#define RT5670_I2S_I_CP_MASK			(0x3 << 8)
++#define RT5670_I2S_I_CP_SFT			8
++#define RT5670_I2S_I_CP_OFF			(0x0 << 8)
++#define RT5670_I2S_I_CP_U_LAW			(0x1 << 8)
++#define RT5670_I2S_I_CP_A_LAW			(0x2 << 8)
++#define RT5670_I2S_BP_MASK			(0x1 << 7)
++#define RT5670_I2S_BP_SFT			7
++#define RT5670_I2S_BP_NOR			(0x0 << 7)
++#define RT5670_I2S_BP_INV			(0x1 << 7)
++#define RT5670_I2S_DL_MASK			(0x3 << 2)
++#define RT5670_I2S_DL_SFT			2
++#define RT5670_I2S_DL_16			(0x0 << 2)
++#define RT5670_I2S_DL_20			(0x1 << 2)
++#define RT5670_I2S_DL_24			(0x2 << 2)
++#define RT5670_I2S_DL_8				(0x3 << 2)
++#define RT5670_I2S_DF_MASK			(0x3)
++#define RT5670_I2S_DF_SFT			0
++#define RT5670_I2S_DF_I2S			(0x0)
++#define RT5670_I2S_DF_LEFT			(0x1)
++#define RT5670_I2S_DF_PCM_A			(0x2)
++#define RT5670_I2S_DF_PCM_B			(0x3)
++
++/* I2S2 Audio Serial Data Port Control (0x71) */
++#define RT5670_I2S2_SDI_MASK			(0x1 << 6)
++#define RT5670_I2S2_SDI_SFT			6
++#define RT5670_I2S2_SDI_I2S1			(0x0 << 6)
++#define RT5670_I2S2_SDI_I2S2			(0x1 << 6)
++
++/* ADC/DAC Clock Control 1 (0x73) */
++#define RT5670_I2S_BCLK_MS1_MASK		(0x1 << 15)
++#define RT5670_I2S_BCLK_MS1_SFT			15
++#define RT5670_I2S_BCLK_MS1_32			(0x0 << 15)
++#define RT5670_I2S_BCLK_MS1_64			(0x1 << 15)
++#define RT5670_I2S_PD1_MASK			(0x7 << 12)
++#define RT5670_I2S_PD1_SFT			12
++#define RT5670_I2S_PD1_1			(0x0 << 12)
++#define RT5670_I2S_PD1_2			(0x1 << 12)
++#define RT5670_I2S_PD1_3			(0x2 << 12)
++#define RT5670_I2S_PD1_4			(0x3 << 12)
++#define RT5670_I2S_PD1_6			(0x4 << 12)
++#define RT5670_I2S_PD1_8			(0x5 << 12)
++#define RT5670_I2S_PD1_12			(0x6 << 12)
++#define RT5670_I2S_PD1_16			(0x7 << 12)
++#define RT5670_I2S_BCLK_MS2_MASK		(0x1 << 11)
++#define RT5670_I2S_BCLK_MS2_SFT			11
++#define RT5670_I2S_BCLK_MS2_32			(0x0 << 11)
++#define RT5670_I2S_BCLK_MS2_64			(0x1 << 11)
++#define RT5670_I2S_PD2_MASK			(0x7 << 8)
++#define RT5670_I2S_PD2_SFT			8
++#define RT5670_I2S_PD2_1			(0x0 << 8)
++#define RT5670_I2S_PD2_2			(0x1 << 8)
++#define RT5670_I2S_PD2_3			(0x2 << 8)
++#define RT5670_I2S_PD2_4			(0x3 << 8)
++#define RT5670_I2S_PD2_6			(0x4 << 8)
++#define RT5670_I2S_PD2_8			(0x5 << 8)
++#define RT5670_I2S_PD2_12			(0x6 << 8)
++#define RT5670_I2S_PD2_16			(0x7 << 8)
++#define RT5670_I2S_BCLK_MS3_MASK		(0x1 << 7)
++#define RT5670_I2S_BCLK_MS3_SFT			7
++#define RT5670_I2S_BCLK_MS3_32			(0x0 << 7)
++#define RT5670_I2S_BCLK_MS3_64			(0x1 << 7)
++#define RT5670_I2S_PD3_MASK			(0x7 << 4)
++#define RT5670_I2S_PD3_SFT			4
++#define RT5670_I2S_PD3_1			(0x0 << 4)
++#define RT5670_I2S_PD3_2			(0x1 << 4)
++#define RT5670_I2S_PD3_3			(0x2 << 4)
++#define RT5670_I2S_PD3_4			(0x3 << 4)
++#define RT5670_I2S_PD3_6			(0x4 << 4)
++#define RT5670_I2S_PD3_8			(0x5 << 4)
++#define RT5670_I2S_PD3_12			(0x6 << 4)
++#define RT5670_I2S_PD3_16			(0x7 << 4)
++#define RT5670_DAC_OSR_MASK			(0x3 << 2)
++#define RT5670_DAC_OSR_SFT			2
++#define RT5670_DAC_OSR_128			(0x0 << 2)
++#define RT5670_DAC_OSR_64			(0x1 << 2)
++#define RT5670_DAC_OSR_32			(0x2 << 2)
++#define RT5670_DAC_OSR_16			(0x3 << 2)
++#define RT5670_ADC_OSR_MASK			(0x3)
++#define RT5670_ADC_OSR_SFT			0
++#define RT5670_ADC_OSR_128			(0x0)
++#define RT5670_ADC_OSR_64			(0x1)
++#define RT5670_ADC_OSR_32			(0x2)
++#define RT5670_ADC_OSR_16			(0x3)
++
++/* ADC/DAC Clock Control 2 (0x74) */
++#define RT5670_DAC_L_OSR_MASK			(0x3 << 14)
++#define RT5670_DAC_L_OSR_SFT			14
++#define RT5670_DAC_L_OSR_128			(0x0 << 14)
++#define RT5670_DAC_L_OSR_64			(0x1 << 14)
++#define RT5670_DAC_L_OSR_32			(0x2 << 14)
++#define RT5670_DAC_L_OSR_16			(0x3 << 14)
++#define RT5670_ADC_R_OSR_MASK			(0x3 << 12)
++#define RT5670_ADC_R_OSR_SFT			12
++#define RT5670_ADC_R_OSR_128			(0x0 << 12)
++#define RT5670_ADC_R_OSR_64			(0x1 << 12)
++#define RT5670_ADC_R_OSR_32			(0x2 << 12)
++#define RT5670_ADC_R_OSR_16			(0x3 << 12)
++#define RT5670_DAHPF_EN				(0x1 << 11)
++#define RT5670_DAHPF_EN_SFT			11
++#define RT5670_ADHPF_EN				(0x1 << 10)
++#define RT5670_ADHPF_EN_SFT			10
++
++/* Digital Microphone Control (0x75) */
++#define RT5670_DMIC_1_EN_MASK			(0x1 << 15)
++#define RT5670_DMIC_1_EN_SFT			15
++#define RT5670_DMIC_1_DIS			(0x0 << 15)
++#define RT5670_DMIC_1_EN			(0x1 << 15)
++#define RT5670_DMIC_2_EN_MASK			(0x1 << 14)
++#define RT5670_DMIC_2_EN_SFT			14
++#define RT5670_DMIC_2_DIS			(0x0 << 14)
++#define RT5670_DMIC_2_EN			(0x1 << 14)
++#define RT5670_DMIC_1L_LH_MASK			(0x1 << 13)
++#define RT5670_DMIC_1L_LH_SFT			13
++#define RT5670_DMIC_1L_LH_FALLING		(0x0 << 13)
++#define RT5670_DMIC_1L_LH_RISING		(0x1 << 13)
++#define RT5670_DMIC_1R_LH_MASK			(0x1 << 12)
++#define RT5670_DMIC_1R_LH_SFT			12
++#define RT5670_DMIC_1R_LH_FALLING		(0x0 << 12)
++#define RT5670_DMIC_1R_LH_RISING		(0x1 << 12)
++#define RT5670_DMIC_2_DP_MASK			(0x1 << 10)
++#define RT5670_DMIC_2_DP_SFT			10
++#define RT5670_DMIC_2_DP_GPIO4			(0x0 << 10)
++#define RT5670_DMIC_2_DP_IN1N			(0x1 << 10)
++#define RT5670_DMIC_2L_LH_MASK			(0x1 << 9)
++#define RT5670_DMIC_2L_LH_SFT			9
++#define RT5670_DMIC_2L_LH_FALLING		(0x0 << 9)
++#define RT5670_DMIC_2L_LH_RISING		(0x1 << 9)
++#define RT5670_DMIC_2R_LH_MASK			(0x1 << 8)
++#define RT5670_DMIC_2R_LH_SFT			8
++#define RT5670_DMIC_2R_LH_FALLING		(0x0 << 8)
++#define RT5670_DMIC_2R_LH_RISING		(0x1 << 8)
++#define RT5670_DMIC_CLK_MASK			(0x7 << 5)
++#define RT5670_DMIC_CLK_SFT			5
++#define RT5670_DMIC_3_EN_MASK			(0x1 << 4)
++#define RT5670_DMIC_3_EN_SFT			4
++#define RT5670_DMIC_3_DIS			(0x0 << 4)
++#define RT5670_DMIC_3_EN			(0x1 << 4)
++#define RT5670_DMIC_1_DP_MASK			(0x3 << 0)
++#define RT5670_DMIC_1_DP_SFT			0
++#define RT5670_DMIC_1_DP_GPIO6			(0x0 << 0)
++#define RT5670_DMIC_1_DP_IN2P			(0x1 << 0)
++#define RT5670_DMIC_1_DP_GPIO7			(0x2 << 0)
++
++/* Global Clock Control (0x80) */
++#define RT5670_SCLK_SRC_MASK			(0x3 << 14)
++#define RT5670_SCLK_SRC_SFT			14
++#define RT5670_SCLK_SRC_MCLK			(0x0 << 14)
++#define RT5670_SCLK_SRC_PLL1			(0x1 << 14)
++#define RT5670_SCLK_SRC_RCCLK			(0x2 << 14) /* 15MHz */
++#define RT5670_PLL1_SRC_MASK			(0x3 << 12)
++#define RT5670_PLL1_SRC_SFT			12
++#define RT5670_PLL1_SRC_MCLK			(0x0 << 12)
++#define RT5670_PLL1_SRC_BCLK1			(0x1 << 12)
++#define RT5670_PLL1_SRC_BCLK2			(0x2 << 12)
++#define RT5670_PLL1_SRC_BCLK3			(0x3 << 12)
++#define RT5670_PLL1_PD_MASK			(0x1 << 3)
++#define RT5670_PLL1_PD_SFT			3
++#define RT5670_PLL1_PD_1			(0x0 << 3)
++#define RT5670_PLL1_PD_2			(0x1 << 3)
++
++#define RT5670_PLL_INP_MAX			40000000
++#define RT5670_PLL_INP_MIN			256000
++/* PLL M/N/K Code Control 1 (0x81) */
++#define RT5670_PLL_N_MAX			0x1ff
++#define RT5670_PLL_N_MASK			(RT5670_PLL_N_MAX << 7)
++#define RT5670_PLL_N_SFT			7
++#define RT5670_PLL_K_MAX			0x1f
++#define RT5670_PLL_K_MASK			(RT5670_PLL_K_MAX)
++#define RT5670_PLL_K_SFT			0
++
++/* PLL M/N/K Code Control 2 (0x82) */
++#define RT5670_PLL_M_MAX			0xf
++#define RT5670_PLL_M_MASK			(RT5670_PLL_M_MAX << 12)
++#define RT5670_PLL_M_SFT			12
++#define RT5670_PLL_M_BP				(0x1 << 11)
++#define RT5670_PLL_M_BP_SFT			11
++
++/* ASRC Control 1 (0x83) */
++#define RT5670_STO_T_MASK			(0x1 << 15)
++#define RT5670_STO_T_SFT			15
++#define RT5670_STO_T_SCLK			(0x0 << 15)
++#define RT5670_STO_T_LRCK1			(0x1 << 15)
++#define RT5670_M1_T_MASK			(0x1 << 14)
++#define RT5670_M1_T_SFT				14
++#define RT5670_M1_T_I2S2			(0x0 << 14)
++#define RT5670_M1_T_I2S2_D3			(0x1 << 14)
++#define RT5670_I2S2_F_MASK			(0x1 << 12)
++#define RT5670_I2S2_F_SFT			12
++#define RT5670_I2S2_F_I2S2_D2			(0x0 << 12)
++#define RT5670_I2S2_F_I2S1_TCLK			(0x1 << 12)
++#define RT5670_DMIC_1_M_MASK			(0x1 << 9)
++#define RT5670_DMIC_1_M_SFT			9
++#define RT5670_DMIC_1_M_NOR			(0x0 << 9)
++#define RT5670_DMIC_1_M_ASYN			(0x1 << 9)
++#define RT5670_DMIC_2_M_MASK			(0x1 << 8)
++#define RT5670_DMIC_2_M_SFT			8
++#define RT5670_DMIC_2_M_NOR			(0x0 << 8)
++#define RT5670_DMIC_2_M_ASYN			(0x1 << 8)
++
++/* ASRC Control 2 (0x84) */
++#define RT5670_MDA_L_M_MASK			(0x1 << 15)
++#define RT5670_MDA_L_M_SFT			15
++#define RT5670_MDA_L_M_NOR			(0x0 << 15)
++#define RT5670_MDA_L_M_ASYN			(0x1 << 15)
++#define RT5670_MDA_R_M_MASK			(0x1 << 14)
++#define RT5670_MDA_R_M_SFT			14
++#define RT5670_MDA_R_M_NOR			(0x0 << 14)
++#define RT5670_MDA_R_M_ASYN			(0x1 << 14)
++#define RT5670_MAD_L_M_MASK			(0x1 << 13)
++#define RT5670_MAD_L_M_SFT			13
++#define RT5670_MAD_L_M_NOR			(0x0 << 13)
++#define RT5670_MAD_L_M_ASYN			(0x1 << 13)
++#define RT5670_MAD_R_M_MASK			(0x1 << 12)
++#define RT5670_MAD_R_M_SFT			12
++#define RT5670_MAD_R_M_NOR			(0x0 << 12)
++#define RT5670_MAD_R_M_ASYN			(0x1 << 12)
++#define RT5670_ADC_M_MASK			(0x1 << 11)
++#define RT5670_ADC_M_SFT			11
++#define RT5670_ADC_M_NOR			(0x0 << 11)
++#define RT5670_ADC_M_ASYN			(0x1 << 11)
++#define RT5670_STO_DAC_M_MASK			(0x1 << 5)
++#define RT5670_STO_DAC_M_SFT			5
++#define RT5670_STO_DAC_M_NOR			(0x0 << 5)
++#define RT5670_STO_DAC_M_ASYN			(0x1 << 5)
++#define RT5670_I2S1_R_D_MASK			(0x1 << 4)
++#define RT5670_I2S1_R_D_SFT			4
++#define RT5670_I2S1_R_D_DIS			(0x0 << 4)
++#define RT5670_I2S1_R_D_EN			(0x1 << 4)
++#define RT5670_I2S2_R_D_MASK			(0x1 << 3)
++#define RT5670_I2S2_R_D_SFT			3
++#define RT5670_I2S2_R_D_DIS			(0x0 << 3)
++#define RT5670_I2S2_R_D_EN			(0x1 << 3)
++#define RT5670_PRE_SCLK_MASK			(0x3)
++#define RT5670_PRE_SCLK_SFT			0
++#define RT5670_PRE_SCLK_512			(0x0)
++#define RT5670_PRE_SCLK_1024			(0x1)
++#define RT5670_PRE_SCLK_2048			(0x2)
++
++/* ASRC Control 3 (0x85) */
++#define RT5670_I2S1_RATE_MASK			(0xf << 12)
++#define RT5670_I2S1_RATE_SFT			12
++#define RT5670_I2S2_RATE_MASK			(0xf << 8)
++#define RT5670_I2S2_RATE_SFT			8
++
++/* ASRC Control 4 (0x89) */
++#define RT5670_I2S1_PD_MASK			(0x7 << 12)
++#define RT5670_I2S1_PD_SFT			12
++#define RT5670_I2S2_PD_MASK			(0x7 << 8)
++#define RT5670_I2S2_PD_SFT			8
++
++/* HPOUT Over Current Detection (0x8b) */
++#define RT5670_HP_OVCD_MASK			(0x1 << 10)
++#define RT5670_HP_OVCD_SFT			10
++#define RT5670_HP_OVCD_DIS			(0x0 << 10)
++#define RT5670_HP_OVCD_EN			(0x1 << 10)
++#define RT5670_HP_OC_TH_MASK			(0x3 << 8)
++#define RT5670_HP_OC_TH_SFT			8
++#define RT5670_HP_OC_TH_90			(0x0 << 8)
++#define RT5670_HP_OC_TH_105			(0x1 << 8)
++#define RT5670_HP_OC_TH_120			(0x2 << 8)
++#define RT5670_HP_OC_TH_135			(0x3 << 8)
++
++/* Class D Over Current Control (0x8c) */
++#define RT5670_CLSD_OC_MASK			(0x1 << 9)
++#define RT5670_CLSD_OC_SFT			9
++#define RT5670_CLSD_OC_PU			(0x0 << 9)
++#define RT5670_CLSD_OC_PD			(0x1 << 9)
++#define RT5670_AUTO_PD_MASK			(0x1 << 8)
++#define RT5670_AUTO_PD_SFT			8
++#define RT5670_AUTO_PD_DIS			(0x0 << 8)
++#define RT5670_AUTO_PD_EN			(0x1 << 8)
++#define RT5670_CLSD_OC_TH_MASK			(0x3f)
++#define RT5670_CLSD_OC_TH_SFT			0
++
++/* Class D Output Control (0x8d) */
++#define RT5670_CLSD_RATIO_MASK			(0xf << 12)
++#define RT5670_CLSD_RATIO_SFT			12
++#define RT5670_CLSD_OM_MASK			(0x1 << 11)
++#define RT5670_CLSD_OM_SFT			11
++#define RT5670_CLSD_OM_MONO			(0x0 << 11)
++#define RT5670_CLSD_OM_STO			(0x1 << 11)
++#define RT5670_CLSD_SCH_MASK			(0x1 << 10)
++#define RT5670_CLSD_SCH_SFT			10
++#define RT5670_CLSD_SCH_L			(0x0 << 10)
++#define RT5670_CLSD_SCH_S			(0x1 << 10)
++
++/* Depop Mode Control 1 (0x8e) */
++#define RT5670_SMT_TRIG_MASK			(0x1 << 15)
++#define RT5670_SMT_TRIG_SFT			15
++#define RT5670_SMT_TRIG_DIS			(0x0 << 15)
++#define RT5670_SMT_TRIG_EN			(0x1 << 15)
++#define RT5670_HP_L_SMT_MASK			(0x1 << 9)
++#define RT5670_HP_L_SMT_SFT			9
++#define RT5670_HP_L_SMT_DIS			(0x0 << 9)
++#define RT5670_HP_L_SMT_EN			(0x1 << 9)
++#define RT5670_HP_R_SMT_MASK			(0x1 << 8)
++#define RT5670_HP_R_SMT_SFT			8
++#define RT5670_HP_R_SMT_DIS			(0x0 << 8)
++#define RT5670_HP_R_SMT_EN			(0x1 << 8)
++#define RT5670_HP_CD_PD_MASK			(0x1 << 7)
++#define RT5670_HP_CD_PD_SFT			7
++#define RT5670_HP_CD_PD_DIS			(0x0 << 7)
++#define RT5670_HP_CD_PD_EN			(0x1 << 7)
++#define RT5670_RSTN_MASK			(0x1 << 6)
++#define RT5670_RSTN_SFT				6
++#define RT5670_RSTN_DIS				(0x0 << 6)
++#define RT5670_RSTN_EN				(0x1 << 6)
++#define RT5670_RSTP_MASK			(0x1 << 5)
++#define RT5670_RSTP_SFT				5
++#define RT5670_RSTP_DIS				(0x0 << 5)
++#define RT5670_RSTP_EN				(0x1 << 5)
++#define RT5670_HP_CO_MASK			(0x1 << 4)
++#define RT5670_HP_CO_SFT			4
++#define RT5670_HP_CO_DIS			(0x0 << 4)
++#define RT5670_HP_CO_EN				(0x1 << 4)
++#define RT5670_HP_CP_MASK			(0x1 << 3)
++#define RT5670_HP_CP_SFT			3
++#define RT5670_HP_CP_PD				(0x0 << 3)
++#define RT5670_HP_CP_PU				(0x1 << 3)
++#define RT5670_HP_SG_MASK			(0x1 << 2)
++#define RT5670_HP_SG_SFT			2
++#define RT5670_HP_SG_DIS			(0x0 << 2)
++#define RT5670_HP_SG_EN				(0x1 << 2)
++#define RT5670_HP_DP_MASK			(0x1 << 1)
++#define RT5670_HP_DP_SFT			1
++#define RT5670_HP_DP_PD				(0x0 << 1)
++#define RT5670_HP_DP_PU				(0x1 << 1)
++#define RT5670_HP_CB_MASK			(0x1)
++#define RT5670_HP_CB_SFT			0
++#define RT5670_HP_CB_PD				(0x0)
++#define RT5670_HP_CB_PU				(0x1)
++
++/* Depop Mode Control 2 (0x8f) */
++#define RT5670_DEPOP_MASK			(0x1 << 13)
++#define RT5670_DEPOP_SFT			13
++#define RT5670_DEPOP_AUTO			(0x0 << 13)
++#define RT5670_DEPOP_MAN			(0x1 << 13)
++#define RT5670_RAMP_MASK			(0x1 << 12)
++#define RT5670_RAMP_SFT				12
++#define RT5670_RAMP_DIS				(0x0 << 12)
++#define RT5670_RAMP_EN				(0x1 << 12)
++#define RT5670_BPS_MASK				(0x1 << 11)
++#define RT5670_BPS_SFT				11
++#define RT5670_BPS_DIS				(0x0 << 11)
++#define RT5670_BPS_EN				(0x1 << 11)
++#define RT5670_FAST_UPDN_MASK			(0x1 << 10)
++#define RT5670_FAST_UPDN_SFT			10
++#define RT5670_FAST_UPDN_DIS			(0x0 << 10)
++#define RT5670_FAST_UPDN_EN			(0x1 << 10)
++#define RT5670_MRES_MASK			(0x3 << 8)
++#define RT5670_MRES_SFT				8
++#define RT5670_MRES_15MO			(0x0 << 8)
++#define RT5670_MRES_25MO			(0x1 << 8)
++#define RT5670_MRES_35MO			(0x2 << 8)
++#define RT5670_MRES_45MO			(0x3 << 8)
++#define RT5670_VLO_MASK				(0x1 << 7)
++#define RT5670_VLO_SFT				7
++#define RT5670_VLO_3V				(0x0 << 7)
++#define RT5670_VLO_32V				(0x1 << 7)
++#define RT5670_DIG_DP_MASK			(0x1 << 6)
++#define RT5670_DIG_DP_SFT			6
++#define RT5670_DIG_DP_DIS			(0x0 << 6)
++#define RT5670_DIG_DP_EN			(0x1 << 6)
++#define RT5670_DP_TH_MASK			(0x3 << 4)
++#define RT5670_DP_TH_SFT			4
++
++/* Depop Mode Control 3 (0x90) */
++#define RT5670_CP_SYS_MASK			(0x7 << 12)
++#define RT5670_CP_SYS_SFT			12
++#define RT5670_CP_FQ1_MASK			(0x7 << 8)
++#define RT5670_CP_FQ1_SFT			8
++#define RT5670_CP_FQ2_MASK			(0x7 << 4)
++#define RT5670_CP_FQ2_SFT			4
++#define RT5670_CP_FQ3_MASK			(0x7)
++#define RT5670_CP_FQ3_SFT			0
++#define RT5670_CP_FQ_1_5_KHZ			0
++#define RT5670_CP_FQ_3_KHZ			1
++#define RT5670_CP_FQ_6_KHZ			2
++#define RT5670_CP_FQ_12_KHZ			3
++#define RT5670_CP_FQ_24_KHZ			4
++#define RT5670_CP_FQ_48_KHZ			5
++#define RT5670_CP_FQ_96_KHZ			6
++#define RT5670_CP_FQ_192_KHZ			7
++
++/* HPOUT charge pump (0x91) */
++#define RT5670_OSW_L_MASK			(0x1 << 11)
++#define RT5670_OSW_L_SFT			11
++#define RT5670_OSW_L_DIS			(0x0 << 11)
++#define RT5670_OSW_L_EN				(0x1 << 11)
++#define RT5670_OSW_R_MASK			(0x1 << 10)
++#define RT5670_OSW_R_SFT			10
++#define RT5670_OSW_R_DIS			(0x0 << 10)
++#define RT5670_OSW_R_EN				(0x1 << 10)
++#define RT5670_PM_HP_MASK			(0x3 << 8)
++#define RT5670_PM_HP_SFT			8
++#define RT5670_PM_HP_LV				(0x0 << 8)
++#define RT5670_PM_HP_MV				(0x1 << 8)
++#define RT5670_PM_HP_HV				(0x2 << 8)
++#define RT5670_IB_HP_MASK			(0x3 << 6)
++#define RT5670_IB_HP_SFT			6
++#define RT5670_IB_HP_125IL			(0x0 << 6)
++#define RT5670_IB_HP_25IL			(0x1 << 6)
++#define RT5670_IB_HP_5IL			(0x2 << 6)
++#define RT5670_IB_HP_1IL			(0x3 << 6)
++
++/* PV detection and SPK gain control (0x92) */
++#define RT5670_PVDD_DET_MASK			(0x1 << 15)
++#define RT5670_PVDD_DET_SFT			15
++#define RT5670_PVDD_DET_DIS			(0x0 << 15)
++#define RT5670_PVDD_DET_EN			(0x1 << 15)
++#define RT5670_SPK_AG_MASK			(0x1 << 14)
++#define RT5670_SPK_AG_SFT			14
++#define RT5670_SPK_AG_DIS			(0x0 << 14)
++#define RT5670_SPK_AG_EN			(0x1 << 14)
++
++/* Micbias Control (0x93) */
++#define RT5670_MIC1_BS_MASK			(0x1 << 15)
++#define RT5670_MIC1_BS_SFT			15
++#define RT5670_MIC1_BS_9AV			(0x0 << 15)
++#define RT5670_MIC1_BS_75AV			(0x1 << 15)
++#define RT5670_MIC2_BS_MASK			(0x1 << 14)
++#define RT5670_MIC2_BS_SFT			14
++#define RT5670_MIC2_BS_9AV			(0x0 << 14)
++#define RT5670_MIC2_BS_75AV			(0x1 << 14)
++#define RT5670_MIC1_CLK_MASK			(0x1 << 13)
++#define RT5670_MIC1_CLK_SFT			13
++#define RT5670_MIC1_CLK_DIS			(0x0 << 13)
++#define RT5670_MIC1_CLK_EN			(0x1 << 13)
++#define RT5670_MIC2_CLK_MASK			(0x1 << 12)
++#define RT5670_MIC2_CLK_SFT			12
++#define RT5670_MIC2_CLK_DIS			(0x0 << 12)
++#define RT5670_MIC2_CLK_EN			(0x1 << 12)
++#define RT5670_MIC1_OVCD_MASK			(0x1 << 11)
++#define RT5670_MIC1_OVCD_SFT			11
++#define RT5670_MIC1_OVCD_DIS			(0x0 << 11)
++#define RT5670_MIC1_OVCD_EN			(0x1 << 11)
++#define RT5670_MIC1_OVTH_MASK			(0x3 << 9)
++#define RT5670_MIC1_OVTH_SFT			9
++#define RT5670_MIC1_OVTH_600UA			(0x0 << 9)
++#define RT5670_MIC1_OVTH_1500UA			(0x1 << 9)
++#define RT5670_MIC1_OVTH_2000UA			(0x2 << 9)
++#define RT5670_MIC2_OVCD_MASK			(0x1 << 8)
++#define RT5670_MIC2_OVCD_SFT			8
++#define RT5670_MIC2_OVCD_DIS			(0x0 << 8)
++#define RT5670_MIC2_OVCD_EN			(0x1 << 8)
++#define RT5670_MIC2_OVTH_MASK			(0x3 << 6)
++#define RT5670_MIC2_OVTH_SFT			6
++#define RT5670_MIC2_OVTH_600UA			(0x0 << 6)
++#define RT5670_MIC2_OVTH_1500UA			(0x1 << 6)
++#define RT5670_MIC2_OVTH_2000UA			(0x2 << 6)
++#define RT5670_PWR_MB_MASK			(0x1 << 5)
++#define RT5670_PWR_MB_SFT			5
++#define RT5670_PWR_MB_PD			(0x0 << 5)
++#define RT5670_PWR_MB_PU			(0x1 << 5)
++#define RT5670_PWR_CLK25M_MASK			(0x1 << 4)
++#define RT5670_PWR_CLK25M_SFT			4
++#define RT5670_PWR_CLK25M_PD			(0x0 << 4)
++#define RT5670_PWR_CLK25M_PU			(0x1 << 4)
++
++/* VAD Control 4 (0x9d) */
++#define RT5670_VAD_SEL_MASK			(0x3 << 8)
++#define RT5670_VAD_SEL_SFT			8
++
++/* EQ Control 1 (0xb0) */
++#define RT5670_EQ_SRC_MASK			(0x1 << 15)
++#define RT5670_EQ_SRC_SFT			15
++#define RT5670_EQ_SRC_DAC			(0x0 << 15)
++#define RT5670_EQ_SRC_ADC			(0x1 << 15)
++#define RT5670_EQ_UPD				(0x1 << 14)
++#define RT5670_EQ_UPD_BIT			14
++#define RT5670_EQ_CD_MASK			(0x1 << 13)
++#define RT5670_EQ_CD_SFT			13
++#define RT5670_EQ_CD_DIS			(0x0 << 13)
++#define RT5670_EQ_CD_EN				(0x1 << 13)
++#define RT5670_EQ_DITH_MASK			(0x3 << 8)
++#define RT5670_EQ_DITH_SFT			8
++#define RT5670_EQ_DITH_NOR			(0x0 << 8)
++#define RT5670_EQ_DITH_LSB			(0x1 << 8)
++#define RT5670_EQ_DITH_LSB_1			(0x2 << 8)
++#define RT5670_EQ_DITH_LSB_2			(0x3 << 8)
++
++/* EQ Control 2 (0xb1) */
++#define RT5670_EQ_HPF1_M_MASK			(0x1 << 8)
++#define RT5670_EQ_HPF1_M_SFT			8
++#define RT5670_EQ_HPF1_M_HI			(0x0 << 8)
++#define RT5670_EQ_HPF1_M_1ST			(0x1 << 8)
++#define RT5670_EQ_LPF1_M_MASK			(0x1 << 7)
++#define RT5670_EQ_LPF1_M_SFT			7
++#define RT5670_EQ_LPF1_M_LO			(0x0 << 7)
++#define RT5670_EQ_LPF1_M_1ST			(0x1 << 7)
++#define RT5670_EQ_HPF2_MASK			(0x1 << 6)
++#define RT5670_EQ_HPF2_SFT			6
++#define RT5670_EQ_HPF2_DIS			(0x0 << 6)
++#define RT5670_EQ_HPF2_EN			(0x1 << 6)
++#define RT5670_EQ_HPF1_MASK			(0x1 << 5)
++#define RT5670_EQ_HPF1_SFT			5
++#define RT5670_EQ_HPF1_DIS			(0x0 << 5)
++#define RT5670_EQ_HPF1_EN			(0x1 << 5)
++#define RT5670_EQ_BPF4_MASK			(0x1 << 4)
++#define RT5670_EQ_BPF4_SFT			4
++#define RT5670_EQ_BPF4_DIS			(0x0 << 4)
++#define RT5670_EQ_BPF4_EN			(0x1 << 4)
++#define RT5670_EQ_BPF3_MASK			(0x1 << 3)
++#define RT5670_EQ_BPF3_SFT			3
++#define RT5670_EQ_BPF3_DIS			(0x0 << 3)
++#define RT5670_EQ_BPF3_EN			(0x1 << 3)
++#define RT5670_EQ_BPF2_MASK			(0x1 << 2)
++#define RT5670_EQ_BPF2_SFT			2
++#define RT5670_EQ_BPF2_DIS			(0x0 << 2)
++#define RT5670_EQ_BPF2_EN			(0x1 << 2)
++#define RT5670_EQ_BPF1_MASK			(0x1 << 1)
++#define RT5670_EQ_BPF1_SFT			1
++#define RT5670_EQ_BPF1_DIS			(0x0 << 1)
++#define RT5670_EQ_BPF1_EN			(0x1 << 1)
++#define RT5670_EQ_LPF_MASK			(0x1)
++#define RT5670_EQ_LPF_SFT			0
++#define RT5670_EQ_LPF_DIS			(0x0)
++#define RT5670_EQ_LPF_EN			(0x1)
++#define RT5670_EQ_CTRL_MASK			(0x7f)
++
++/* Memory Test (0xb2) */
++#define RT5670_MT_MASK				(0x1 << 15)
++#define RT5670_MT_SFT				15
++#define RT5670_MT_DIS				(0x0 << 15)
++#define RT5670_MT_EN				(0x1 << 15)
++
++/* DRC/AGC Control 1 (0xb4) */
++#define RT5670_DRC_AGC_P_MASK			(0x1 << 15)
++#define RT5670_DRC_AGC_P_SFT			15
++#define RT5670_DRC_AGC_P_DAC			(0x0 << 15)
++#define RT5670_DRC_AGC_P_ADC			(0x1 << 15)
++#define RT5670_DRC_AGC_MASK			(0x1 << 14)
++#define RT5670_DRC_AGC_SFT			14
++#define RT5670_DRC_AGC_DIS			(0x0 << 14)
++#define RT5670_DRC_AGC_EN			(0x1 << 14)
++#define RT5670_DRC_AGC_UPD			(0x1 << 13)
++#define RT5670_DRC_AGC_UPD_BIT			13
++#define RT5670_DRC_AGC_AR_MASK			(0x1f << 8)
++#define RT5670_DRC_AGC_AR_SFT			8
++#define RT5670_DRC_AGC_R_MASK			(0x7 << 5)
++#define RT5670_DRC_AGC_R_SFT			5
++#define RT5670_DRC_AGC_R_48K			(0x1 << 5)
++#define RT5670_DRC_AGC_R_96K			(0x2 << 5)
++#define RT5670_DRC_AGC_R_192K			(0x3 << 5)
++#define RT5670_DRC_AGC_R_441K			(0x5 << 5)
++#define RT5670_DRC_AGC_R_882K			(0x6 << 5)
++#define RT5670_DRC_AGC_R_1764K			(0x7 << 5)
++#define RT5670_DRC_AGC_RC_MASK			(0x1f)
++#define RT5670_DRC_AGC_RC_SFT			0
++
++/* DRC/AGC Control 2 (0xb5) */
++#define RT5670_DRC_AGC_POB_MASK			(0x3f << 8)
++#define RT5670_DRC_AGC_POB_SFT			8
++#define RT5670_DRC_AGC_CP_MASK			(0x1 << 7)
++#define RT5670_DRC_AGC_CP_SFT			7
++#define RT5670_DRC_AGC_CP_DIS			(0x0 << 7)
++#define RT5670_DRC_AGC_CP_EN			(0x1 << 7)
++#define RT5670_DRC_AGC_CPR_MASK			(0x3 << 5)
++#define RT5670_DRC_AGC_CPR_SFT			5
++#define RT5670_DRC_AGC_CPR_1_1			(0x0 << 5)
++#define RT5670_DRC_AGC_CPR_1_2			(0x1 << 5)
++#define RT5670_DRC_AGC_CPR_1_3			(0x2 << 5)
++#define RT5670_DRC_AGC_CPR_1_4			(0x3 << 5)
++#define RT5670_DRC_AGC_PRB_MASK			(0x1f)
++#define RT5670_DRC_AGC_PRB_SFT			0
++
++/* DRC/AGC Control 3 (0xb6) */
++#define RT5670_DRC_AGC_NGB_MASK			(0xf << 12)
++#define RT5670_DRC_AGC_NGB_SFT			12
++#define RT5670_DRC_AGC_TAR_MASK			(0x1f << 7)
++#define RT5670_DRC_AGC_TAR_SFT			7
++#define RT5670_DRC_AGC_NG_MASK			(0x1 << 6)
++#define RT5670_DRC_AGC_NG_SFT			6
++#define RT5670_DRC_AGC_NG_DIS			(0x0 << 6)
++#define RT5670_DRC_AGC_NG_EN			(0x1 << 6)
++#define RT5670_DRC_AGC_NGH_MASK			(0x1 << 5)
++#define RT5670_DRC_AGC_NGH_SFT			5
++#define RT5670_DRC_AGC_NGH_DIS			(0x0 << 5)
++#define RT5670_DRC_AGC_NGH_EN			(0x1 << 5)
++#define RT5670_DRC_AGC_NGT_MASK			(0x1f)
++#define RT5670_DRC_AGC_NGT_SFT			0
++
++/* Jack Detect Control (0xbb) */
++#define RT5670_JD_MASK				(0x7 << 13)
++#define RT5670_JD_SFT				13
++#define RT5670_JD_DIS				(0x0 << 13)
++#define RT5670_JD_GPIO1				(0x1 << 13)
++#define RT5670_JD_JD1_IN4P			(0x2 << 13)
++#define RT5670_JD_JD2_IN4N			(0x3 << 13)
++#define RT5670_JD_GPIO2				(0x4 << 13)
++#define RT5670_JD_GPIO3				(0x5 << 13)
++#define RT5670_JD_GPIO4				(0x6 << 13)
++#define RT5670_JD_HP_MASK			(0x1 << 11)
++#define RT5670_JD_HP_SFT			11
++#define RT5670_JD_HP_DIS			(0x0 << 11)
++#define RT5670_JD_HP_EN				(0x1 << 11)
++#define RT5670_JD_HP_TRG_MASK			(0x1 << 10)
++#define RT5670_JD_HP_TRG_SFT			10
++#define RT5670_JD_HP_TRG_LO			(0x0 << 10)
++#define RT5670_JD_HP_TRG_HI			(0x1 << 10)
++#define RT5670_JD_SPL_MASK			(0x1 << 9)
++#define RT5670_JD_SPL_SFT			9
++#define RT5670_JD_SPL_DIS			(0x0 << 9)
++#define RT5670_JD_SPL_EN			(0x1 << 9)
++#define RT5670_JD_SPL_TRG_MASK			(0x1 << 8)
++#define RT5670_JD_SPL_TRG_SFT			8
++#define RT5670_JD_SPL_TRG_LO			(0x0 << 8)
++#define RT5670_JD_SPL_TRG_HI			(0x1 << 8)
++#define RT5670_JD_SPR_MASK			(0x1 << 7)
++#define RT5670_JD_SPR_SFT			7
++#define RT5670_JD_SPR_DIS			(0x0 << 7)
++#define RT5670_JD_SPR_EN			(0x1 << 7)
++#define RT5670_JD_SPR_TRG_MASK			(0x1 << 6)
++#define RT5670_JD_SPR_TRG_SFT			6
++#define RT5670_JD_SPR_TRG_LO			(0x0 << 6)
++#define RT5670_JD_SPR_TRG_HI			(0x1 << 6)
++#define RT5670_JD_MO_MASK			(0x1 << 5)
++#define RT5670_JD_MO_SFT			5
++#define RT5670_JD_MO_DIS			(0x0 << 5)
++#define RT5670_JD_MO_EN				(0x1 << 5)
++#define RT5670_JD_MO_TRG_MASK			(0x1 << 4)
++#define RT5670_JD_MO_TRG_SFT			4
++#define RT5670_JD_MO_TRG_LO			(0x0 << 4)
++#define RT5670_JD_MO_TRG_HI			(0x1 << 4)
++#define RT5670_JD_LO_MASK			(0x1 << 3)
++#define RT5670_JD_LO_SFT			3
++#define RT5670_JD_LO_DIS			(0x0 << 3)
++#define RT5670_JD_LO_EN				(0x1 << 3)
++#define RT5670_JD_LO_TRG_MASK			(0x1 << 2)
++#define RT5670_JD_LO_TRG_SFT			2
++#define RT5670_JD_LO_TRG_LO			(0x0 << 2)
++#define RT5670_JD_LO_TRG_HI			(0x1 << 2)
++#define RT5670_JD1_IN4P_MASK			(0x1 << 1)
++#define RT5670_JD1_IN4P_SFT			1
++#define RT5670_JD1_IN4P_DIS			(0x0 << 1)
++#define RT5670_JD1_IN4P_EN			(0x1 << 1)
++#define RT5670_JD2_IN4N_MASK			(0x1)
++#define RT5670_JD2_IN4N_SFT			0
++#define RT5670_JD2_IN4N_DIS			(0x0)
++#define RT5670_JD2_IN4N_EN			(0x1)
++
++/* IRQ Control 1 (0xbd) */
++#define RT5670_IRQ_JD_MASK			(0x1 << 15)
++#define RT5670_IRQ_JD_SFT			15
++#define RT5670_IRQ_JD_BP			(0x0 << 15)
++#define RT5670_IRQ_JD_NOR			(0x1 << 15)
++#define RT5670_IRQ_OT_MASK			(0x1 << 14)
++#define RT5670_IRQ_OT_SFT			14
++#define RT5670_IRQ_OT_BP			(0x0 << 14)
++#define RT5670_IRQ_OT_NOR			(0x1 << 14)
++#define RT5670_JD_STKY_MASK			(0x1 << 13)
++#define RT5670_JD_STKY_SFT			13
++#define RT5670_JD_STKY_DIS			(0x0 << 13)
++#define RT5670_JD_STKY_EN			(0x1 << 13)
++#define RT5670_OT_STKY_MASK			(0x1 << 12)
++#define RT5670_OT_STKY_SFT			12
++#define RT5670_OT_STKY_DIS			(0x0 << 12)
++#define RT5670_OT_STKY_EN			(0x1 << 12)
++#define RT5670_JD_P_MASK			(0x1 << 11)
++#define RT5670_JD_P_SFT				11
++#define RT5670_JD_P_NOR				(0x0 << 11)
++#define RT5670_JD_P_INV				(0x1 << 11)
++#define RT5670_OT_P_MASK			(0x1 << 10)
++#define RT5670_OT_P_SFT				10
++#define RT5670_OT_P_NOR				(0x0 << 10)
++#define RT5670_OT_P_INV				(0x1 << 10)
++
++/* IRQ Control 2 (0xbe) */
++#define RT5670_IRQ_MB1_OC_MASK			(0x1 << 15)
++#define RT5670_IRQ_MB1_OC_SFT			15
++#define RT5670_IRQ_MB1_OC_BP			(0x0 << 15)
++#define RT5670_IRQ_MB1_OC_NOR			(0x1 << 15)
++#define RT5670_IRQ_MB2_OC_MASK			(0x1 << 14)
++#define RT5670_IRQ_MB2_OC_SFT			14
++#define RT5670_IRQ_MB2_OC_BP			(0x0 << 14)
++#define RT5670_IRQ_MB2_OC_NOR			(0x1 << 14)
++#define RT5670_MB1_OC_STKY_MASK			(0x1 << 11)
++#define RT5670_MB1_OC_STKY_SFT			11
++#define RT5670_MB1_OC_STKY_DIS			(0x0 << 11)
++#define RT5670_MB1_OC_STKY_EN			(0x1 << 11)
++#define RT5670_MB2_OC_STKY_MASK			(0x1 << 10)
++#define RT5670_MB2_OC_STKY_SFT			10
++#define RT5670_MB2_OC_STKY_DIS			(0x0 << 10)
++#define RT5670_MB2_OC_STKY_EN			(0x1 << 10)
++#define RT5670_MB1_OC_P_MASK			(0x1 << 7)
++#define RT5670_MB1_OC_P_SFT			7
++#define RT5670_MB1_OC_P_NOR			(0x0 << 7)
++#define RT5670_MB1_OC_P_INV			(0x1 << 7)
++#define RT5670_MB2_OC_P_MASK			(0x1 << 6)
++#define RT5670_MB2_OC_P_SFT			6
++#define RT5670_MB2_OC_P_NOR			(0x0 << 6)
++#define RT5670_MB2_OC_P_INV			(0x1 << 6)
++#define RT5670_MB1_OC_CLR			(0x1 << 3)
++#define RT5670_MB1_OC_CLR_SFT			3
++#define RT5670_MB2_OC_CLR			(0x1 << 2)
++#define RT5670_MB2_OC_CLR_SFT			2
++
++/* GPIO Control 1 (0xc0) */
++#define RT5670_GP1_PIN_MASK			(0x1 << 15)
++#define RT5670_GP1_PIN_SFT			15
++#define RT5670_GP1_PIN_GPIO1			(0x0 << 15)
++#define RT5670_GP1_PIN_IRQ			(0x1 << 15)
++#define RT5670_GP2_PIN_MASK			(0x1 << 14)
++#define RT5670_GP2_PIN_SFT			14
++#define RT5670_GP2_PIN_GPIO2			(0x0 << 14)
++#define RT5670_GP2_PIN_DMIC1_SCL		(0x1 << 14)
++#define RT5670_GP3_PIN_MASK			(0x3 << 12)
++#define RT5670_GP3_PIN_SFT			12
++#define RT5670_GP3_PIN_GPIO3			(0x0 << 12)
++#define RT5670_GP3_PIN_DMIC1_SDA		(0x1 << 12)
++#define RT5670_GP3_PIN_IRQ			(0x2 << 12)
++#define RT5670_GP4_PIN_MASK			(0x1 << 11)
++#define RT5670_GP4_PIN_SFT			11
++#define RT5670_GP4_PIN_GPIO4			(0x0 << 11)
++#define RT5670_GP4_PIN_DMIC2_SDA		(0x1 << 11)
++#define RT5670_DP_SIG_MASK			(0x1 << 10)
++#define RT5670_DP_SIG_SFT			10
++#define RT5670_DP_SIG_TEST			(0x0 << 10)
++#define RT5670_DP_SIG_AP			(0x1 << 10)
++#define RT5670_GPIO_M_MASK			(0x1 << 9)
++#define RT5670_GPIO_M_SFT			9
++#define RT5670_GPIO_M_FLT			(0x0 << 9)
++#define RT5670_GPIO_M_PH			(0x1 << 9)
++#define RT5670_I2S2_PIN_MASK			(0x1 << 8)
++#define RT5670_I2S2_PIN_SFT			8
++#define RT5670_I2S2_PIN_I2S			(0x0 << 8)
++#define RT5670_I2S2_PIN_GPIO			(0x1 << 8)
++#define RT5670_GP5_PIN_MASK			(0x1 << 7)
++#define RT5670_GP5_PIN_SFT			7
++#define RT5670_GP5_PIN_GPIO5			(0x0 << 7)
++#define RT5670_GP5_PIN_DMIC3_SCL		(0x1 << 7)
++#define RT5670_GP6_PIN_MASK			(0x1 << 6)
++#define RT5670_GP6_PIN_SFT			6
++#define RT5670_GP6_PIN_GPIO6			(0x0 << 6)
++#define RT5670_GP6_PIN_DMIC1_SDA		(0x1 << 6)
++#define RT5670_GP7_PIN_MASK			(0x3 << 4)
++#define RT5670_GP7_PIN_SFT			4
++#define RT5670_GP7_PIN_GPIO7			(0x0 << 4)
++#define RT5670_GP7_PIN_DMIC1_SDA		(0x1 << 4)
++#define RT5670_GP7_PIN_PDM_SCL2			(0x2 << 4)
++#define RT5670_GP8_PIN_MASK			(0x1 << 3)
++#define RT5670_GP8_PIN_SFT			3
++#define RT5670_GP8_PIN_GPIO8			(0x0 << 3)
++#define RT5670_GP8_PIN_DMIC2_SDA		(0x1 << 3)
++#define RT5670_GP9_PIN_MASK			(0x1 << 2)
++#define RT5670_GP9_PIN_SFT			2
++#define RT5670_GP9_PIN_GPIO9			(0x0 << 2)
++#define RT5670_GP9_PIN_DMIC3_SDA		(0x1 << 2)
++#define RT5670_GP10_PIN_MASK			(0x3)
++#define RT5670_GP10_PIN_SFT			0
++#define RT5670_GP10_PIN_GPIO9			(0x0)
++#define RT5670_GP10_PIN_DMIC3_SDA		(0x1)
++#define RT5670_GP10_PIN_PDM_ADT2		(0x2)
++
++/* GPIO Control 2 (0xc1) */
++#define RT5670_GP4_PF_MASK			(0x1 << 11)
++#define RT5670_GP4_PF_SFT			11
++#define RT5670_GP4_PF_IN			(0x0 << 11)
++#define RT5670_GP4_PF_OUT			(0x1 << 11)
++#define RT5670_GP4_OUT_MASK			(0x1 << 10)
++#define RT5670_GP4_OUT_SFT			10
++#define RT5670_GP4_OUT_LO			(0x0 << 10)
++#define RT5670_GP4_OUT_HI			(0x1 << 10)
++#define RT5670_GP4_P_MASK			(0x1 << 9)
++#define RT5670_GP4_P_SFT			9
++#define RT5670_GP4_P_NOR			(0x0 << 9)
++#define RT5670_GP4_P_INV			(0x1 << 9)
++#define RT5670_GP3_PF_MASK			(0x1 << 8)
++#define RT5670_GP3_PF_SFT			8
++#define RT5670_GP3_PF_IN			(0x0 << 8)
++#define RT5670_GP3_PF_OUT			(0x1 << 8)
++#define RT5670_GP3_OUT_MASK			(0x1 << 7)
++#define RT5670_GP3_OUT_SFT			7
++#define RT5670_GP3_OUT_LO			(0x0 << 7)
++#define RT5670_GP3_OUT_HI			(0x1 << 7)
++#define RT5670_GP3_P_MASK			(0x1 << 6)
++#define RT5670_GP3_P_SFT			6
++#define RT5670_GP3_P_NOR			(0x0 << 6)
++#define RT5670_GP3_P_INV			(0x1 << 6)
++#define RT5670_GP2_PF_MASK			(0x1 << 5)
++#define RT5670_GP2_PF_SFT			5
++#define RT5670_GP2_PF_IN			(0x0 << 5)
++#define RT5670_GP2_PF_OUT			(0x1 << 5)
++#define RT5670_GP2_OUT_MASK			(0x1 << 4)
++#define RT5670_GP2_OUT_SFT			4
++#define RT5670_GP2_OUT_LO			(0x0 << 4)
++#define RT5670_GP2_OUT_HI			(0x1 << 4)
++#define RT5670_GP2_P_MASK			(0x1 << 3)
++#define RT5670_GP2_P_SFT			3
++#define RT5670_GP2_P_NOR			(0x0 << 3)
++#define RT5670_GP2_P_INV			(0x1 << 3)
++#define RT5670_GP1_PF_MASK			(0x1 << 2)
++#define RT5670_GP1_PF_SFT			2
++#define RT5670_GP1_PF_IN			(0x0 << 2)
++#define RT5670_GP1_PF_OUT			(0x1 << 2)
++#define RT5670_GP1_OUT_MASK			(0x1 << 1)
++#define RT5670_GP1_OUT_SFT			1
++#define RT5670_GP1_OUT_LO			(0x0 << 1)
++#define RT5670_GP1_OUT_HI			(0x1 << 1)
++#define RT5670_GP1_P_MASK			(0x1)
++#define RT5670_GP1_P_SFT			0
++#define RT5670_GP1_P_NOR			(0x0)
++#define RT5670_GP1_P_INV			(0x1)
++
++/* Scramble Function (0xcd) */
++#define RT5670_SCB_KEY_MASK			(0xff)
++#define RT5670_SCB_KEY_SFT			0
++
++/* Scramble Control (0xce) */
++#define RT5670_SCB_SWAP_MASK			(0x1 << 15)
++#define RT5670_SCB_SWAP_SFT			15
++#define RT5670_SCB_SWAP_DIS			(0x0 << 15)
++#define RT5670_SCB_SWAP_EN			(0x1 << 15)
++#define RT5670_SCB_MASK				(0x1 << 14)
++#define RT5670_SCB_SFT				14
++#define RT5670_SCB_DIS				(0x0 << 14)
++#define RT5670_SCB_EN				(0x1 << 14)
++
++/* Baseback Control (0xcf) */
++#define RT5670_BB_MASK				(0x1 << 15)
++#define RT5670_BB_SFT				15
++#define RT5670_BB_DIS				(0x0 << 15)
++#define RT5670_BB_EN				(0x1 << 15)
++#define RT5670_BB_CT_MASK			(0x7 << 12)
++#define RT5670_BB_CT_SFT			12
++#define RT5670_BB_CT_A				(0x0 << 12)
++#define RT5670_BB_CT_B				(0x1 << 12)
++#define RT5670_BB_CT_C				(0x2 << 12)
++#define RT5670_BB_CT_D				(0x3 << 12)
++#define RT5670_M_BB_L_MASK			(0x1 << 9)
++#define RT5670_M_BB_L_SFT			9
++#define RT5670_M_BB_R_MASK			(0x1 << 8)
++#define RT5670_M_BB_R_SFT			8
++#define RT5670_M_BB_HPF_L_MASK			(0x1 << 7)
++#define RT5670_M_BB_HPF_L_SFT			7
++#define RT5670_M_BB_HPF_R_MASK			(0x1 << 6)
++#define RT5670_M_BB_HPF_R_SFT			6
++#define RT5670_G_BB_BST_MASK			(0x3f)
++#define RT5670_G_BB_BST_SFT			0
++
++/* MP3 Plus Control 1 (0xd0) */
++#define RT5670_M_MP3_L_MASK			(0x1 << 15)
++#define RT5670_M_MP3_L_SFT			15
++#define RT5670_M_MP3_R_MASK			(0x1 << 14)
++#define RT5670_M_MP3_R_SFT			14
++#define RT5670_M_MP3_MASK			(0x1 << 13)
++#define RT5670_M_MP3_SFT			13
++#define RT5670_M_MP3_DIS			(0x0 << 13)
++#define RT5670_M_MP3_EN				(0x1 << 13)
++#define RT5670_EG_MP3_MASK			(0x1f << 8)
++#define RT5670_EG_MP3_SFT			8
++#define RT5670_MP3_HLP_MASK			(0x1 << 7)
++#define RT5670_MP3_HLP_SFT			7
++#define RT5670_MP3_HLP_DIS			(0x0 << 7)
++#define RT5670_MP3_HLP_EN			(0x1 << 7)
++#define RT5670_M_MP3_ORG_L_MASK			(0x1 << 6)
++#define RT5670_M_MP3_ORG_L_SFT			6
++#define RT5670_M_MP3_ORG_R_MASK			(0x1 << 5)
++#define RT5670_M_MP3_ORG_R_SFT			5
++
++/* MP3 Plus Control 2 (0xd1) */
++#define RT5670_MP3_WT_MASK			(0x1 << 13)
++#define RT5670_MP3_WT_SFT			13
++#define RT5670_MP3_WT_1_4			(0x0 << 13)
++#define RT5670_MP3_WT_1_2			(0x1 << 13)
++#define RT5670_OG_MP3_MASK			(0x1f << 8)
++#define RT5670_OG_MP3_SFT			8
++#define RT5670_HG_MP3_MASK			(0x3f)
++#define RT5670_HG_MP3_SFT			0
++
++/* 3D HP Control 1 (0xd2) */
++#define RT5670_3D_CF_MASK			(0x1 << 15)
++#define RT5670_3D_CF_SFT			15
++#define RT5670_3D_CF_DIS			(0x0 << 15)
++#define RT5670_3D_CF_EN				(0x1 << 15)
++#define RT5670_3D_HP_MASK			(0x1 << 14)
++#define RT5670_3D_HP_SFT			14
++#define RT5670_3D_HP_DIS			(0x0 << 14)
++#define RT5670_3D_HP_EN				(0x1 << 14)
++#define RT5670_3D_BT_MASK			(0x1 << 13)
++#define RT5670_3D_BT_SFT			13
++#define RT5670_3D_BT_DIS			(0x0 << 13)
++#define RT5670_3D_BT_EN				(0x1 << 13)
++#define RT5670_3D_1F_MIX_MASK			(0x3 << 11)
++#define RT5670_3D_1F_MIX_SFT			11
++#define RT5670_3D_HP_M_MASK			(0x1 << 10)
++#define RT5670_3D_HP_M_SFT			10
++#define RT5670_3D_HP_M_SUR			(0x0 << 10)
++#define RT5670_3D_HP_M_FRO			(0x1 << 10)
++#define RT5670_M_3D_HRTF_MASK			(0x1 << 9)
++#define RT5670_M_3D_HRTF_SFT			9
++#define RT5670_M_3D_D2H_MASK			(0x1 << 8)
++#define RT5670_M_3D_D2H_SFT			8
++#define RT5670_M_3D_D2R_MASK			(0x1 << 7)
++#define RT5670_M_3D_D2R_SFT			7
++#define RT5670_M_3D_REVB_MASK			(0x1 << 6)
++#define RT5670_M_3D_REVB_SFT			6
++
++/* Adjustable high pass filter control 1 (0xd3) */
++#define RT5670_2ND_HPF_MASK			(0x1 << 15)
++#define RT5670_2ND_HPF_SFT			15
++#define RT5670_2ND_HPF_DIS			(0x0 << 15)
++#define RT5670_2ND_HPF_EN			(0x1 << 15)
++#define RT5670_HPF_CF_L_MASK			(0x7 << 12)
++#define RT5670_HPF_CF_L_SFT			12
++#define RT5670_1ST_HPF_MASK			(0x1 << 11)
++#define RT5670_1ST_HPF_SFT			11
++#define RT5670_1ST_HPF_DIS			(0x0 << 11)
++#define RT5670_1ST_HPF_EN			(0x1 << 11)
++#define RT5670_HPF_CF_R_MASK			(0x7 << 8)
++#define RT5670_HPF_CF_R_SFT			8
++#define RT5670_ZD_T_MASK			(0x3 << 6)
++#define RT5670_ZD_T_SFT				6
++#define RT5670_ZD_F_MASK			(0x3 << 4)
++#define RT5670_ZD_F_SFT				4
++#define RT5670_ZD_F_IM				(0x0 << 4)
++#define RT5670_ZD_F_ZC_IM			(0x1 << 4)
++#define RT5670_ZD_F_ZC_IOD			(0x2 << 4)
++#define RT5670_ZD_F_UN				(0x3 << 4)
++
++/* HP calibration control and Amp detection (0xd6) */
++#define RT5670_SI_DAC_MASK			(0x1 << 11)
++#define RT5670_SI_DAC_SFT			11
++#define RT5670_SI_DAC_AUTO			(0x0 << 11)
++#define RT5670_SI_DAC_TEST			(0x1 << 11)
++#define RT5670_DC_CAL_M_MASK			(0x1 << 10)
++#define RT5670_DC_CAL_M_SFT			10
++#define RT5670_DC_CAL_M_CAL			(0x0 << 10)
++#define RT5670_DC_CAL_M_NOR			(0x1 << 10)
++#define RT5670_DC_CAL_MASK			(0x1 << 9)
++#define RT5670_DC_CAL_SFT			9
++#define RT5670_DC_CAL_DIS			(0x0 << 9)
++#define RT5670_DC_CAL_EN			(0x1 << 9)
++#define RT5670_HPD_RCV_MASK			(0x7 << 6)
++#define RT5670_HPD_RCV_SFT			6
++#define RT5670_HPD_PS_MASK			(0x1 << 5)
++#define RT5670_HPD_PS_SFT			5
++#define RT5670_HPD_PS_DIS			(0x0 << 5)
++#define RT5670_HPD_PS_EN			(0x1 << 5)
++#define RT5670_CAL_M_MASK			(0x1 << 4)
++#define RT5670_CAL_M_SFT			4
++#define RT5670_CAL_M_DEP			(0x0 << 4)
++#define RT5670_CAL_M_CAL			(0x1 << 4)
++#define RT5670_CAL_MASK				(0x1 << 3)
++#define RT5670_CAL_SFT				3
++#define RT5670_CAL_DIS				(0x0 << 3)
++#define RT5670_CAL_EN				(0x1 << 3)
++#define RT5670_CAL_TEST_MASK			(0x1 << 2)
++#define RT5670_CAL_TEST_SFT			2
++#define RT5670_CAL_TEST_DIS			(0x0 << 2)
++#define RT5670_CAL_TEST_EN			(0x1 << 2)
++#define RT5670_CAL_P_MASK			(0x3)
++#define RT5670_CAL_P_SFT			0
++#define RT5670_CAL_P_NONE			(0x0)
++#define RT5670_CAL_P_CAL			(0x1)
++#define RT5670_CAL_P_DAC_CAL			(0x2)
++
++/* Soft volume and zero cross control 1 (0xd9) */
++#define RT5670_SV_MASK				(0x1 << 15)
++#define RT5670_SV_SFT				15
++#define RT5670_SV_DIS				(0x0 << 15)
++#define RT5670_SV_EN				(0x1 << 15)
++#define RT5670_SPO_SV_MASK			(0x1 << 14)
++#define RT5670_SPO_SV_SFT			14
++#define RT5670_SPO_SV_DIS			(0x0 << 14)
++#define RT5670_SPO_SV_EN			(0x1 << 14)
++#define RT5670_OUT_SV_MASK			(0x1 << 13)
++#define RT5670_OUT_SV_SFT			13
++#define RT5670_OUT_SV_DIS			(0x0 << 13)
++#define RT5670_OUT_SV_EN			(0x1 << 13)
++#define RT5670_HP_SV_MASK			(0x1 << 12)
++#define RT5670_HP_SV_SFT			12
++#define RT5670_HP_SV_DIS			(0x0 << 12)
++#define RT5670_HP_SV_EN				(0x1 << 12)
++#define RT5670_ZCD_DIG_MASK			(0x1 << 11)
++#define RT5670_ZCD_DIG_SFT			11
++#define RT5670_ZCD_DIG_DIS			(0x0 << 11)
++#define RT5670_ZCD_DIG_EN			(0x1 << 11)
++#define RT5670_ZCD_MASK				(0x1 << 10)
++#define RT5670_ZCD_SFT				10
++#define RT5670_ZCD_PD				(0x0 << 10)
++#define RT5670_ZCD_PU				(0x1 << 10)
++#define RT5670_M_ZCD_MASK			(0x3f << 4)
++#define RT5670_M_ZCD_SFT			4
++#define RT5670_M_ZCD_RM_L			(0x1 << 9)
++#define RT5670_M_ZCD_RM_R			(0x1 << 8)
++#define RT5670_M_ZCD_SM_L			(0x1 << 7)
++#define RT5670_M_ZCD_SM_R			(0x1 << 6)
++#define RT5670_M_ZCD_OM_L			(0x1 << 5)
++#define RT5670_M_ZCD_OM_R			(0x1 << 4)
++#define RT5670_SV_DLY_MASK			(0xf)
++#define RT5670_SV_DLY_SFT			0
++
++/* Soft volume and zero cross control 2 (0xda) */
++#define RT5670_ZCD_HP_MASK			(0x1 << 15)
++#define RT5670_ZCD_HP_SFT			15
++#define RT5670_ZCD_HP_DIS			(0x0 << 15)
++#define RT5670_ZCD_HP_EN			(0x1 << 15)
++
++
++/* Codec Private Register definition */
++/* 3D Speaker Control (0x63) */
++#define RT5670_3D_SPK_MASK			(0x1 << 15)
++#define RT5670_3D_SPK_SFT			15
++#define RT5670_3D_SPK_DIS			(0x0 << 15)
++#define RT5670_3D_SPK_EN			(0x1 << 15)
++#define RT5670_3D_SPK_M_MASK			(0x3 << 13)
++#define RT5670_3D_SPK_M_SFT			13
++#define RT5670_3D_SPK_CG_MASK			(0x1f << 8)
++#define RT5670_3D_SPK_CG_SFT			8
++#define RT5670_3D_SPK_SG_MASK			(0x1f)
++#define RT5670_3D_SPK_SG_SFT			0
++
++/* Wind Noise Detection Control 1 (0x6c) */
++#define RT5670_WND_MASK				(0x1 << 15)
++#define RT5670_WND_SFT				15
++#define RT5670_WND_DIS				(0x0 << 15)
++#define RT5670_WND_EN				(0x1 << 15)
++
++/* Wind Noise Detection Control 2 (0x6d) */
++#define RT5670_WND_FC_NW_MASK			(0x3f << 10)
++#define RT5670_WND_FC_NW_SFT			10
++#define RT5670_WND_FC_WK_MASK			(0x3f << 4)
++#define RT5670_WND_FC_WK_SFT			4
++
++/* Wind Noise Detection Control 3 (0x6e) */
++#define RT5670_HPF_FC_MASK			(0x3f << 6)
++#define RT5670_HPF_FC_SFT			6
++#define RT5670_WND_FC_ST_MASK			(0x3f)
++#define RT5670_WND_FC_ST_SFT			0
++
++/* Wind Noise Detection Control 4 (0x6f) */
++#define RT5670_WND_TH_LO_MASK			(0x3ff)
++#define RT5670_WND_TH_LO_SFT			0
++
++/* Wind Noise Detection Control 5 (0x70) */
++#define RT5670_WND_TH_HI_MASK			(0x3ff)
++#define RT5670_WND_TH_HI_SFT			0
++
++/* Wind Noise Detection Control 8 (0x73) */
++#define RT5670_WND_WIND_MASK			(0x1 << 13) /* Read-Only */
++#define RT5670_WND_WIND_SFT			13
++#define RT5670_WND_STRONG_MASK			(0x1 << 12) /* Read-Only */
++#define RT5670_WND_STRONG_SFT			12
++enum {
++	RT5670_NO_WIND,
++	RT5670_BREEZE,
++	RT5670_STORM,
++};
++
++/* Dipole Speaker Interface (0x75) */
++#define RT5670_DP_ATT_MASK			(0x3 << 14)
++#define RT5670_DP_ATT_SFT			14
++#define RT5670_DP_SPK_MASK			(0x1 << 10)
++#define RT5670_DP_SPK_SFT			10
++#define RT5670_DP_SPK_DIS			(0x0 << 10)
++#define RT5670_DP_SPK_EN			(0x1 << 10)
++
++/* EQ Pre Volume Control (0xb3) */
++#define RT5670_EQ_PRE_VOL_MASK			(0xffff)
++#define RT5670_EQ_PRE_VOL_SFT			0
++
++/* EQ Post Volume Control (0xb4) */
++#define RT5670_EQ_PST_VOL_MASK			(0xffff)
++#define RT5670_EQ_PST_VOL_SFT			0
++
++/* Jack Detect Control 3 (0xf8) */
++#define RT5670_CMP_MIC_IN_DET_MASK		(0x7 << 12)
++#define RT5670_JD_CBJ_EN			(0x1 << 7)
++#define RT5670_JD_CBJ_POL			(0x1 << 6)
++#define RT5670_JD_TRI_CBJ_SEL_MASK		(0x7 << 3)
++#define RT5670_JD_TRI_CBJ_SEL_SFT		(3)
++#define RT5670_JD_TRI_HPO_SEL_MASK		(0x7)
++#define RT5670_JD_TRI_HPO_SEL_SFT		(0)
++#define RT5670_JD_F_GPIO_JD1			(0x0)
++#define RT5670_JD_F_JD1_1			(0x1)
++#define RT5670_JD_F_JD1_2			(0x2)
++#define RT5670_JD_F_JD2				(0x3)
++#define RT5670_JD_F_JD3				(0x4)
++#define RT5670_JD_F_GPIO_JD2			(0x5)
++#define RT5670_JD_F_MX0B_12			(0x6)
++
++/* Digital Misc Control (0xfa) */
++#define RT5670_RST_DSP				(0x1 << 13)
++#define RT5670_IF1_ADC1_IN1_SEL			(0x1 << 12)
++#define RT5670_IF1_ADC1_IN1_SFT			12
++#define RT5670_IF1_ADC1_IN2_SEL			(0x1 << 11)
++#define RT5670_IF1_ADC1_IN2_SFT			11
++#define RT5670_IF1_ADC2_IN1_SEL			(0x1 << 10)
++#define RT5670_IF1_ADC2_IN1_SFT			10
++
++/* General Control2 (0xfb) */
++#define RT5670_RXDC_SRC_MASK			(0x1 << 7)
++#define RT5670_RXDC_SRC_STO			(0x0 << 7)
++#define RT5670_RXDC_SRC_MONO			(0x1 << 7)
++#define RT5670_RXDC_SRC_SFT			(7)
++#define RT5670_RXDP2_SEL_MASK			(0x1 << 3)
++#define RT5670_RXDP2_SEL_IF2			(0x0 << 3)
++#define RT5670_RXDP2_SEL_ADC			(0x1 << 3)
++#define RT5670_RXDP2_SEL_SFT			(3)
++
++
++/* Vendor ID (0xfd) */
++#define RT5670_VER_C				0x2
++#define RT5670_VER_D				0x3
++
++
++/* Volume Rescale */
++#define RT5670_VOL_RSCL_MAX 0x27
++#define RT5670_VOL_RSCL_RANGE 0x1F
++/* Debug String Length */
++#define RT5670_REG_DISP_LEN 23
++
++int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert);
++int rt5670_check_interrupt_event(struct snd_soc_codec *codec, int *data);
++
++/* System Clock Source */
++enum {
++	RT5670_SCLK_S_MCLK,
++	RT5670_SCLK_S_PLL1,
++	RT5670_SCLK_S_RCCLK,
++};
++
++/* PLL1 Source */
++enum {
++	RT5670_PLL1_S_MCLK,
++	RT5670_PLL1_S_BCLK1,
++	RT5670_PLL1_S_BCLK2,
++	RT5670_PLL1_S_BCLK3,
++	RT5670_PLL1_S_BCLK4,
++};
++
++enum {
++	RT5670_AIF1,
++	RT5670_AIF2,
++	RT5670_AIF3,
++	RT5670_AIF4,
++	RT5670_AIFS,
++};
++
++#define RT5670_U_IF1 (0x1)
++#define RT5670_U_IF2 (0x1 << 1)
++#define RT5670_U_IF3 (0x1 << 2)
++#define RT5670_U_IF4 (0x1 << 3)
++
++enum {
++	RT5670_DMIC_DIS,
++	RT5670_DMIC1,
++	RT5670_DMIC2,
++	RT5670_DMIC3,
++};
++
++enum {
++	RT5670_BTN_EVENT = BIT(0), /* Jack evulse */
++	RT5670_BR_EVENT = BIT(1), /* Button Release */
++	RT5670_J_IN_EVENT = BIT(2), /* Jack insert */
++	RT5670_J_OUT_EVENT = BIT(3), /* Jack evulse */
++	RT5670_UN_EVENT = BIT(4), /* Unknown */
++};
++
++struct rt5670_pll_code {
++	bool m_bp; /* Indicates bypass m code or not. */
++	int m_code;
++	int n_code;
++	int k_code;
++};
++
++struct rt5670_priv {
++	struct snd_soc_codec *codec;
++	struct delayed_work patch_work;
++
++	int aif_pu;
++	int sysclk;
++	int sysclk_src;
++	int lrck[RT5670_AIFS];
++	int bclk[RT5670_AIFS];
++	int master[RT5670_AIFS];
++
++	int pll_src;
++	int pll_in;
++	int pll_out;
++
++	int dmic_en;
++	bool combo_jack_en;
++	int dsp_sw; /* expected parameter setting */
++	int jack_type;
++};
++
++#endif /* __RT5670_H__ */
+diff --git a/sound/soc/codecs/rt5670_ioctl.c b/sound/soc/codecs/rt5670_ioctl.c
+new file mode 100644
+index 00000000..df293cdc
+--- /dev/null
++++ b/sound/soc/codecs/rt5670_ioctl.c
+@@ -0,0 +1,132 @@
++/*
++ * rt5670_ioctl.h  --  RT5670 ALSA SoC audio driver IO control
++ *
++ * Copyright 2012 Realtek Microelectronics
++ * Author: Bard <bardliao@realtek.com>
++ *
++ * 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.
++ */
++
++#include <linux/spi/spi.h>
++#include <sound/soc.h>
++#include "rt_codec_ioctl.h"
++#include "rt5670_ioctl.h"
++#include "rt5670.h"
++#include "rt5670-dsp.h"
++
++hweq_t hweq_param[] = {
++	{/* NORMAL */
++		{0},
++		{0},
++		0x0000,
++	},
++	{/* SPK */
++		{0},
++		{0x1c10,0x01f4,	0xc5e9,	0x1a98,	0x1d2c,	0xc882,	0x1c10,	0x01f4,	0xe904,	0x1c10,	0x01f4, 0xe904,	0x1c10,	0x01f4,	0x1c10,	0x01f4,	0x2000,	0x0000,	0x2000},
++		0x0000,
++	},
++	{/* HP */
++		{0},
++		{0x1c10,0x01f4,	0xc5e9,	0x1a98,	0x1d2c,	0xc882,	0x1c10,	0x01f4,	0xe904,	0x1c10,	0x01f4, 0xe904,	0x1c10,	0x01f4,	0x1c10,	0x01f4,	0x2000,	0x0000,	0x2000},
++		0x0000,
++	},
++};
++#define RT5670_HWEQ_LEN ARRAY_SIZE(hweq_param)
++
++int eqreg[EQ_CH_NUM][EQ_REG_NUM] = {
++	{0xa4, 0xa5, 0xeb, 0xec, 0xed, 0xee, 0xe7, 0xe8, 0xe9, 0xea, 0xe5,
++	 0xe6, 0xae, 0xaf, 0xb0, 0xb4, 0xb5, 0xb6, 0xba, 0xbb, 0xbc, 0xc0,
++	 0xc1, 0xc4, 0xc5, 0xc6, 0xca, 0xcc},
++	{0xa6, 0xa7, 0xf5, 0xf6, 0xf7, 0xf8, 0xf1, 0xf2, 0xf3, 0xf4, 0xef,
++	 0xf0, 0xb1, 0xb2, 0xb3, 0xb7, 0xb8, 0xb9, 0xbd, 0xbe, 0xbf, 0xc2,
++	 0xc3, 0xc7, 0xc8, 0xc9, 0xcb, 0xcd},
++	{0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
++	 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xe1, 0xe2},
++};
++
++int rt5670_update_eqmode(
++	struct snd_soc_codec *codec, int channel, int mode)
++{
++	struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
++	int i;
++
++	if(codec == NULL ||  mode >= RT5670_HWEQ_LEN)
++		return -EINVAL;
++
++	dev_dbg(codec->dev, "%s(): mode=%d\n", __func__, mode);
++
++	for(i = 0; i <= EQ_REG_NUM; i++) {
++		hweq_param[mode].reg[i] = eqreg[channel][i];
++	}
++
++	for(i = 0; i <= EQ_REG_NUM; i++) {
++		if(hweq_param[mode].reg[i])
++			ioctl_ops->index_write(codec, hweq_param[mode].reg[i],
++					hweq_param[mode].value[i]);
++		else
++			break;
++	}
++	snd_soc_update_bits(codec, RT5670_EQ_CTRL2, RT5670_EQ_CTRL_MASK,
++					hweq_param[mode].ctrl);
++	snd_soc_update_bits(codec, RT5670_EQ_CTRL1,
++		RT5670_EQ_UPD, RT5670_EQ_UPD);
++	snd_soc_update_bits(codec, RT5670_EQ_CTRL1, RT5670_EQ_UPD, 0);
++
++	return 0;
++}
++
++int rt5670_ioctl_common(struct snd_hwdep *hw, struct file *file,
++			unsigned int cmd, unsigned long arg)
++{
++	struct snd_soc_codec *codec = hw->private_data;
++	struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
++	struct rt_codec_cmd rt_codec;
++	//struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
++	int *buf;
++	static int eq_mode[EQ_CH_NUM];
++
++	if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
++		dev_err(codec->dev,"copy_from_user faild\n");
++		return -EFAULT;
++	}
++	dev_dbg(codec->dev, "%s(): rt_codec.number=%d, cmd=%d\n",
++			__func__, rt_codec.number, cmd);
++	buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
++	if (buf == NULL)
++		return -ENOMEM;
++	if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) {
++		goto err;
++	}
++
++	switch (cmd) {
++	case RT_SET_CODEC_HWEQ_IOCTL:
++		if (eq_mode == *buf)
++			break;
++		eq_mode[*buf] = *(buf + 1);
++		rt5670_update_eqmode(codec, eq_mode[*buf], *buf);
++		break;
++
++	case RT_GET_CODEC_ID:
++		*buf = snd_soc_read(codec, RT5670_VENDOR_ID2);
++		if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
++			goto err;
++		break;
++	case RT_READ_CODEC_DSP_IOCTL:
++	case RT_WRITE_CODEC_DSP_IOCTL:
++	case RT_GET_CODEC_DSP_MODE_IOCTL:
++		return rt5670_dsp_ioctl_common(hw, file, cmd, arg);
++		break;
++	default:
++		break;
++	}
++
++	kfree(buf);
++	return 0;
++
++err:
++	kfree(buf);
++	return -EFAULT;
++}
++EXPORT_SYMBOL_GPL(rt5670_ioctl_common);
+diff --git a/sound/soc/codecs/rt5670_ioctl.h b/sound/soc/codecs/rt5670_ioctl.h
+new file mode 100644
+index 00000000..dda20b19
+--- /dev/null
++++ b/sound/soc/codecs/rt5670_ioctl.h
+@@ -0,0 +1,46 @@
++/*
++ * rt5670_ioctl.h  --  RT5670 ALSA SoC audio driver IO control
++ *
++ * Copyright 2012 Realtek Microelectronics
++ * Author: Bard <bardliao@realtek.com>
++ *
++ * 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.
++ */
++
++#ifndef __RT5670_IOCTL_H__
++#define __RT5670_IOCTL_H__
++
++#include <sound/hwdep.h>
++#include <linux/ioctl.h>
++
++enum {
++	NORMAL=0,
++	SPK,
++	HP,
++	MODE_NUM,
++};
++
++enum {
++	EQ_CH_DACL=0,
++	EQ_CH_DACR,
++	EQ_CH_ADC,
++	EQ_CH_NUM,
++};
++
++
++
++#define EQ_REG_NUM 28
++typedef struct  hweq_s {
++	unsigned int reg[EQ_REG_NUM];
++	unsigned int value[EQ_REG_NUM];
++	unsigned int ctrl;
++} hweq_t;
++
++int rt5670_ioctl_common(struct snd_hwdep *hw, struct file *file,
++			unsigned int cmd, unsigned long arg);
++int rt5670_update_eqmode(
++	struct snd_soc_codec *codec, int channel, int mode);
++
++#endif /* __RT5670_IOCTL_H__ */
+diff --git a/sound/soc/codecs/rt_codec_ioctl.c b/sound/soc/codecs/rt_codec_ioctl.c
+new file mode 100644
+index 00000000..f51bb0f2
+--- /dev/null
++++ b/sound/soc/codecs/rt_codec_ioctl.c
+@@ -0,0 +1,183 @@
++/*
++ * rt_codec_ioctl.h  --  RT56XX ALSA SoC audio driver IO control
++ *
++ * Copyright 2012 Realtek Microelectronics
++ * Author: Bard <bardliao@realtek.com>
++ *
++ * 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.
++ */
++#define DEBUG 1
++#include <linux/spi/spi.h>
++#include <sound/soc.h>
++#include "rt_codec_ioctl.h"
++
++static struct rt_codec_ops rt_codec_ioctl_ops;
++
++#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
++#define RT_CE_CODEC_HWDEP_NAME "rt_codec hwdep "
++static int rt_codec_hwdep_open(struct snd_hwdep *hw, struct file *file)
++{
++	struct snd_soc_codec *codec = hw->private_data;
++	dev_dbg(codec->dev, "%s()\n", __func__);
++	return 0;
++}
++
++static int rt_codec_hwdep_release(struct snd_hwdep *hw, struct file *file)
++{
++	struct snd_soc_codec *codec = hw->private_data;
++	dev_dbg(codec->dev, "%s()\n", __func__);
++	return 0;
++}
++
++static int rt_codec_hwdep_ioctl_common(struct snd_hwdep *hw,
++		struct file *file, unsigned int cmd, unsigned long arg)
++{
++	struct snd_soc_codec *codec = hw->private_data;
++	struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
++	struct rt_codec_cmd rt_codec;
++	int *buf, *p;
++
++	if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
++		dev_err(codec->dev,"copy_from_user faild\n");
++		return -EFAULT;
++	}
++	dev_dbg(codec->dev, "%s(): rt_codec.number=%d, cmd=%d\n",
++			__func__, rt_codec.number, cmd);
++	buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
++	if (buf == NULL)
++		return -ENOMEM;
++	if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) {
++		goto err;
++	}
++
++	switch (cmd) {
++	case RT_READ_CODEC_REG_IOCTL:
++		for (p = buf; p < buf + rt_codec.number / 2; p++) {
++			*(p + rt_codec.number / 2) = snd_soc_read(codec, *p);
++		}
++		if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
++			goto err;
++		break;		
++
++	case RT_WRITE_CODEC_REG_IOCTL:
++		for (p = buf; p < buf + rt_codec.number / 2; p++)
++			snd_soc_write(codec, *p, *(p + rt_codec.number / 2));
++		break;
++
++	case RT_READ_CODEC_INDEX_IOCTL:
++		if (NULL == rt_codec_ioctl_ops.index_read)
++			goto err;
++
++		for (p = buf; p < buf + rt_codec.number / 2; p++)
++			*(p+rt_codec.number/2) = rt_codec_ioctl_ops.index_read(
++							codec, *p);
++		if (copy_to_user(rt_codec.buf, buf,
++			sizeof(*buf) * rt_codec.number))
++			goto err;
++		break;
++
++	case RT_WRITE_CODEC_INDEX_IOCTL:
++		if (NULL == rt_codec_ioctl_ops.index_write)
++			goto err;
++
++		for (p = buf; p < buf + rt_codec.number / 2; p++)
++		{
++			dev_dbg(codec->dev, "%x , %x\n",
++				*p,*(p+rt_codec.number/2));
++			rt_codec_ioctl_ops.index_write(codec, *p,
++				*(p+rt_codec.number/2));
++		}
++		break;		
++
++	default:
++		if (NULL == rt_codec_ioctl_ops.ioctl_common)
++			goto err;
++
++		rt_codec_ioctl_ops.ioctl_common(hw, file, cmd, arg);
++		break;
++	}
++
++	kfree(buf);
++	return 0;
++
++err:
++	kfree(buf);
++	return -EFAULT;
++}
++
++static int rt_codec_codec_dump_reg(struct snd_hwdep *hw,
++		struct file *file, unsigned long arg)
++{
++	struct snd_soc_codec *codec = hw->private_data;
++	struct rt_codec_cmd __user *_rt_codec =(struct rt_codec_cmd *)arg;
++	struct rt_codec_cmd rt_codec;
++	int i, *buf, number = codec->driver->reg_cache_size;
++
++	dev_dbg(codec->dev, "enter %s, number = %d\n", __func__, number);
++	if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec)))
++		return -EFAULT;
++	
++	buf = kmalloc(sizeof(*buf) * number, GFP_KERNEL);
++	if (buf == NULL)
++		return -ENOMEM;
++
++	for (i = 0; i < number/2; i++) {
++		buf[i] = i << 1;
++		buf[i + number / 2] = codec->read(codec, buf[i]);
++	}
++	if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * i))
++		goto err;
++	rt_codec.number = number;
++	if (copy_to_user(_rt_codec, &rt_codec, sizeof(rt_codec)))
++		goto err;
++	kfree(buf);
++	return 0;
++
++err:
++	kfree(buf);
++	return -EFAULT;
++}
++
++static int rt_codec_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
++			unsigned int cmd, unsigned long arg)
++{
++	switch (cmd) {
++	case RT_READ_ALL_CODEC_REG_IOCTL:
++		return rt_codec_codec_dump_reg(hw, file, arg);
++
++	default:
++		return rt_codec_hwdep_ioctl_common(hw, file, cmd, arg);
++	}
++
++	return 0;
++}
++
++int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
++{
++	struct snd_hwdep *hw;
++	struct snd_card *card = codec->card->snd_card;
++	int err;
++
++	dev_dbg(codec->dev, "enter %s\n", __func__);
++
++	if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0)
++		return err;
++	
++	strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME);
++	hw->private_data = codec;
++	hw->ops.open = rt_codec_hwdep_open;
++	hw->ops.release = rt_codec_hwdep_release;
++	hw->ops.ioctl = rt_codec_hwdep_ioctl;
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(realtek_ce_init_hwdep);
++#endif
++
++struct rt_codec_ops *rt_codec_get_ioctl_ops(void)
++{
++	return &rt_codec_ioctl_ops;
++}
++EXPORT_SYMBOL_GPL(rt_codec_get_ioctl_ops);
+diff --git a/sound/soc/codecs/rt_codec_ioctl.h b/sound/soc/codecs/rt_codec_ioctl.h
+new file mode 100644
+index 00000000..56daa371
+--- /dev/null
++++ b/sound/soc/codecs/rt_codec_ioctl.h
+@@ -0,0 +1,78 @@
++/*
++ * rt_codec_ioctl.h  --  RT56XX ALSA SoC audio driver IO control
++ *
++ * Copyright 2012 Realtek Microelectronics
++ * Author: Bard <bardliao@realtek.com>
++ *
++ * 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.
++ */
++
++#ifndef __RT56XX_IOCTL_H__
++#define __RT56XX_IOCTL_H__
++
++#include <sound/hwdep.h>
++#include <linux/ioctl.h>
++
++struct rt_codec_cmd {
++	size_t number;
++	int __user *buf;
++};
++
++struct rt_codec_ops {
++	int (*index_write)(struct snd_soc_codec *codec,
++		unsigned int reg, unsigned int value);
++	unsigned int (*index_read)(struct snd_soc_codec *codec,
++				unsigned int reg);
++	int (*index_update_bits)(struct snd_soc_codec *codec,
++		unsigned int reg, unsigned int mask, unsigned int value);
++	int (*ioctl_common)(struct snd_hwdep *hw, struct file *file,
++			unsigned int cmd, unsigned long arg);
++};
++
++enum {
++	RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt_codec_cmd),
++	RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x01, struct rt_codec_cmd),
++	RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt_codec_cmd),
++	RT_READ_CODEC_INDEX_IOCTL = _IOR('R', 0x03, struct rt_codec_cmd),
++	RT_WRITE_CODEC_INDEX_IOCTL = _IOW('R', 0x03, struct rt_codec_cmd),
++	RT_READ_CODEC_DSP_IOCTL = _IOR('R', 0x04, struct rt_codec_cmd),
++	RT_WRITE_CODEC_DSP_IOCTL = _IOW('R', 0x04, struct rt_codec_cmd),
++	RT_SET_CODEC_HWEQ_IOCTL = _IOW('R', 0x05, struct rt_codec_cmd),
++	RT_GET_CODEC_HWEQ_IOCTL = _IOR('R', 0x05, struct rt_codec_cmd),
++	RT_SET_CODEC_SPK_VOL_IOCTL = _IOW('R', 0x06, struct rt_codec_cmd),
++	RT_GET_CODEC_SPK_VOL_IOCTL = _IOR('R', 0x06, struct rt_codec_cmd),
++	RT_SET_CODEC_MIC_GAIN_IOCTL = _IOW('R', 0x07, struct rt_codec_cmd),
++	RT_GET_CODEC_MIC_GAIN_IOCTL = _IOR('R', 0x07, struct rt_codec_cmd),
++	RT_SET_CODEC_3D_SPK_IOCTL = _IOW('R', 0x08, struct rt_codec_cmd),
++	RT_GET_CODEC_3D_SPK_IOCTL = _IOR('R', 0x08, struct rt_codec_cmd),
++	RT_SET_CODEC_MP3PLUS_IOCTL = _IOW('R', 0x09, struct rt_codec_cmd),
++	RT_GET_CODEC_MP3PLUS_IOCTL = _IOR('R', 0x09, struct rt_codec_cmd),
++	RT_SET_CODEC_3D_HEADPHONE_IOCTL = _IOW('R', 0x0a, struct rt_codec_cmd),
++	RT_GET_CODEC_3D_HEADPHONE_IOCTL = _IOR('R', 0x0a, struct rt_codec_cmd),
++	RT_SET_CODEC_BASS_BACK_IOCTL = _IOW('R', 0x0b, struct rt_codec_cmd),
++	RT_GET_CODEC_BASS_BACK_IOCTL = _IOR('R', 0x0b, struct rt_codec_cmd),
++	RT_SET_CODEC_DIPOLE_SPK_IOCTL = _IOW('R', 0x0c, struct rt_codec_cmd),
++	RT_GET_CODEC_DIPOLE_SPK_IOCTL = _IOR('R', 0x0c, struct rt_codec_cmd),
++	RT_SET_CODEC_DRC_AGC_ENABLE_IOCTL = _IOW('R', 0x0d, struct rt_codec_cmd),
++	RT_GET_CODEC_DRC_AGC_ENABLE_IOCTL = _IOR('R', 0x0d, struct rt_codec_cmd),
++	RT_SET_CODEC_DSP_MODE_IOCTL = _IOW('R', 0x0e, struct rt_codec_cmd),
++	RT_GET_CODEC_DSP_MODE_IOCTL = _IOR('R', 0x0e, struct rt_codec_cmd),
++	RT_SET_CODEC_WNR_ENABLE_IOCTL = _IOW('R', 0x0f, struct rt_codec_cmd),
++	RT_GET_CODEC_WNR_ENABLE_IOCTL = _IOR('R', 0x0f, struct rt_codec_cmd),
++	RT_SET_CODEC_DRC_AGC_PAR_IOCTL = _IOW('R', 0x10, struct rt_codec_cmd),
++	RT_GET_CODEC_DRC_AGC_PAR_IOCTL = _IOR('R', 0x10, struct rt_codec_cmd),
++	RT_SET_CODEC_DIGI_BOOST_GAIN_IOCTL = _IOW('R', 0x11, struct rt_codec_cmd),
++	RT_GET_CODEC_DIGI_BOOST_GAIN_IOCTL = _IOR('R', 0x11, struct rt_codec_cmd),
++	RT_SET_CODEC_NOISE_GATE_IOCTL = _IOW('R', 0x12, struct rt_codec_cmd),
++	RT_GET_CODEC_NOISE_GATE_IOCTL = _IOR('R', 0x12, struct rt_codec_cmd),
++	RT_SET_CODEC_DRC_AGC_COMP_IOCTL = _IOW('R', 0x13, struct rt_codec_cmd),
++	RT_GET_CODEC_DRC_AGC_COMP_IOCTL = _IOR('R', 0x13, struct rt_codec_cmd),
++	RT_GET_CODEC_ID = _IOR('R', 0x30, struct rt_codec_cmd),
++};
++
++int realtek_ce_init_hwdep(struct snd_soc_codec *codec);
++struct rt_codec_ops *rt_codec_get_ioctl_ops(void);
++
++#endif /* __RT56XX_IOCTL_H__ */
+diff --git a/sound/soc/codecs/tlv320adc3xxx_amb.c b/sound/soc/codecs/tlv320adc3xxx_amb.c
+new file mode 100644
+index 00000000..a914fdd4
+--- /dev/null
++++ b/sound/soc/codecs/tlv320adc3xxx_amb.c
+@@ -0,0 +1,1215 @@
++/*
++ * sound/soc/codecs/tlv320adc3xxx_amb.c
++ *
++ * Author: Dongge wu <dgwu@ambarella.com>
++ *
++ * History:
++ *	2015/10/28 - [Dongge wu] Created file
++ *
++ * Copyright (C) 2014-2018, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++
++/***************************** INCLUDES ************************************/
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <linux/cdev.h>
++#include <linux/of_gpio.h>
++#include <linux/slab.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++
++#include "tlv320adc3xxx_amb.h"
++
++/*
++ * ****************************************************************************
++ *  Macros
++ * ****************************************************************************
++ *
++ */
++
++
++/* codec private data */
++struct adc3xxx_priv {
++	void *control_data;
++	unsigned int rst_pin;
++	unsigned int rst_active;
++	unsigned int sysclk;
++	int master;
++	u8 page_no;
++};
++
++static int adc3xxx_set_bias_level(struct snd_soc_codec *,
++				  enum snd_soc_bias_level);
++/*
++ * ADC3xxx register cache
++ * We can't read the ADC3xxx register space when we are
++ * using 2 wire for device control, so we cache them instead.
++ * There is no point in caching the reset register
++ */
++static const u8 adc3xxx_reg[ADC3xxx_CACHEREGNUM] = {
++	0x00, 0x00, 0x00, 0x00,	/* 0 */
++	0x00, 0x11, 0x04, 0x00,	/* 4 */
++	0x00, 0x00, 0x00, 0x00,	/* 8 */
++	0x00, 0x00, 0x00, 0x00,	/* 12 */
++	0x00, 0x00, 0x01, 0x01,	/* 16 */
++	0x80, 0x80, 0x04, 0x00,	/* 20 */
++	0x00, 0x00, 0x01, 0x00,	/* 24 */
++	0x00, 0x02, 0x01, 0x00,	/* 28 */
++	0x00, 0x10, 0x00, 0x00,	/* 32 */
++	0x00, 0x00, 0x02, 0x00,	/* 36 */
++	0x00, 0x00, 0x00, 0x00,	/* 40 */
++	0x00, 0x00, 0x00, 0x00,	/* 44 */
++	0x00, 0x00, 0x00, 0x00,	/* 48 */
++	0x00, 0x12, 0x00, 0x00,	/* 52 */
++	0x00, 0x00, 0x00, 0x44,	/* 56 */
++	0x00, 0x01, 0x00, 0x00,	/* 60 */
++	0x00, 0x00, 0x00, 0x00,	/* 64 */
++	0x00, 0x00, 0x00, 0x00,	/* 68 */
++	0x00, 0x00, 0x00, 0x00,	/* 72 */
++	0x00, 0x00, 0x00, 0x00,	/* 76 */
++	0x00, 0x00, 0x88, 0x00,	/* 80 */
++	0x00, 0x00, 0x00, 0x00,	/* 84 */
++	0x7F, 0x00, 0x00, 0x00,	/* 88 */
++	0x00, 0x00, 0x00, 0x00,	/* 92 */
++	0x7F, 0x00, 0x00, 0x00,	/* 96 */
++	0x00, 0x00, 0x00, 0x00,	/* 100 */
++	0x00, 0x00, 0x00, 0x00,	/* 104 */
++	0x00, 0x00, 0x00, 0x00,	/* 108 */
++	0x00, 0x00, 0x00, 0x00,	/* 112 */
++	0x00, 0x00, 0x00, 0x00,	/* 116 */
++	0x00, 0x00, 0x00, 0x00,	/* 120 */
++	0x00, 0x00, 0x00, 0x00,	/* 124 - PAGE0 Registers(127) ends here */
++	0x00, 0x00, 0x00, 0x00,	/* 128, PAGE1-0 */
++	0x00, 0x00, 0x00, 0x00,	/* 132, PAGE1-4 */
++	0x00, 0x00, 0x00, 0x00,	/* 136, PAGE1-8 */
++	0x00, 0x00, 0x00, 0x00,	/* 140, PAGE1-12 */
++	0x00, 0x00, 0x00, 0x00,	/* 144, PAGE1-16 */
++	0x00, 0x00, 0x00, 0x00,	/* 148, PAGE1-20 */
++	0x00, 0x00, 0x00, 0x00,	/* 152, PAGE1-24 */
++	0x00, 0x00, 0x00, 0x00,	/* 156, PAGE1-28 */
++	0x00, 0x00, 0x00, 0x00,	/* 160, PAGE1-32 */
++	0x00, 0x00, 0x00, 0x00,	/* 164, PAGE1-36 */
++	0x00, 0x00, 0x00, 0x00,	/* 168, PAGE1-40 */
++	0x00, 0x00, 0x00, 0x00,	/* 172, PAGE1-44 */
++	0x00, 0x00, 0x00, 0x00,	/* 176, PAGE1-48 */
++	0xFF, 0x00, 0x3F, 0xFF,	/* 180, PAGE1-52 */
++	0x00, 0x3F, 0x00, 0x80,	/* 184, PAGE1-56 */
++	0x80, 0x00, 0x00, 0x00,	/* 188, PAGE1-60 */
++};
++
++/*
++ * adc3xxx initialization data
++ * This structure initialization contains the initialization required for
++ * ADC3xxx.
++ * These registers values (reg_val) are written into the respective ADC3xxx
++ * register offset (reg_offset) to  initialize ADC3xxx.
++ * These values are used in adc3xxx_init() function only.
++ */
++struct adc3xxx_configs {
++	u8 reg_offset;
++	u8 reg_val;
++};
++
++/* The global Register Initialization sequence Array. During the Audio Driver
++ * Initialization, this array will be utilized to perform the default
++ * initialization of the audio Driver.
++ */
++static const struct adc3xxx_configs adc3xxx_reg_init[] = {
++	/* Select IN1L/IN1R Single Ended (0dB) inputs
++	 * use value 10 for no connection, this enables dapm
++	 * to switch ON/OFF inputs using MS Bit only.
++	 * with this setup, -6dB input option is not used.
++	 */
++	{LEFT_PGA_SEL_1, 0xA8},
++	{LEFT_PGA_SEL_2, 0x37},
++	{RIGHT_PGA_SEL_1, 0x28},
++	/* mute Left PGA + default gain */
++	{LEFT_APGA_CTRL, 0xc6},
++	/* mute Right PGA + default gain */
++	{RIGHT_APGA_CTRL, 0xc6},
++	{LEFT_CHN_AGC_1, 0x80},
++	{RIGHT_CHN_AGC_1, 0x80},
++	/* MICBIAS1=2.5V, MICBIAS2=2.5V */
++	{MICBIAS_CTRL, 0x50},
++	/* Use PLL for generating clocks from MCLK */
++	{CLKGEN_MUX, USE_PLL},
++	/* I2S, 16LE, codec as Master */
++	{INTERFACE_CTRL_1, 0x0C},
++	/*BDIV_CLKIN = ADC_CLK, BCLK & WCLK active when power-down */
++	{INTERFACE_CTRL_2, 0x02},
++
++	#ifdef ADC3101_CODEC_SUPPORT
++	/* Use Primary BCLK and WCLK */
++	{INTERFACE_CTRL_4, 0x0},
++	#endif
++
++	/* Left AGC Maximum Gain to 40db */
++	{LEFT_CHN_AGC_3, 0x50},
++	/* Right AGC Maximum Gain to 40db */
++	{RIGHT_CHN_AGC_3, 0X50},
++	/* ADC control, Gain soft-stepping disabled */
++	{ADC_DIGITAL, 0x02},
++	/* Fine Gain 0dB, Left/Right ADC Unmute */
++	{ADC_FGA, 0x00},
++
++	#ifdef ADC3101_CODEC_SUPPORT
++	/* DMCLK output = ADC_MOD_CLK */
++	{GPIO2_CTRL, 0x28},
++	/* DMDIN is in Dig_Mic_In mode */
++	{GPIO1_CTRL, 0x04},
++	#endif
++};
++
++/*
++ * PLL and Clock settings
++ */
++static const struct adc3xxx_rate_divs adc3xxx_divs[] = {
++	/*  mclk, rate, p, r, j, d, nadc, madc, aosr, bdiv */
++	/* 8k rate */
++	{12288000, 8000, 1, 1, 7, 0000, 42, 2, 128, 8, 188},
++	/* 11.025k rate */
++	//{12000000, 11025, 1, 1, 6, 8208, 29, 2, 128, 8, 188},
++	/* 16k rate */
++	{12288000, 16000, 1, 1, 7, 0000, 21, 2, 128, 8, 188},
++	/* 22.05k rate */
++	//{12000000, 22050, 1, 1, 7, 560, 15, 2, 128, 8, 188},
++	/* 32k rate */
++	{12288000, 32000, 1, 1, 8, 0000, 12, 2, 128, 8, 188},
++	/* 44.1k rate */
++	//{12000000, 44100, 1, 1, 7, 5264, 8, 2, 128, 8, 188},
++	/* 48k rate */
++	{12288000, 48000, 1, 1, 7, 0000, 7, 2, 128, 8, 188},
++	/* 88.2k rate */
++	//{12000000, 88200, 1, 1, 7, 5264, 4, 4, 64, 8, 188},
++	/* 96k rate */
++	//{12000000, 96000, 1, 1, 8, 1920, 4, 4, 64, 8, 188},
++};
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_get_divs
++ * Purpose  : This function is to get required divisor from the "adc3xxx_divs"
++ *            table.
++ *
++ *----------------------------------------------------------------------------
++ */
++static inline int adc3xxx_get_divs(int mclk, int rate)
++{
++	int i;
++
++	printk(KERN_INFO "adc3xxx_get_divs mclk = %d, rate = %d\n", mclk, rate);
++	for (i = 0; i < ARRAY_SIZE(adc3xxx_divs); i++) {
++		if ((adc3xxx_divs[i].rate == rate)
++		    && (adc3xxx_divs[i].mclk == mclk)) {
++			return i;
++		}
++	}
++
++	printk("Master clock and sample rate is not supported\n");
++	return -EINVAL;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_change_page
++ * Purpose  : This function is to switch between page 0 and page 1.
++ *
++ *----------------------------------------------------------------------------
++ */
++int adc3xxx_change_page(struct snd_soc_codec *codec, u8 new_page)
++{
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++
++	if (i2c_smbus_write_byte_data(codec->control_data, 0x0, new_page) < 0) {
++		printk("adc3xxx_change_page: I2C Wrte Error\n");
++		return -1;
++	}
++	adc3xxx->page_no = new_page;
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_write_reg_cache
++ * Purpose  : This function is to write adc3xxx register cache
++ *
++ *----------------------------------------------------------------------------
++ */
++static inline void adc3xxx_write_reg_cache(struct snd_soc_codec *codec,
++					   unsigned int reg, unsigned int value)
++{
++	u8 *cache = codec->reg_cache;
++	if (reg >= ADC3xxx_CACHEREGNUM)
++		return;
++	cache[reg] = value & 0xFF;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_read_reg_cache
++ * Purpose  : This function is to read adc3xxx register cache
++ *
++ *----------------------------------------------------------------------------
++ */
++static inline unsigned int adc3xxx_read_reg_cache(struct snd_soc_codec *codec,
++						  unsigned int reg)
++{
++	u8 *cache = codec->reg_cache;
++	if (reg >= ADC3xxx_CACHEREGNUM)
++		return -1;
++	return cache[reg];
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_write
++ * Purpose  : This function is to write to the adc3xxx register space.
++ *
++ *----------------------------------------------------------------------------
++ */
++int adc3xxx_write(struct snd_soc_codec *codec, unsigned int reg,
++		  unsigned int value)
++{
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++	u8 data[2];
++	u8 page;
++
++	page = reg / ADC3xxx_PAGE_SIZE;
++
++	if (adc3xxx->page_no != page) {
++		adc3xxx_change_page(codec, page);
++	}
++
++	/* data is
++	 *   D15..D8 adc3xxx register offset
++	 *   D7...D0 register data
++	 */
++	data[0] = reg % ADC3xxx_PAGE_SIZE;
++	data[1] = value & 0xFF;
++
++	if (i2c_smbus_write_byte_data(codec->control_data, data[0], data[1]) < 0) {
++		printk("adc3xxx_write: I2C write Error\n");
++		return -EIO;
++	}
++
++	/* Update register cache */
++	if ((page == 0) || (page == 1)) {
++		adc3xxx_write_reg_cache(codec, reg, data[1]);
++	}
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_read
++ * Purpose  : This function is to read the adc3xxx register space.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++	u8 value, page;
++
++	page = reg / ADC3xxx_PAGE_SIZE;
++	if (adc3xxx->page_no != page) {
++		adc3xxx_change_page(codec, page);
++	}
++
++	/* write register address */
++	reg = reg % ADC3xxx_PAGE_SIZE;
++
++	/*  read register value */
++	value = i2c_smbus_read_word_data(codec->control_data, reg);
++	if (value < 0) {
++		printk("adc3xxx_read: I2C read Error\n");
++		return -EIO;
++	}
++
++	/* Update register cache */
++	if ((page == 0) || (page == 1)) {
++		adc3xxx_write_reg_cache(codec, reg, value);
++	}
++	return value;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : snd_soc_adc3xxx_put_volsw
++ * Purpose  : Callback to set the value of a mixer control.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int snd_soc_adc3xxx_put_volsw(struct snd_kcontrol *kcontrol,
++				     struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	s8 val1, val2;
++	u8 reg;
++
++	val1 = ucontrol->value.integer.value[0];
++	val2 = ucontrol->value.integer.value[1];
++
++	if ((val1 >= ADC_POS_VOL)) {
++		if (val1 > ADC_MAX_VOLUME)
++			val1 = ADC_MAX_VOLUME;
++		val1 = val1 - ADC_POS_VOL;
++	} else if ((val1 >= 0) && (val1 <= 23)) {
++		val1 = ADC_POS_VOL - val1;
++		val1 = 128 - val1;
++	} else
++		return -EINVAL;
++
++	if (val2 >= ADC_POS_VOL) {
++		if (val2 > ADC_MAX_VOLUME)
++			val2 = ADC_MAX_VOLUME;
++		val2 = val2 - ADC_POS_VOL;
++	} else if ((val2 >= 0) && (val2 <= 23)) {
++		val2 = ADC_POS_VOL - val2;
++		val2 = 128 - val2;
++	} else
++		return -EINVAL;
++
++	reg = adc3xxx_read_reg_cache(codec, LADC_VOL) & (~0x7F);
++	adc3xxx_write(codec, LADC_VOL, reg | (val1 << 0));
++	reg = adc3xxx_read_reg_cache(codec, RADC_VOL) & (~0x7F);
++	adc3xxx_write(codec, RADC_VOL, reg | (val2 << 0));
++
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : snd_soc_adc3xxx_get_volsw
++ * Purpose  : Callback to get the value of a mixer control.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int snd_soc_adc3xxx_get_volsw(struct snd_kcontrol *kcontrol,
++				     struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	u8 val1;
++	u8 val2;
++
++	val1 = adc3xxx_read_reg_cache(codec, LADC_VOL) & (0x7F);
++	if ((val1 >= 0) && (val1 <= 40)) {
++		val1 = val1 + ADC_POS_VOL;
++	} else if ((val1 >= 104) && (val1 <= 127)) {
++		val1 = val1 - 104;
++	} else
++		return -EINVAL;
++
++	val2 = adc3xxx_read_reg_cache(codec, RADC_VOL) & (0x7F);
++	if ((val2 >= 0) && (val2 <= 40)) {
++		val2 = val2 + ADC_POS_VOL;
++	} else if ((val2 >= 104) && (val2 <= 127)) {
++		val2 = val2 - 104;
++	} else
++		return -EINVAL;
++
++	ucontrol->value.integer.value[0] = val1;
++	ucontrol->value.integer.value[1] = val2;
++	return 0;
++
++}
++
++#define SOC_ADC3xxx_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
++{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
++        .get = snd_soc_adc3xxx_get_volsw, .put = snd_soc_adc3xxx_put_volsw, \
++        .private_value = (unsigned long)&(struct soc_mixer_control) \
++                {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
++                .max = xmax, .invert = xinvert} }
++
++static const char *micbias_voltage[] = { "off", "2V", "2.5V", "AVDD" };
++static const char *linein_attenuation[] = { "0db", "-6db" };
++static const char *adc_softstepping[] = { "1 step", "2 step", "off" };
++
++#define MICBIAS1_ENUM		0
++#define MICBIAS2_ENUM		1
++#define ATTLINEL1_ENUM		2
++#define ATTLINEL2_ENUM		3
++#define ATTLINEL3_ENUM		4
++#define ATTLINER1_ENUM		5
++#define ATTLINER2_ENUM		6
++#define ATTLINER3_ENUM		7
++#define ADCSOFTSTEP_ENUM	8
++
++/* Creates an array of the Single Ended Widgets*/
++static const struct soc_enum adc3xxx_enum[] = {
++	SOC_ENUM_SINGLE(MICBIAS_CTRL, 5, 4, micbias_voltage),
++	SOC_ENUM_SINGLE(MICBIAS_CTRL, 3, 4, micbias_voltage),
++	SOC_ENUM_SINGLE(LEFT_PGA_SEL_1, 0, 2, linein_attenuation),
++	SOC_ENUM_SINGLE(LEFT_PGA_SEL_1, 2, 2, linein_attenuation),
++	SOC_ENUM_SINGLE(LEFT_PGA_SEL_1, 4, 2, linein_attenuation),
++	SOC_ENUM_SINGLE(RIGHT_PGA_SEL_1, 0, 2, linein_attenuation),
++	SOC_ENUM_SINGLE(RIGHT_PGA_SEL_1, 2, 2, linein_attenuation),
++	SOC_ENUM_SINGLE(RIGHT_PGA_SEL_1, 4, 2, linein_attenuation),
++	SOC_ENUM_SINGLE(ADC_DIGITAL, 0, 3, adc_softstepping),
++};
++
++/* Various Controls For adc3xxx */
++static const struct snd_kcontrol_new adc3xxx_snd_controls[] = {
++	/* PGA Gain Volume Control */
++	SOC_DOUBLE_R("PGA Gain Volume Control (0=0dB, 80=40dB)",
++		    LEFT_APGA_CTRL, RIGHT_APGA_CTRL, 0, 0x50, 0),
++	/* Audio gain control (AGC) */
++	SOC_DOUBLE_R("Audio Gain Control (AGC)", LEFT_CHN_AGC_1,
++		     RIGHT_CHN_AGC_1, 7, 0x01, 0),
++	/* AGC Target level control */
++	SOC_DOUBLE_R("AGC Target Level Control", LEFT_CHN_AGC_1,
++		     RIGHT_CHN_AGC_1, 4, 0x07, 1),
++	/* AGC Maximum PGA applicable */
++	SOC_DOUBLE_R("AGC Maximum PGA Control", LEFT_CHN_AGC_3,
++		     RIGHT_CHN_AGC_3, 0, 0x50, 0),
++	/* AGC Attack Time control */
++	SOC_DOUBLE_R("AGC Attack Time control", LEFT_CHN_AGC_4,
++		     RIGHT_CHN_AGC_4, 3, 0x1F, 0),
++	/* AGC Decay Time control */
++	SOC_DOUBLE_R("AGC Decay Time control", LEFT_CHN_AGC_5,
++		     RIGHT_CHN_AGC_5, 3, 0x1F, 0),
++	/* AGC Noise Bounce control */
++	SOC_DOUBLE_R("AGC Noise bounce control", LEFT_CHN_AGC_6,
++		     RIGHT_CHN_AGC_6, 0, 0x1F, 0),
++	/* AGC Signal Bounce control */
++	SOC_DOUBLE_R("AGC Signal bounce control", LEFT_CHN_AGC_7,
++		     RIGHT_CHN_AGC_7, 0, 0x0F, 0),
++	/* Mic Bias voltage */
++	SOC_ENUM("Mic Bias 1 Voltage", adc3xxx_enum[MICBIAS1_ENUM]),
++	SOC_ENUM("Mic Bias 2 Voltage", adc3xxx_enum[MICBIAS2_ENUM]),
++	/* ADC soft stepping */
++	SOC_ENUM("ADC soft stepping", adc3xxx_enum[ADCSOFTSTEP_ENUM]),
++	/* Left/Right Input attenuation */
++	SOC_ENUM("Left Linein1 input attenuation",
++		 adc3xxx_enum[ATTLINEL1_ENUM]),
++	SOC_ENUM("Left Linein2 input attenuation",
++		 adc3xxx_enum[ATTLINEL2_ENUM]),
++	SOC_ENUM("Left Linein3 input attenuation",
++		 adc3xxx_enum[ATTLINEL3_ENUM]),
++	SOC_ENUM("Right Linein1 input attenuation",
++		 adc3xxx_enum[ATTLINER1_ENUM]),
++	SOC_ENUM("Right Linein2 input attenuation",
++		 adc3xxx_enum[ATTLINER2_ENUM]),
++	SOC_ENUM("Right Linein3 input attenuation",
++		 adc3xxx_enum[ATTLINER3_ENUM]),
++	/* ADC Volume */
++	SOC_ADC3xxx_DOUBLE_R("ADC Volume Control (0=-12dB, 64=+20dB)", LADC_VOL,
++		 RADC_VOL, 0, 64,0),
++	/* ADC Fine Volume */
++	SOC_SINGLE("Left ADC Fine Volume (0=-0.4dB, 4=0dB)", ADC_FGA, 4, 4, 1),
++	SOC_SINGLE("Right ADC Fine Volume (0=-0.4dB, 4=0dB)", ADC_FGA, 0, 4, 1),
++};
++
++/* Left input selection, Single Ended inputs and Differential inputs */
++static const struct snd_kcontrol_new left_input_mixer_controls[] = {
++	SOC_DAPM_SINGLE("IN1_L switch", LEFT_PGA_SEL_1, 1, 0x1, 1),
++	SOC_DAPM_SINGLE("IN2_L switch", LEFT_PGA_SEL_1, 3, 0x1, 1),
++	SOC_DAPM_SINGLE("IN3_L switch", LEFT_PGA_SEL_1, 5, 0x1, 1),
++	SOC_DAPM_SINGLE("DIF1_L switch", LEFT_PGA_SEL_1, 7, 0x1, 1),
++	SOC_DAPM_SINGLE("DIF2_L switch", LEFT_PGA_SEL_2, 5, 0x1, 1),
++	SOC_DAPM_SINGLE("DIF3_L switch", LEFT_PGA_SEL_2, 3, 0x1, 1), //DIF3_L
++	SOC_DAPM_SINGLE("IN1_R switch", LEFT_PGA_SEL_2, 1, 0x1, 1),
++};
++
++/* Right input selection, Single Ended inputs and Differential inputs */
++static const struct snd_kcontrol_new right_input_mixer_controls[] = {
++	SOC_DAPM_SINGLE("IN1_R switch", RIGHT_PGA_SEL_1, 1, 0x1, 1),
++	SOC_DAPM_SINGLE("IN2_R switch", RIGHT_PGA_SEL_1, 3, 0x1, 1),
++	SOC_DAPM_SINGLE("IN3_R switch", RIGHT_PGA_SEL_1, 5, 0x1, 1),
++	SOC_DAPM_SINGLE("DIF1_R switch", RIGHT_PGA_SEL_1, 7, 0x1, 1), // DIF1_R
++	SOC_DAPM_SINGLE("DIF2_R switch", RIGHT_PGA_SEL_2, 5, 0x1, 1),
++	SOC_DAPM_SINGLE("DIF3_R switch", RIGHT_PGA_SEL_2, 3, 0x1, 1),
++	SOC_DAPM_SINGLE("IN1_L switch", RIGHT_PGA_SEL_2, 1, 0x1, 1),
++};
++
++/* Left Digital Mic input for left ADC */
++static const struct snd_kcontrol_new left_input_dmic_controls[] = {
++	SOC_DAPM_SINGLE("Left ADC switch", ADC_DIGITAL, 3, 0x1, 0),
++};
++
++/* Right Digital Mic input for Right ADC */
++static const struct snd_kcontrol_new right_input_dmic_controls[] = {
++	SOC_DAPM_SINGLE("Right ADC switch", ADC_DIGITAL, 2, 0x1, 0),
++};
++
++/* adc3xxx Widget structure */
++static const struct snd_soc_dapm_widget adc3xxx_dapm_widgets[] = {
++
++	/* Left Input Selection */
++	SND_SOC_DAPM_MIXER("Left Input Selection", SND_SOC_NOPM, 0, 0,
++			   &left_input_mixer_controls[0],
++			   ARRAY_SIZE(left_input_mixer_controls)),
++	/* Right Input Selection */
++	SND_SOC_DAPM_MIXER("Right Input Selection", SND_SOC_NOPM, 0, 0,
++			   &right_input_mixer_controls[0],
++			   ARRAY_SIZE(right_input_mixer_controls)),
++	/*PGA selection */
++	SND_SOC_DAPM_PGA("Left PGA", LEFT_APGA_CTRL, 7, 1, NULL, 0),
++	SND_SOC_DAPM_PGA("Right PGA", RIGHT_APGA_CTRL, 7, 1, NULL, 0),
++
++	/*Digital Microphone Input Control for Left/Right ADC */
++	SND_SOC_DAPM_MIXER("Left DMic Input", SND_SOC_NOPM, 0, 0,
++			&left_input_dmic_controls[0],
++			ARRAY_SIZE(left_input_dmic_controls)),
++	SND_SOC_DAPM_MIXER("Right DMic Input", SND_SOC_NOPM , 0, 0,
++			&right_input_dmic_controls[0],
++			ARRAY_SIZE(right_input_dmic_controls)),
++
++	/* Left/Right ADC */
++	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ADC_DIGITAL, 7, 0),
++	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ADC_DIGITAL, 6, 0),
++
++	/* Inputs */
++	SND_SOC_DAPM_INPUT("IN1_L"),
++	SND_SOC_DAPM_INPUT("IN1_R"),
++	SND_SOC_DAPM_INPUT("IN2_L"),
++	SND_SOC_DAPM_INPUT("IN2_R"),
++	SND_SOC_DAPM_INPUT("IN3_L"),
++	SND_SOC_DAPM_INPUT("IN3_R"),
++	SND_SOC_DAPM_INPUT("DIF1_L"),
++	SND_SOC_DAPM_INPUT("DIF2_L"),
++	SND_SOC_DAPM_INPUT("DIF3_L"),
++	SND_SOC_DAPM_INPUT("DIF1_R"),
++	SND_SOC_DAPM_INPUT("DIF2_R"),
++	SND_SOC_DAPM_INPUT("DIF3_R"),
++	SND_SOC_DAPM_INPUT("DMic_L"),
++	SND_SOC_DAPM_INPUT("DMic_R"),
++
++};
++
++/* DAPM Routing related array declaratiom */
++static const struct snd_soc_dapm_route intercon[] = {
++/* Left input selection from switchs */
++	{"Left Input Selection", "IN1_L switch", "IN1_L"},
++	{"Left Input Selection", "IN2_L switch", "IN2_L"},
++	{"Left Input Selection", "IN3_L switch", "IN3_L"},
++	{"Left Input Selection", "DIF1_L switch", "DIF1_L"},
++	{"Left Input Selection", "DIF2_L switch", "DIF2_L"},
++	{"Left Input Selection", "DIF3_L switch", "DIF3_L"},
++	{"Left Input Selection", "IN1_R switch", "IN1_R"},
++
++/* Left input selection to left PGA */
++	{"Left PGA", NULL, "Left Input Selection"},
++
++/* Left PGA to left ADC */
++	{"Left ADC", NULL, "Left PGA"},
++
++/* Right input selection from switchs */
++	{"Right Input Selection", "IN1_R switch", "IN1_R"},
++	{"Right Input Selection", "IN2_R switch", "IN2_R"},
++	{"Right Input Selection", "IN3_R switch", "IN3_R"},
++	{"Right Input Selection", "DIF1_R switch", "DIF1_R"},
++	{"Right Input Selection", "DIF2_R switch", "DIF2_R"},
++	{"Right Input Selection", "DIF3_R switch", "DIF3_R"},
++	{"Right Input Selection", "IN1_L switch", "IN1_L"},
++
++/* Right input selection to right PGA */
++	{"Right PGA", NULL, "Right Input Selection"},
++
++/* Right PGA to right ADC */
++	{"Right ADC", NULL, "Right PGA"},
++
++/* Left DMic Input selection from switch */
++	{"Left DMic Input", "Left ADC switch", "DMic_L"},
++
++/* Left DMic to left ADC */
++	{"Left ADC", NULL, "Left DMic Input"},
++
++/* Right DMic Input selection from switch */
++	{"Right DMic Input", "Right ADC switch", "DMic_R"},
++
++/* Right DMic to right ADC */
++	{"Right ADC", NULL, "Right DMic Input"},
++};
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_hw_params
++ * Purpose  : This function is to set the hardware parameters for adc3xxx.
++ *            The functions set the sample rate and audio serial data word
++ *            length.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_hw_params(struct snd_pcm_substream *substream,
++			     struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++	int i, width = 16;
++	u8 data, bdiv;
++
++	i = adc3xxx_get_divs(adc3xxx->sysclk, params_rate(params));
++
++	if (i < 0) {
++		printk("Clock configuration is not supported\n");
++		return i;
++	}
++
++	/* select data word length */
++	data =
++	    adc3xxx_read_reg_cache(codec, INTERFACE_CTRL_1) & (~WLENGTH_MASK);
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		width = 16;
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		data |= (0x01 << 4);
++		width = 20;
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		data |= (0x02 << 4);
++		width = 24;
++		break;
++	case SNDRV_PCM_FORMAT_S32_LE:
++		data |= (0x03 << 4);
++		width = 32;
++		break;
++	}
++	adc3xxx_write(codec, INTERFACE_CTRL_1, data);
++
++	/* BCLK is derived from ADC_CLK */
++	if (width == 16) {
++		bdiv = adc3xxx_divs[i].bdiv_n;
++	} else {
++		bdiv =
++		    (adc3xxx_divs[i].aosr * adc3xxx_divs[i].madc) / (2 * width);
++	}
++
++	/* P & R values */
++	adc3xxx_write(codec, PLL_PROG_PR,
++		      (adc3xxx_divs[i].pll_p << PLLP_SHIFT) | (adc3xxx_divs[i].
++							       pll_r <<
++							       PLLR_SHIFT));
++	/* J value */
++	adc3xxx_write(codec, PLL_PROG_J, adc3xxx_divs[i].pll_j & PLLJ_MASK);
++	/* D value */
++	adc3xxx_write(codec, PLL_PROG_D_LSB,
++		      adc3xxx_divs[i].pll_d & PLLD_LSB_MASK);
++	adc3xxx_write(codec, PLL_PROG_D_MSB,
++		      (adc3xxx_divs[i].pll_d >> 8) & PLLD_MSB_MASK);
++	/* NADC */
++	adc3xxx_write(codec, ADC_NADC, adc3xxx_divs[i].nadc & NADC_MASK);
++	/* MADC */
++	adc3xxx_write(codec, ADC_MADC, adc3xxx_divs[i].madc & MADC_MASK);
++	/* AOSR */
++	adc3xxx_write(codec, ADC_AOSR, adc3xxx_divs[i].aosr & AOSR_MASK);
++	/* BDIV N Value */
++	adc3xxx_write(codec, BCLK_N_DIV, bdiv & BDIV_MASK);
++	msleep(10);
++
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_set_dai_sysclk
++ * Purpose  : This function is to set the DAI system clock
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++				  int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++
++	adc3xxx->sysclk = freq;
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_set_dai_fmt
++ * Purpose  : This function is to set the DAI format
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++	u8 iface_reg;
++
++	iface_reg =
++	    adc3xxx_read_reg_cache(codec, INTERFACE_CTRL_1) & (~FMT_MASK);
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		adc3xxx->master = 1;
++		iface_reg |= BCLK_MASTER | WCLK_MASTER;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		adc3xxx->master = 0;
++		iface_reg &= ~ (BCLK_MASTER | WCLK_MASTER ); //new repladec | with &
++		break;
++	case SND_SOC_DAIFMT_CBS_CFM: //new case..just for debugging
++		printk("%s: SND_SOC_DAIFMT_CBS_CFM\n", __FUNCTION__);
++		adc3xxx->master = 0;
++		/* BCLK by codec ie BCLK output */
++		iface_reg |=  (BCLK_MASTER);
++		iface_reg &= ~(WCLK_MASTER);
++
++		break;
++	default:
++		printk("Invalid DAI master/slave interface\n");
++		return -EINVAL;
++	}
++
++	/*
++	 * match both interface format and signal polarities since they
++	 * are fixed
++	 */
++	switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK)) {
++	case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
++		break;
++	case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
++		iface_reg |= (0x01 << 6);
++		break;
++	case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
++		iface_reg |= (0x01 << 6);
++		break;
++	case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
++		iface_reg |= (0x02 << 6);
++		break;
++	case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
++		iface_reg |= (0x03 << 6);
++		break;
++	default:
++		printk("Invalid DAI format\n");
++		return -EINVAL;
++	}
++
++	/* set iface */
++	adc3xxx_write(codec, INTERFACE_CTRL_1, iface_reg);
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_set_bias_level
++ * Purpose  : This function is to get triggered when dapm events occurs.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_set_bias_level(struct snd_soc_codec *codec,
++				  enum snd_soc_bias_level level)
++{
++	struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
++	u8 reg;
++
++	/* Check if  the New Bias level is equal to the existing one, if so return */
++	if (codec->dapm.bias_level  == level)
++	return 0;
++
++	/* all power is driven by DAPM system */
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++		if (adc3xxx->master) {
++			/* Enable pll */
++			reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
++			adc3xxx_write(codec, PLL_PROG_PR, reg | ENABLE_PLL);
++
++			/* 10msec delay needed after PLL power-up */
++			mdelay(10);
++
++			/* Switch on NADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
++			adc3xxx_write(codec, ADC_NADC, reg | ENABLE_NADC);
++
++			/* Switch on MADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
++			adc3xxx_write(codec, ADC_MADC, reg | ENABLE_MADC);
++
++			/* Switch on BCLK_N Divider */
++			reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
++			adc3xxx_write(codec, BCLK_N_DIV, reg | ENABLE_BCLK);
++		}
++	      else{ //new
++			/* Enable pll */
++			reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
++			adc3xxx_write(codec, PLL_PROG_PR, reg | ENABLE_PLL);
++
++			/* 10msec delay needed after PLL power-up */
++			mdelay(10);
++
++			/*Switch on NADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
++			adc3xxx_write(codec, ADC_NADC, reg | ENABLE_NADC);
++
++			/* Switch on MADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
++			adc3xxx_write(codec, ADC_MADC, reg | ENABLE_MADC);
++
++			/* Switch on BCLK_N Divider */
++			reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
++			adc3xxx_write(codec, BCLK_N_DIV, reg | ~ENABLE_BCLK);
++
++		}
++		 msleep(350);
++		break;
++
++		/* partial On */
++	case SND_SOC_BIAS_PREPARE:
++		break;
++
++		/* Off, with power */
++	case SND_SOC_BIAS_STANDBY:
++		if (adc3xxx->master) {
++			/* switch off pll */
++			reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
++			adc3xxx_write(codec, PLL_PROG_PR, reg & (~ENABLE_PLL));
++			msleep(10);
++
++			/* Switch off NADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
++			adc3xxx_write(codec, ADC_NADC, reg & (~ENABLE_NADC));
++
++			/* Switch off MADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
++			adc3xxx_write(codec, ADC_MADC, reg & (~ENABLE_MADC));
++
++			/* Switch off BCLK_N Divider */
++			reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
++			adc3xxx_write(codec, BCLK_N_DIV, reg & (~ENABLE_BCLK));
++			msleep(100);
++		}
++		break;
++
++		/* Off without power */
++	case SND_SOC_BIAS_OFF:
++
++		/* power off Left/Right ADC channels */
++		reg = adc3xxx_read_reg_cache(codec, ADC_DIGITAL);
++		adc3xxx_write(codec, ADC_DIGITAL,
++			      reg & ~(LADC_PWR_ON | RADC_PWR_ON));
++
++		/* Turn off PLLs */
++		if (adc3xxx->master) {
++			/* switch off pll */
++			reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
++			adc3xxx_write(codec, PLL_PROG_PR, reg & (~ENABLE_PLL));
++
++			/* Switch off NADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
++			adc3xxx_write(codec, ADC_NADC, reg & (~ENABLE_NADC));
++
++			/* Switch off MADC Divider */
++			reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
++			adc3xxx_write(codec, ADC_MADC, reg & (~ENABLE_MADC));
++
++			/* Switch off BCLK_N Divider */
++			reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
++			adc3xxx_write(codec, BCLK_N_DIV, reg & (~ENABLE_BCLK));
++		}
++		break;
++	}
++	codec->dapm.bias_level = level;
++
++	return 0;
++}
++
++static struct snd_soc_dai_ops adc3xxx_dai_ops = {
++	.hw_params	= adc3xxx_hw_params,
++	.set_sysclk = adc3xxx_set_dai_sysclk,
++	.set_fmt	= adc3xxx_set_dai_fmt,
++};
++
++struct snd_soc_dai_driver adc3xxx_dai = {
++	.name = "tlv320adc3xxx-hifi",
++	.capture = {
++		    .stream_name = "Capture",
++		    .channels_min = 1,
++		    .channels_max = 2,
++		    .rates = ADC3xxx_RATES,
++		    .formats = ADC3xxx_FORMATS,
++		    },
++	.ops = &adc3xxx_dai_ops,
++};
++
++EXPORT_SYMBOL_GPL(adc3xxx_dai);
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : tlv320adc3xxx_init
++ * Purpose  : This function is to initialise the adc3xxx driver
++ *            register the mixer and dsp interfaces with the kernel.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_init(struct snd_soc_codec *codec)
++{
++	int i, ret = 0;
++
++	codec->name = "tlv320adc3xxx";
++	codec->num_dai = 1;
++	codec->reg_cache =
++		kmemdup(adc3xxx_reg, sizeof(adc3xxx_reg), GFP_KERNEL);
++	if (codec->reg_cache == NULL)
++		return -ENOMEM;
++
++	/* Select Page 0 */
++	adc3xxx_write(codec, PAGE_SELECT, 0);
++	/* Issue software reset to adc3xxx */
++	adc3xxx_write(codec, RESET, SOFT_RESET);
++
++	adc3xxx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	for (i = 0;
++	     i < sizeof(adc3xxx_reg_init) / sizeof(struct adc3xxx_configs);
++	     i++) {
++		adc3xxx_write(codec, adc3xxx_reg_init[i].reg_offset,
++			      adc3xxx_reg_init[i].reg_val);
++	}
++
++	//adc3xxx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return ret;
++
++	kfree(codec->reg_cache);
++	return ret;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_probe
++ * Purpose  : This is first driver function called by the SoC core driver.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_probe(struct snd_soc_codec *codec)
++{
++	struct adc3xxx_priv *adc3xxx = NULL;
++	int ret = 0;
++
++	printk(KERN_INFO "ADC3xxx Audio Codec %s provided by Amba Dongge\n", ADC3xxx_VERSION);
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	codec->write = adc3xxx_write;
++	codec->read = adc3xxx_read;
++#endif
++
++	adc3xxx = (struct adc3xxx_priv *)snd_soc_codec_get_drvdata(codec);
++	codec->control_data = adc3xxx->control_data;
++	mutex_init(&codec->mutex);
++
++	ret = devm_gpio_request(codec->dev, adc3xxx->rst_pin, "adc3xxx reset");
++	if (ret < 0){
++		dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
++		return ret;
++	}
++
++	/* Reset adc3xxx codec */
++	gpio_direction_output(adc3xxx->rst_pin, adc3xxx->rst_active);
++	msleep(2);
++	gpio_direction_output(adc3xxx->rst_pin, !adc3xxx->rst_active);
++
++	ret = adc3xxx_init(codec);
++
++	if (ret < 0) {
++		printk(KERN_ERR "adc3xxx: failed to initialise ADC3xxx\n");
++		devm_gpio_free(codec->dev, adc3xxx->rst_pin);
++	}
++
++	return ret;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_remove
++ * Purpose  : to remove adc3xxx soc device
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_remove(struct snd_soc_codec *codec)
++{
++	adc3xxx_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_suspend
++ * Purpose  : This function is to suspend the adc3xxx driver.
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_suspend(struct snd_soc_codec *codec)
++{
++	adc3xxx_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++	return 0;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_resume
++ * Purpose  : This function is to resume the ADC3xxx driver
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_resume(struct snd_soc_codec *codec)
++{
++	snd_soc_cache_sync(codec);
++	adc3xxx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++	return 0;
++}
++
++struct snd_soc_codec_driver soc_codec_dev_adc3xxx = {
++	.probe = adc3xxx_probe,
++	.remove = adc3xxx_remove,
++	.suspend =	adc3xxx_suspend,
++	.resume =	adc3xxx_resume,
++	.set_bias_level = adc3xxx_set_bias_level,
++	.reg_cache_default	= adc3xxx_reg,
++	.reg_cache_size		= ARRAY_SIZE(adc3xxx_reg),
++	.reg_word_size		= sizeof(u8),
++	.reg_cache_step		= 1,
++
++	.controls = adc3xxx_snd_controls,
++	.num_controls = ARRAY_SIZE(adc3xxx_snd_controls),
++	.dapm_widgets = adc3xxx_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(adc3xxx_dapm_widgets),
++	.dapm_routes = intercon,
++	.num_dapm_routes = ARRAY_SIZE(intercon),
++};
++EXPORT_SYMBOL_GPL(soc_codec_dev_adc3xxx);
++
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_i2c_probe
++ * Purpose  : This function attaches the i2c client and initializes
++ *				adc3xxx CODEC.
++ *            NOTE:
++ *            This function is called from i2c core when the I2C address is
++ *            valid.
++ *            If the i2c layer weren't so broken, we could pass this kind of
++ *            data around
++ *
++ *----------------------------------------------------------------------------
++ */
++static int adc3xxx_i2c_probe(struct i2c_client *i2c,
++			     const struct i2c_device_id *id)
++{
++	struct device_node *np = i2c->dev.of_node;
++	struct adc3xxx_priv *adc3xxx = NULL;
++	enum of_gpio_flags flags;
++	int rst_pin;
++	int ret;
++
++	adc3xxx = kzalloc(sizeof(struct adc3xxx_priv), GFP_KERNEL);
++	if (adc3xxx == NULL) {
++		return -ENOMEM;
++	}
++
++	rst_pin = of_get_gpio_flags(np, 0, &flags);
++	if (rst_pin < 0 || !gpio_is_valid(rst_pin))
++		return -ENXIO;
++
++	adc3xxx->rst_pin = rst_pin;
++	adc3xxx->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++	adc3xxx->control_data = i2c;
++
++	i2c_set_clientdata(i2c, adc3xxx);
++	ret = snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_adc3xxx, &adc3xxx_dai, 1);
++	if (ret < 0){
++		kfree(adc3xxx);
++		printk("\t[adc3xxx Error!] %s(%d)\n",__FUNCTION__,__LINE__);
++	}
++
++	return ret;
++}
++
++/*
++ *----------------------------------------------------------------------------
++ * Function : adc3xxx_i2c_remove
++ * Purpose  : This function removes the i2c client and uninitializes
++ *                              adc3xxx CODEC.
++ *            NOTE:
++ *            This function is called from i2c core
++ *            If the i2c layer weren't so broken, we could pass this kind of
++ *            data around
++ *
++ *----------------------------------------------------------------------------
++ */
++static int __exit adc3xxx_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	kfree(i2c_get_clientdata(client));
++	return 0;
++}
++
++static struct of_device_id tlv320adc3xxx_of_match[] = {
++	{ .compatible = "ambarella,tlv320adc3xxx",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, tlv320adc3xxx_of_match);
++
++
++static const struct i2c_device_id adc3xxx_i2c_id[] = {
++	{"tlv320adc3xxx", 0},
++	{}
++};
++
++MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id);
++
++/* machine i2c codec control layer */
++static struct i2c_driver adc3xxx_i2c_driver = {
++	.driver = {
++		   .name = "tlv320adc3xxx-codec",
++		   .owner = THIS_MODULE,
++		   .of_match_table = tlv320adc3xxx_of_match,
++		   },
++	.probe = adc3xxx_i2c_probe,
++	.remove = adc3xxx_i2c_remove,
++	.id_table = adc3xxx_i2c_id,
++};
++#endif
++
++static int __init tlv320adc3xxx_init(void)
++{
++	return i2c_add_driver(&adc3xxx_i2c_driver);
++}
++
++static void __exit tlv320adc3xxx_exit(void)
++{
++	i2c_del_driver(&adc3xxx_i2c_driver);
++}
++
++module_init(tlv320adc3xxx_init);
++module_exit(tlv320adc3xxx_exit);
++
++MODULE_DESCRIPTION("ASoC TLV320ADC3xxx codec driver");
++MODULE_AUTHOR("dgwu@ambarella.com ");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/tlv320adc3xxx_amb.h b/sound/soc/codecs/tlv320adc3xxx_amb.h
+new file mode 100644
+index 00000000..e18f48e3
+--- /dev/null
++++ b/sound/soc/codecs/tlv320adc3xxx_amb.h
+@@ -0,0 +1,378 @@
++/*
++ * sound/soc/codecs/tlv320adc3xxx_amb.H
++ *
++ * Author: Dongge wu <dgwu@ambarella.com>
++ *
++ * History:
++ *	2015/10/28 - [Dongge wu] Created file
++ *
++ * Copyright (C) 2014-2018, Ambarella, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++
++#ifndef _ADC3xxx_AMB_H
++#define _ADC3xxx_AMB_H
++
++#define AUDIO_NAME 			"tlv320adc3xxx"
++#define ADC3xxx_VERSION		"Rev A"
++
++#define ADC3101_CODEC_SUPPORT
++//#define ADC3001_CODEC_SUPPORT
++
++/* Macro enables or disables support for TiLoad in the driver */
++#define ADC3xxx_TiLoad
++//#undef ADC3xxx_TiLoad
++
++/* 8 bit mask value */
++#define ADC3xxx_8BITS_MASK           0xFF
++
++/* Enable slave / master mode for codec */
++#define ADC3xxx_MCBSP_SLAVE //codec master
++//#undef ADC3xxx_MCBSP_SLAVE
++
++
++/****************************************************************************/
++/* 							 Page 0 Registers 						 		*/
++/****************************************************************************/
++
++/* Page select register */
++#define PAGE_SELECT				0
++/* Software reset register */
++#define RESET					1
++
++/* 2-3 Reserved */
++
++/* PLL programming register B */
++#define CLKGEN_MUX				4
++/* PLL P and R-Val */
++#define PLL_PROG_PR				5
++/* PLL J-Val */
++#define PLL_PROG_J				6
++/* PLL D-Val MSB */
++#define PLL_PROG_D_MSB			7
++/* PLL D-Val LSB */
++#define PLL_PROG_D_LSB			8
++
++/* 9-17 Reserved */
++
++/* ADC NADC */
++#define ADC_NADC				18
++/* ADC MADC */
++#define ADC_MADC				19
++/* ADC AOSR */
++#define ADC_AOSR				20
++/* ADC IADC */
++#define ADC_IADC				21
++
++/* 23-24 Reserved */
++
++/* CLKOUT MUX */
++#define CLKOUT_MUX				25
++/* CLOCKOUT M divider value */
++#define CLKOUT_M_DIV			26
++/*Audio Interface Setting Register 1*/
++#define INTERFACE_CTRL_1		27
++/* Data Slot Offset (Ch_Offset_1) */
++#define CH_OFFSET_1				28
++/* ADC interface control 2 */
++#define INTERFACE_CTRL_2		29
++/* BCLK N Divider */
++#define BCLK_N_DIV				30
++/* Secondary audio interface control 1 */
++#define INTERFACE_CTRL_3		31
++/* Secondary audio interface control 2 */
++#define INTERFACE_CTRL_4		32
++/* Secondary audio interface control 3 */
++#define INTERFACE_CTRL_5		33
++/* I2S sync */
++#define I2S_SYNC				34
++
++/* 35 Reserved */
++
++/* ADC flag register */
++#define ADC_FLAG				36
++/* Data slot offset 2 (Ch_Offset_2) */
++#define CH_OFFSET_2				37
++/* I2S TDM control register */
++#define I2S_TDM_CTRL			38
++
++/* 39-41 Reserved */
++
++/* Interrupt flags (overflow) */
++#define INTR_FLAG_1				42
++/* Interrupt flags (overflow) */
++#define INTR_FLAG_2				43
++
++/* 44 Reserved */
++
++/* Interrupt flags ADC */
++#define INTR_FLAG_ADC1			45
++
++/* 46 Reserved */
++
++/* Interrupt flags ADC */
++#define INTR_FLAG_ADC2			47
++/* INT1 interrupt control */
++#define INT1_CTRL				48
++/* INT2 interrupt control */
++#define INT2_CTRL				49
++
++/* 50 Reserved */
++
++/* DMCLK/GPIO2 control */
++#define GPIO2_CTRL				51
++/* DMDIN/GPIO1 control */
++#define GPIO1_CTRL				52
++/* DOUT Control */
++#define DOUT_CTRL				53
++
++/* 54-56 Reserved */
++
++/* ADC sync control 1 */
++#define SYNC_CTRL_1				57
++/* ADC sync control 2 */
++#define SYNC_CTRL_2				58
++/* ADC CIC filter gain control */
++#define CIC_GAIN_CTRL			59
++
++/* 60 Reserved */
++
++/* ADC processing block selection  */
++#define PRB_SELECT				61
++/* Programmable instruction mode control bits */
++#define INST_MODE_CTRL			62
++
++/* 63-79 Reserved */
++
++/* Digital microphone polarity control */
++#define MIC_POLARITY_CTRL		80
++/* ADC Digital */
++#define ADC_DIGITAL				81
++/* ADC Fine Gain Adjust */
++#define	ADC_FGA					82
++/* Left ADC Channel Volume Control */
++#define LADC_VOL				83
++/* Right ADC Channel Volume Control */
++#define RADC_VOL				84
++/* ADC phase compensation */
++#define ADC_PHASE_COMP			85
++/* Left Channel AGC Control Register 1 */
++#define LEFT_CHN_AGC_1			86
++/* Left Channel AGC Control Register 2 */
++#define LEFT_CHN_AGC_2			87
++/* Left Channel AGC Control Register 3 */
++#define LEFT_CHN_AGC_3			88
++/* Left Channel AGC Control Register 4 */
++#define LEFT_CHN_AGC_4			89
++/* Left Channel AGC Control Register 5 */
++#define LEFT_CHN_AGC_5			90
++/* Left Channel AGC Control Register 6 */
++#define LEFT_CHN_AGC_6			91
++/* Left Channel AGC Control Register 7 */
++#define LEFT_CHN_AGC_7			92
++/* Left AGC gain */
++#define LEFT_AGC_GAIN			93
++/* Right Channel AGC Control Register 1 */
++#define RIGHT_CHN_AGC_1			94
++/* Right Channel AGC Control Register 2 */
++#define RIGHT_CHN_AGC_2 		95
++/* Right Channel AGC Control Register 3 */
++#define RIGHT_CHN_AGC_3			96
++/* Right Channel AGC Control Register 4 */
++#define RIGHT_CHN_AGC_4			97
++/* Right Channel AGC Control Register 5 */
++#define RIGHT_CHN_AGC_5			98
++/* Right Channel AGC Control Register 6 */
++#define RIGHT_CHN_AGC_6			99
++/* Right Channel AGC Control Register 7 */
++#define RIGHT_CHN_AGC_7			100
++/* Right AGC gain */
++#define RIGHT_AGC_GAIN			101
++
++/* 102-127 Reserved */
++
++/****************************************************************************/
++/* 							 Page 1 Registers 						 		*/
++/****************************************************************************/
++#define PAGE_1					128
++
++/* 1-25 Reserved */
++
++/* Dither control */
++#define DITHER_CTRL			(PAGE_1 + 26)
++
++/* 27-50 Reserved */
++
++/* MICBIAS Configuration Register */
++#define MICBIAS_CTRL		(PAGE_1 + 51)
++/* Left ADC input selection for Left PGA */
++#define LEFT_PGA_SEL_1		(PAGE_1 + 52)
++
++/* 53 Reserved */
++
++/* Right ADC input selection for Left PGA */
++#define LEFT_PGA_SEL_2		(PAGE_1 + 54)
++/* Right ADC input selection for right PGA */
++#define RIGHT_PGA_SEL_1		(PAGE_1 + 55)
++
++/* 56 Reserved */
++
++/* Right ADC input selection for right PGA */
++#define RIGHT_PGA_SEL_2		(PAGE_1 + 57)
++
++/* 58 Reserved */
++
++/* Left analog PGA settings */
++#define LEFT_APGA_CTRL		(PAGE_1 + 59)
++/* Right analog PGA settings */
++#define RIGHT_APGA_CTRL		(PAGE_1 + 60)
++/* ADC Low current Modes */
++#define LOW_CURRENT_MODES	(PAGE_1 + 61)
++/* ADC analog PGA flags */
++#define ANALOG_PGA_FLAGS	(PAGE_1 + 62)
++
++/* 63-127 Reserved */
++
++/****************************************************************************/
++/*						Macros and definitions							   	*/
++/****************************************************************************/
++
++/* ADC3xxx register space */
++#define ADC3xxx_CACHEREGNUM		192
++#define ADC3xxx_PAGE_SIZE		128
++
++#define ADC3xxx_RATES   SNDRV_PCM_RATE_8000_96000
++#define ADC3xxx_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
++             SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
++
++/* bits defined for easy usage */
++#define D7                    (0x01 << 7)
++#define D6                    (0x01 << 6)
++#define D5                    (0x01 << 5)
++#define D4                    (0x01 << 4)
++#define D3                    (0x01 << 3)
++#define D2                    (0x01 << 2)
++#define D1                    (0x01 << 1)
++#define D0                    (0x01 << 0)
++
++/****************************************************************************/
++/*						ADC3xxx Register bits							   	*/
++/****************************************************************************/
++/* PLL Enable bits */
++#define ENABLE_PLL              D7
++#define ENABLE_NADC             D7
++#define ENABLE_MADC             D7
++#define ENABLE_BCLK             D7
++
++/* Power bits */
++#define LADC_PWR_ON     		D7
++#define RADC_PWR_ON     		D6
++
++#define SOFT_RESET              D0
++#define BCLK_MASTER          	D3
++#define WCLK_MASTER         	D2
++
++/* Interface register masks */
++#define FMT_MASK				(D7|D6|D3|D2)
++#define WLENGTH_MASK			(D5|D4)
++
++/* PLL P/R bit offsets */
++#define PLLP_SHIFT      	4
++#define PLLR_SHIFT      	0
++#define PLL_PR_MASK			0x7F
++#define PLLJ_MASK			0x3F
++#define PLLD_MSB_MASK		0x3F
++#define PLLD_LSB_MASK		0xFF
++#define NADC_MASK			0x7F
++#define MADC_MASK			0x7F
++#define AOSR_MASK			0xFF
++#define IADC_MASK			0xFF
++#define BDIV_MASK			0x7F
++
++/* PLL_CLKIN bits */
++#define PLL_CLKIN_SHIFT			2
++#define PLL_CLKIN_MCLK			0x0
++#define PLL_CLKIN_BCLK			0x1
++#define PLL_CLKIN_ZERO			0x3
++
++/* CODEC_CLKIN bits */
++#define CODEC_CLKIN_SHIFT		0
++#define CODEC_CLKIN_MCLK		0x0
++#define CODEC_CLKIN_BCLK		0x1
++#define CODEC_CLKIN_PLL_CLK		0x3
++
++#define USE_PLL					(PLL_CLKIN_MCLK << PLL_CLKIN_SHIFT) |	\
++					            (CODEC_CLKIN_PLL_CLK << CODEC_CLKIN_SHIFT)
++
++/*  Analog PGA control bits */
++#define LPGA_MUTE				D7
++#define RPGA_MUTE				D7
++
++#define LPGA_GAIN_MASK			0x7F
++#define RPGA_GAIN_MASK			0x7F
++
++/* ADC current modes */
++#define ADC_LOW_CURR_MODE		D0
++
++/* Left ADC Input selection bits */
++#define LCH_SEL1_SHIFT			0
++#define LCH_SEL2_SHIFT			2
++#define LCH_SEL3_SHIFT			4
++#define LCH_SEL4_SHIFT			6
++
++#define LCH_SEL1X_SHIFT			0
++#define LCH_SEL2X_SHIFT			2
++#define LCH_SEL3X_SHIFT			4
++#define LCH_COMMON_MODE			D6
++#define BYPASS_LPGA				D7
++
++/* Right ADC Input selection bits */
++#define RCH_SEL1_SHIFT			0
++#define RCH_SEL2_SHIFT			2
++#define RCH_SEL3_SHIFT			4
++#define RCH_SEL4_SHIFT			6
++
++#define RCH_SEL1X_SHIFT			0
++#define RCH_SEL2X_SHIFT			2
++#define RCH_SEL3X_SHIFT			4
++#define RCH_COMMON_MODE			D6
++#define BYPASS_RPGA				D7
++
++/* MICBIAS control bits */
++#define MICBIAS1_SHIFT			5
++#define MICBIAS2_SHIFT			3
++
++#define ADC_MAX_VOLUME			64
++#define ADC_POS_VOL			24
++
++/****************** RATES TABLE FOR ADC3xxx ************************/
++struct adc3xxx_rate_divs {
++	u32 mclk;
++	u32 rate;
++	u8 pll_p;
++	u8 pll_r;
++	u8 pll_j;
++	u16 pll_d;
++	u8 nadc;
++	u8 madc;
++	u8 aosr;
++	u8 bdiv_n;
++	u8 iadc;
++};
++
++#endif /* _ADC3xxx_AMB_H */
+diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
+index 62bacb85..1d37160d 100644
+--- a/sound/soc/codecs/wm8737.c
++++ b/sound/soc/codecs/wm8737.c
+@@ -47,13 +47,13 @@ struct wm8737_priv {
+ };
+ 
+ static const struct reg_default wm8737_reg_defaults[] = {
+-	{  0, 0x00C3 },     /* R0  - Left PGA volume */
+-	{  1, 0x00C3 },     /* R1  - Right PGA volume */
+-	{  2, 0x0007 },     /* R2  - AUDIO path L */
+-	{  3, 0x0007 },     /* R3  - AUDIO path R */
++	{  0, 0x01C3 },     /* R0  - Left PGA volume, 0db default */
++	{  1, 0x01C3 },     /* R1  - Right PGA volume, 0db default */
++	{  2, 0x0010 },     /* R2  - AUDIO path L, apply gain immediately. */
++	{  3, 0x0010 },     /* R3  - AUDIO path R, apply gain immediately. */
+ 	{  4, 0x0000 },     /* R4  - 3D Enhance */
+ 	{  5, 0x0000 },     /* R5  - ADC Control */
+-	{  6, 0x0000 },     /* R6  - Power Management */
++	{  6, 0x01FF },     /* R6  - Power Management, turn on all modules */
+ 	{  7, 0x000A },     /* R7  - Audio Format */
+ 	{  8, 0x0000 },     /* R8  - Clocking */
+ 	{  9, 0x000F },     /* R9  - MIC Preamp Control */
+diff --git a/sound/soc/codecs/wm8940_amb.c b/sound/soc/codecs/wm8940_amb.c
+new file mode 100644
+index 00000000..5ad809d6
+--- /dev/null
++++ b/sound/soc/codecs/wm8940_amb.c
+@@ -0,0 +1,824 @@
++/*
++ * wm8940_amb.c  --  WM8940 ALSA Soc Audio driver
++ *
++ * Copyright 2011 Ambarella Ltd.
++ *
++ * Author: Wu Dongge <dgwu@ambarella.com>
++ *
++ * Based on wm8940.c
++ *    Copyright  2006 Wolfson Microelectronics PLC.
++ *    Author:  Jonathan Cameron <jic23@cam.ac.uk>
++ *
++ * History:
++ *	2012/10/19 - [Wu Dongge] Created file
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/slab.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++
++#include "wm8940_amb.h"
++
++struct wm8940_priv {
++	unsigned int sysclk;
++	enum snd_soc_control_type control_type;
++	void *control_data;
++};
++
++static u16 wm8940_reg_defaults[] = {
++	0x8940, /* Soft Reset */
++	0x0000, /* Power 1 */
++	0x0000, /* Power 2 */
++	0x0000, /* Power 3 */
++	0x0010, /* Interface Control */
++	0x0000, /* Companding Control */
++	0x0140, /* Clock Control */
++	0x0000, /* Additional Controls */
++	0x0000, /* GPIO Control */
++	0x0002, /* Auto Increment Control */
++	0x0000, /* DAC Control */
++	0x00FF, /* DAC Volume */
++	0,
++	0,
++	0x0100, /* ADC Control */
++	0x00FF, /* ADC Volume */
++	0x0000, /* Notch Filter 1 Control 1 */
++	0x0000, /* Notch Filter 1 Control 2 */
++	0x0000, /* Notch Filter 2 Control 1 */
++	0x0000, /* Notch Filter 2 Control 2 */
++	0x0000, /* Notch Filter 3 Control 1 */
++	0x0000, /* Notch Filter 3 Control 2 */
++	0x0000, /* Notch Filter 4 Control 1 */
++	0x0000, /* Notch Filter 4 Control 2 */
++	0x0032, /* DAC Limit Control 1 */
++	0x0000, /* DAC Limit Control 2 */
++	0,
++	0,
++	0,
++	0,
++	0,
++	0,
++	0x0038, /* ALC Control 1 */
++	0x000B, /* ALC Control 2 */
++	0x0032, /* ALC Control 3 */
++	0x0000, /* Noise Gate */
++	0x0041, /* PLLN */
++	0x000C, /* PLLK1 */
++	0x0093, /* PLLK2 */
++	0x00E9, /* PLLK3 */
++	0,
++	0,
++	0x0030, /* ALC Control 4 */
++	0,
++	0x0002, /* Input Control */
++	0x0050, /* PGA Gain */
++	0,
++	0x0002, /* ADC Boost Control */
++	0,
++	0x0002, /* Output Control */
++	0x0000, /* Speaker Mixer Control */
++	0,
++	0,
++	0,
++	0x0079, /* Speaker Volume */
++	0,
++	0x0000, /* Mono Mixer Control */
++};
++
++static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
++static const struct soc_enum wm8940_adc_companding_enum
++= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding);
++static const struct soc_enum wm8940_dac_companding_enum
++= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding);
++
++static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"};
++static const struct soc_enum wm8940_alc_mode_enum
++= SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text);
++
++static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"};
++static const struct soc_enum wm8940_mic_bias_level_enum
++= SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text);
++
++static const char *wm8940_filter_mode_text[] = {"Audio", "Application"};
++static const struct soc_enum wm8940_filter_mode_enum
++= SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text);
++
++static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1);
++static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0);
++static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1);
++static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0);
++
++static const struct snd_kcontrol_new wm8940_snd_controls[] = {
++	SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL,
++		   6, 1, 0),
++	SOC_ENUM("DAC Companding", wm8940_dac_companding_enum),
++	SOC_ENUM("ADC Companding", wm8940_adc_companding_enum),
++
++	SOC_ENUM("ALC Mode", wm8940_alc_mode_enum),
++	SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0),
++	SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1,
++		       3, 7, 0, wm8940_alc_max_tlv),
++	SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1,
++		       0, 7, 0, wm8940_alc_min_tlv),
++	SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2,
++		       0, 14, 0, wm8940_alc_tar_tlv),
++	SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0),
++	SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0),
++	SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0),
++	SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0),
++	SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE,
++		   3, 1, 0),
++	SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE,
++		   0, 7, 0),
++
++	SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0),
++	SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0),
++	SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0),
++	SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2,
++		       4, 9, 1, wm8940_lim_thresh_tlv),
++	SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2,
++		       0, 12, 0, wm8940_lim_boost_tlv),
++
++	SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0),
++	SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN,
++		       0, 63, 0, wm8940_pga_vol_tlv),
++	SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL,
++		       0, 255, 0, wm8940_adc_tlv),
++	SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
++		       0, 255, 0, wm8940_adc_tlv),
++	SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
++	SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST,
++		       8, 1, 0, wm8940_capture_boost_vol_tlv),
++	SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
++		       0, 63, 0, wm8940_spk_vol_tlv),
++	SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL,  6, 1, 1),
++
++	SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL,
++		       8, 1, 1, wm8940_att_tlv),
++	SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0),
++
++	SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1),
++	SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX,
++		       7, 1, 1, wm8940_att_tlv),
++
++	SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0),
++	SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum),
++	SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0),
++	SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0),
++	SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0),
++	SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0),
++	SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0),
++	SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0),
++	SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0),
++	SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0),
++	SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0),
++};
++
++static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1);
++static const struct snd_kcontrol_new wm8940_input_boost_controls[] = {
++	SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1),
++	SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST,
++			    0, 7, 0, wm8940_boost_vol_tlv),
++	SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST,
++			    4, 7, 0, wm8940_boost_vol_tlv),
++};
++
++static const struct snd_kcontrol_new wm8940_micpga_controls[] = {
++	SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0),
++	SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0),
++	SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0),
++};
++
++static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = {
++	SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0,
++			   &wm8940_speaker_mixer_controls[0],
++			   ARRAY_SIZE(wm8940_speaker_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0,
++			   &wm8940_mono_mixer_controls[0],
++			   ARRAY_SIZE(wm8940_mono_mixer_controls)),
++	SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0),
++
++	SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0),
++	SND_SOC_DAPM_OUTPUT("MONOOUT"),
++	SND_SOC_DAPM_OUTPUT("SPKOUTP"),
++	SND_SOC_DAPM_OUTPUT("SPKOUTN"),
++
++	SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0),
++	SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0),
++	SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0,
++			   &wm8940_micpga_controls[0],
++			   ARRAY_SIZE(wm8940_micpga_controls)),
++	SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0,
++			   &wm8940_input_boost_controls[0],
++			   ARRAY_SIZE(wm8940_input_boost_controls)),
++	SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0),
++
++	SND_SOC_DAPM_INPUT("MICN"),
++	SND_SOC_DAPM_INPUT("MICP"),
++	SND_SOC_DAPM_INPUT("AUX"),
++};
++
++static const struct snd_soc_dapm_route audio_map[] = {
++	/* Mono output mixer */
++	{"Mono Mixer", "PCM Playback Switch", "DAC"},
++	{"Mono Mixer", "Aux Playback Switch", "Aux Input"},
++	{"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
++
++	/* Speaker output mixer */
++	{"Speaker Mixer", "PCM Playback Switch", "DAC"},
++	{"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
++	{"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
++
++	/* Outputs */
++	{"Mono Out", NULL, "Mono Mixer"},
++	{"MONOOUT", NULL, "Mono Out"},
++	{"SpkN Out", NULL, "Speaker Mixer"},
++	{"SpkP Out", NULL, "Speaker Mixer"},
++	{"SPKOUTN", NULL, "SpkN Out"},
++	{"SPKOUTP", NULL, "SpkP Out"},
++
++	/*  Microphone PGA */
++	{"Mic PGA", "MICN Switch", "MICN"},
++	{"Mic PGA", "MICP Switch", "MICP"},
++	{"Mic PGA", "AUX Switch", "AUX"},
++
++	/* Boost Mixer */
++	{"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
++	{"Boost Mixer", "Mic Volume",  "MICP"},
++	{"Boost Mixer", "Aux Volume", "Aux Input"},
++
++	{"ADC", NULL, "Boost Mixer"},
++};
++
++#define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
++
++static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
++			      unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFE67;
++	u16 clk = snd_soc_read(codec, WM8940_CLOCK) & 0x1fe;
++
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		clk |= 1;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++	snd_soc_write(codec, WM8940_CLOCK, clk);
++
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		iface |= (2 << 3);
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		iface |= (1 << 3);
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		iface |= (3 << 3);
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		iface |= (3 << 3) | (1 << 7);
++		break;
++	}
++
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		iface |= (1 << 7);
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		iface |= (1 << 8);
++		break;
++	case SND_SOC_DAIFMT_IB_IF:
++		iface |= (1 << 8) | (1 << 7);
++		break;
++	}
++
++	snd_soc_write(codec, WM8940_IFACE, iface);
++
++	return 0;
++}
++
++static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
++				struct snd_pcm_hw_params *params,
++				struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++	u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
++	u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
++	u16 companding =  snd_soc_read(codec, WM8940_COMPANDINGCTL) & 0xFFDF;
++	int ret;
++
++	/* LoutR control */
++	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
++	    && params_channels(params) == 2)
++		iface |= (1 << 9);
++
++	switch (params_rate(params)) {
++	case 8000:
++		addcntrl |= (0x5 << 1);
++		break;
++	case 11025:
++	case 12000:
++		addcntrl |= (0x4 << 1);
++		break;
++	case 16000:
++		addcntrl |= (0x3 << 1);
++		break;
++	case 24000:
++	case 22050:
++		addcntrl |= (0x2 << 1);
++		break;
++	case 32000:
++		addcntrl |= (0x1 << 1);
++		break;
++	case 44100:
++	case 48000:
++		break;
++	}
++	ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
++	if (ret)
++		goto error_ret;
++
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S8:
++		companding = companding | (1 << 5);
++		break;
++	case SNDRV_PCM_FORMAT_S16_LE:
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		iface |= (1 << 5);
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		iface |= (2 << 5);
++		break;
++	case SNDRV_PCM_FORMAT_S32_LE:
++		iface |= (3 << 5);
++		break;
++	}
++	ret = snd_soc_write(codec, WM8940_COMPANDINGCTL, companding);
++	if (ret)
++		goto error_ret;
++	ret = snd_soc_write(codec, WM8940_IFACE, iface);
++
++error_ret:
++	return ret;
++}
++
++static int wm8940_mute(struct snd_soc_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 mute_reg = snd_soc_read(codec, WM8940_DAC) & 0xffbf;
++
++	if (mute)
++		mute_reg |= 0x40;
++
++	return snd_soc_write(codec, WM8940_DAC, mute_reg);
++}
++
++static int wm8940_set_bias_level(struct snd_soc_codec *codec,
++				 enum snd_soc_bias_level level)
++{
++	u16 val = 0;
++	u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
++	int ret = 0;
++
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++		/* ensure bufioen and biasen and micben */
++		pwr_reg |= (1 << 2) | (1 << 3) | (1 << 4);
++		/* Enable thermal shutdown */
++		val = snd_soc_read(codec, WM8940_OUTPUTCTL);
++		ret = snd_soc_write(codec, WM8940_OUTPUTCTL, val | 0x2);
++		if (ret)
++			break;
++		/* set vmid to 50k */
++		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
++		break;
++	case SND_SOC_BIAS_PREPARE:
++		/* ensure bufioen and biasen */
++		pwr_reg |= (1 << 2) | (1 << 3);
++		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
++		break;
++	case SND_SOC_BIAS_STANDBY:
++		/* ensure bufioen and biasen */
++		pwr_reg |= (1 << 2) | (1 << 3);
++		/* set vmid to 300k for standby */
++		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x2);
++		break;
++	case SND_SOC_BIAS_OFF:
++		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg);
++		break;
++	}
++
++       codec->dapm.bias_level = level;
++
++	return ret;
++}
++
++struct pll_ {
++	unsigned int pre_scale:2;
++	unsigned int n:4;
++	unsigned int k;
++};
++
++static struct pll_ pll_div;
++
++/* The size in bits of the pll divide multiplied by 10
++ * to allow rounding later */
++#define FIXED_PLL_SIZE ((1 << 24) * 10)
++static void pll_factors(unsigned int target, unsigned int source)
++{
++	unsigned long long Kpart;
++	unsigned int K, Ndiv, Nmod;
++	/* The left shift ist to avoid accuracy loss when right shifting */
++	Ndiv = target / source;
++
++	if (Ndiv > 12) {
++		source <<= 1;
++		/* Multiply by 2 */
++		pll_div.pre_scale = 0;
++		Ndiv = target / source;
++	} else if (Ndiv < 3) {
++		source >>= 2;
++		/* Divide by 4 */
++		pll_div.pre_scale = 3;
++		Ndiv = target / source;
++	} else if (Ndiv < 6) {
++		source >>= 1;
++		/* divide by 2 */
++		pll_div.pre_scale = 2;
++		Ndiv = target / source;
++	} else {
++		pll_div.pre_scale = 1;
++	}
++
++	if ((Ndiv < 6) || (Ndiv > 12))
++		printk(KERN_WARNING "WM8940 N value %d outwith recommended range!\n", Ndiv);
++
++	pll_div.n = Ndiv;
++	Nmod = target % source;
++	Kpart = FIXED_PLL_SIZE * (long long)Nmod;
++
++	do_div(Kpart, source);
++	K = Kpart & 0xFFFFFFFF;
++
++	/* Check if we need to round */
++	if ((K % 10) >= 5)
++		K += 5;
++
++	/* Move down to proper range now rounding is done */
++	K /= 10;
++	pll_div.k = K;
++}
++
++/* Untested at the moment */
++static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 reg;
++
++	/* Turn off PLL */
++	reg = snd_soc_read(codec, WM8940_POWER1);
++	snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
++
++	if (freq_in == 0 || freq_out == 0) {
++		/* Clock CODEC directly from MCLK */
++		reg = snd_soc_read(codec, WM8940_CLOCK);
++		snd_soc_write(codec, WM8940_CLOCK, reg & 0x0ff);
++		/* Pll power down */
++		snd_soc_write(codec, WM8940_PLLN, (1 << 7));
++		return 0;
++	}
++
++	/* Pll is followed by a frequency divide by 4 */
++	pll_factors(freq_out*4, freq_in);
++
++	if (pll_div.k)
++		snd_soc_write(codec, WM8940_PLLN,
++			     (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
++	else /* No factional component */
++		snd_soc_write(codec, WM8940_PLLN,
++			     (pll_div.pre_scale << 4) | pll_div.n);
++
++	snd_soc_write(codec, WM8940_PLLK1, (pll_div.k >> 18) & 0x3f);
++	snd_soc_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
++	snd_soc_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
++	/* Enable the PLL */
++	reg = snd_soc_read(codec, WM8940_POWER1);
++	snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
++
++	/* Run CODEC from PLL instead of MCLK */
++	reg = snd_soc_read(codec, WM8940_CLOCK);
++	snd_soc_write(codec, WM8940_CLOCK, reg | 0x100);
++
++	return 0;
++}
++
++static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++				 int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
++	u16 reg;
++
++	switch(clk_id) {
++	case WM8940_MCLKIN:
++		/* Clock CODEC directly from MCLK */
++		reg = snd_soc_read(codec, WM8940_CLOCK) & 0x0fe;
++		snd_soc_write(codec, WM8940_CLOCK, reg);
++
++		/* Turn off PLL */
++		reg = snd_soc_read(codec, WM8940_POWER1);
++		snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
++		break;
++	case WM8940_PLLOUT:
++		/* Clock CODEC is generated by PLL */
++		reg = snd_soc_read(codec, WM8940_CLOCK) & 0x0fe;
++		reg |= 0x100;
++		snd_soc_write(codec, WM8940_CLOCK, reg);
++
++		/* Turn on PLL */
++		reg = snd_soc_read(codec, WM8940_POWER1);
++		snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
++
++//		wm8940_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
++		break;
++	case WM8940_MCLKIN_BCLKOUT:
++		reg = snd_soc_read(codec, WM8940_CLOCK) & 0x0fe;
++		reg |= 0x001;
++		snd_soc_write(codec, WM8940_CLOCK, reg);
++
++		/* Turn on PLL */
++		reg = snd_soc_read(codec, WM8940_POWER1);
++		snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
++
++//		wm8940_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
++		break;
++
++	}
++
++	wm8940->sysclk = freq;
++}
++
++static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
++				 int div_id, int div)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 reg;
++	int ret = 0;
++
++	switch (div_id) {
++	case WM8940_BCLKDIV:
++		reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3;
++		ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
++		break;
++	case WM8940_MCLKDIV:
++		reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFF1F;
++		ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
++		break;
++	case WM8940_OPCLKDIV:
++		reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
++		ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
++		break;
++	}
++	return ret;
++}
++
++#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
++
++#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 |				\
++			SNDRV_PCM_FMTBIT_S16_LE |			\
++			SNDRV_PCM_FMTBIT_S20_3LE |			\
++			SNDRV_PCM_FMTBIT_S24_LE |			\
++			SNDRV_PCM_FMTBIT_S32_LE)
++
++static const struct snd_soc_dai_ops wm8940_dai_ops = {
++	.hw_params = wm8940_i2s_hw_params,
++	.set_sysclk = wm8940_set_dai_sysclk,
++	.digital_mute = wm8940_mute,
++	.set_fmt = wm8940_set_dai_fmt,
++	.set_clkdiv = wm8940_set_dai_clkdiv,
++	.set_pll = wm8940_set_dai_pll,
++};
++
++static struct snd_soc_dai_driver wm8940_dai = {
++	.name = "wm8940-hifi",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM8940_RATES,
++		.formats = WM8940_FORMATS,
++	},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM8940_RATES,
++		.formats = WM8940_FORMATS,
++	},
++	.ops = &wm8940_dai_ops,
++	.symmetric_rates = 1,
++};
++
++static int wm8940_suspend(struct snd_soc_codec *codec)
++{
++	return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
++}
++
++static int wm8940_resume(struct snd_soc_codec *codec)
++{
++	snd_soc_cache_sync(codec);
++	wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	return 0;
++}
++
++static int wm8940_probe(struct snd_soc_codec *codec)
++{
++	int ret = 0;
++	printk(KERN_NOTICE "wm8940_probe amba.....\n");
++
++	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++	ret = wm8940_reset(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to issue reset\n");
++		return ret;
++	}
++
++	wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	snd_soc_write(codec, WM8940_POWER1, 0x180);
++
++	/************************ RECORD PATH SETTINGS *******************************/
++	snd_soc_write(codec, WM8940_CLOCK, 0x0100);	/*set MCLK, MCLKDIV 1, BCLKDIV 1, BCLK and frame clock are inputs*/
++	snd_soc_write(codec, WM8940_GPIO, 0x0000);
++	snd_soc_write(codec, WM8940_ADDCNTRL, 0x0000);
++	snd_soc_write(codec, WM8940_INPUTCTL, 0x0107);
++	snd_soc_write(codec, WM8940_PGAGAIN, 0x003d);	/*set PGA gain 30db*/
++	snd_soc_write(codec, WM8940_ADCBOOST, 0x0155);	/*set PGB2BOOST, MICP2BOOSTVOL gain*/
++	snd_soc_write(codec, WM8940_ADC, 0x01c0);	/*Enable high pass filter 396HZ under 48k, select audio mode*/
++	snd_soc_write(codec, WM8940_ADCVOL, 0x00ff);	/*Set ADC vol, 0db*/
++	snd_soc_write(codec, WM8940_ALC1, 0x0138);	/*Enable ALC, set max gain +35.25db and min gain -12db*/
++	snd_soc_write(codec, WM8940_ALC2, 0x0007);	/*set min alc target gain -12db and hold time 0ms*/
++	snd_soc_write(codec, WM8940_ALC3, 0x0042);	/*ALC mode, DCY 384ms, ATK 24ms*/
++	snd_soc_write(codec, WM8940_ALC4, 0x0000);	/*ZC OFF*/
++	snd_soc_write(codec, WM8940_NOISEGATE, 0x000f); /*Enable nosie gate and set threshold -81db*/
++	snd_soc_write(codec, WM8940_NOTCH8, 0x00c1); /*Set low pass filter from 15khz*/
++
++	/************************ PLAYBACK PATH SETTINGS *******************************/
++	snd_soc_write(codec, WM8940_DAC, 0x0000);		/*Disable soft mute, Disable DAC auto mute, no inversion*/
++	snd_soc_write(codec, WM8940_DACVOL, 0x00ff);	/*Set DACVOL 0dB*/
++	snd_soc_write(codec, WM8940_DACLIM1, 0x0000);	/*Disable DAC Limiter*/
++	snd_soc_write(codec, WM8940_DACLIM2, 0x000c);	/*Set DAC boost 12dB*/
++	snd_soc_write(codec, WM8940_SPKMIX, 0x0001);	/*select output DAC to speaker mixer*/
++	snd_soc_write(codec, WM8940_SPKVOL, 0x003f);	/*Eable speaker out and set speaker volume +6dB*/
++	snd_soc_write(codec, WM8940_MONOMIX, 0x0000); /*Not select DAC to mono*/
++
++	ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
++			     ARRAY_SIZE(wm8940_snd_controls));
++
++	return ret;
++}
++
++static int wm8940_remove(struct snd_soc_codec *codec)
++{
++	wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
++	.probe =	wm8940_probe,
++	.remove =	wm8940_remove,
++	.suspend =	wm8940_suspend,
++	.resume =	wm8940_resume,
++	.set_bias_level = wm8940_set_bias_level,
++	.reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
++	.reg_word_size = sizeof(u16),
++	.reg_cache_default = wm8940_reg_defaults,
++	.reg_cache_step = 1,
++	.dapm_widgets = wm8940_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets),
++	.dapm_routes = audio_map,
++	.num_dapm_routes = ARRAY_SIZE(audio_map),
++};
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static int wm8940_i2c_probe(struct i2c_client *i2c,
++				      const struct i2c_device_id *id)
++{
++	struct wm8940_priv *wm8940;
++
++	wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv), GFP_KERNEL);
++	if (wm8940 == NULL)
++		return -ENOMEM;
++
++	i2c_set_clientdata(i2c, wm8940);
++
++	return snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_wm8940, &wm8940_dai, 1);
++}
++
++static int wm8940_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	return 0;
++}
++
++static struct of_device_id wm8940_of_match[] = {
++	{ .compatible = "ambarella,wm8940",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, wm8940_of_match);
++
++
++static const struct i2c_device_id wm8940_i2c_id[] = {
++	{ "wm8940", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
++
++static struct i2c_driver wm8940_i2c_driver = {
++	.driver = {
++		.name = "wm8940-codec",
++		.owner = THIS_MODULE,
++		.of_match_table = wm8940_of_match,
++	},
++	.probe =    wm8940_i2c_probe,
++	.remove =   wm8940_i2c_remove,
++	.id_table = wm8940_i2c_id,
++};
++#endif
++
++static int __init wm8940_modinit(void)
++{
++	int ret = 0;
++
++	printk(KERN_INFO "wm8940_amb.c:: __init wm8940_modinit(void)\n");
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&wm8940_i2c_driver);
++	if (ret != 0) {
++		printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
++		       ret);
++	}
++#endif
++	return ret;
++}
++module_init(wm8940_modinit);
++
++static void __exit wm8940_exit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	i2c_del_driver(&wm8940_i2c_driver);
++#endif
++}
++module_exit(wm8940_exit);
++
++MODULE_DESCRIPTION("ASoC WM8940 driver");
++MODULE_AUTHOR("Wu Dongge <dgwu@ambarella.com>");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/wm8940_amb.h b/sound/soc/codecs/wm8940_amb.h
+new file mode 100644
+index 00000000..d60a97a2
+--- /dev/null
++++ b/sound/soc/codecs/wm8940_amb.h
+@@ -0,0 +1,110 @@
++/*
++ * wm8940_amb.h -- WM8940 Soc Audio driver
++ *
++ * 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.
++ */
++
++#ifndef _WM8940_AMB_H
++#define _WM8940_AMB_H
++
++struct wm8940_setup_data {
++	/* Vref to analogue output resistance */
++#define WM8940_VROI_1K 0
++#define WM8940_VROI_30K 1
++	unsigned int vroi:1;
++};
++
++/* WM8940 register space */
++#define WM8940_SOFTRESET	0x00
++#define WM8940_POWER1		0x01
++#define WM8940_POWER2		0x02
++#define WM8940_POWER3		0x03
++#define WM8940_IFACE		0x04
++#define WM8940_COMPANDINGCTL	0x05
++#define WM8940_CLOCK		0x06
++#define WM8940_ADDCNTRL		0x07
++#define WM8940_GPIO		0x08
++#define WM8940_CTLINT		0x09
++#define WM8940_DAC		0x0A
++#define WM8940_DACVOL		0x0B
++
++#define WM8940_ADC		0x0E
++#define WM8940_ADCVOL		0x0F
++#define WM8940_NOTCH1		0x10
++#define WM8940_NOTCH2		0x11
++#define WM8940_NOTCH3		0x12
++#define WM8940_NOTCH4		0x13
++#define WM8940_NOTCH5		0x14
++#define WM8940_NOTCH6		0x15
++#define WM8940_NOTCH7		0x16
++#define WM8940_NOTCH8		0x17
++#define WM8940_DACLIM1		0x18
++#define WM8940_DACLIM2		0x19
++
++#define WM8940_ALC1		0x20
++#define WM8940_ALC2		0x21
++#define WM8940_ALC3		0x22
++#define WM8940_NOISEGATE	0x23
++#define WM8940_PLLN		0x24
++#define WM8940_PLLK1		0x25
++#define WM8940_PLLK2		0x26
++#define WM8940_PLLK3		0x27
++
++#define WM8940_ALC4		0x2A
++
++#define WM8940_INPUTCTL		0x2C
++#define WM8940_PGAGAIN		0x2D
++
++#define WM8940_ADCBOOST		0x2F
++
++#define WM8940_OUTPUTCTL	0x31
++#define WM8940_SPKMIX		0x32
++
++#define WM8940_SPKVOL		0x36
++
++#define WM8940_MONOMIX		0x38
++
++#define WM8940_CACHEREGNUM  57
++
++
++/* Clock divider Id's */
++#define WM8940_BCLKDIV 0
++#define WM8940_MCLKDIV 1
++#define WM8940_OPCLKDIV 2
++
++/* Clock source */
++#define WM8940_MCLKIN		0
++#define WM8940_PLLOUT		1
++#define WM8940_MCLKIN_BCLKOUT	2
++
++/* MCLK clock dividers */
++#define WM8940_MCLKDIV_1	0
++#define WM8940_MCLKDIV_1_5	1
++#define WM8940_MCLKDIV_2	2
++#define WM8940_MCLKDIV_3	3
++#define WM8940_MCLKDIV_4	4
++#define WM8940_MCLKDIV_6	5
++#define WM8940_MCLKDIV_8	6
++#define WM8940_MCLKDIV_12	7
++
++/* BCLK clock dividers */
++#define WM8940_BCLKDIV_1 0
++#define WM8940_BCLKDIV_2 1
++#define WM8940_BCLKDIV_4 2
++#define WM8940_BCLKDIV_8 3
++#define WM8940_BCLKDIV_16 4
++#define WM8940_BCLKDIV_32 5
++
++/* PLL Out Dividers */
++#define WM8940_OPCLKDIV_1 0
++#define WM8940_OPCLKDIV_2 1
++#define WM8940_OPCLKDIV_3 2
++#define WM8940_OPCLKDIV_4 3
++
++#define WM8940_SYSCLK	0
++
++
++#endif /* _WM8940_H */
++
+diff --git a/sound/soc/codecs/wm8974_amb.c b/sound/soc/codecs/wm8974_amb.c
+new file mode 100644
+index 00000000..40b8917a
+--- /dev/null
++++ b/sound/soc/codecs/wm8974_amb.c
+@@ -0,0 +1,800 @@
++/*
++ * wm8940_amb.c  --  WM8940 ALSA Soc Audio driver
++ *
++ * Copyright 2011 Ambarella Ltd.
++ *
++ * Author: Wu Dongge <dgwu@ambarella.com>
++ *
++ * Based on wm8974.c
++ * Copyright 2006-2009 Wolfson Microelectronics PLC.
++ *
++ * Author: Liam Girdwood <linux@wolfsonmicro.com>
++ *
++ * History:
++ *	2012/10/25 - [Wu Dongge] Created file
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/slab.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++
++#include "wm8974_amb.h"
++
++static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0050, 0x0000, 0x0140, 0x0000,
++	0x0000, 0x0000, 0x0000, 0x00ff,
++	0x0000, 0x0000, 0x0100, 0x00ff,
++	0x0000, 0x0000, 0x012c, 0x002c,
++	0x002c, 0x002c, 0x002c, 0x0000,
++	0x0032, 0x0000, 0x0000, 0x0000,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0038, 0x000b, 0x0032, 0x0000,
++	0x0008, 0x000c, 0x0093, 0x00e9,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0003, 0x0010, 0x0000, 0x0000,
++	0x0000, 0x0002, 0x0000, 0x0000,
++	0x0000, 0x0000, 0x0039, 0x0000,
++	0x0000,
++};
++
++#define WM8974_POWER1_BIASEN  0x08
++#define WM8974_POWER1_BUFIOEN 0x04
++
++struct wm8974_priv {
++	unsigned int sysclk;
++	enum snd_soc_control_type control_type;
++	void *control_data;
++};
++
++#define wm8974_reset(c)	snd_soc_write(c, WM8974_RESET, 0)
++
++static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
++static const char *wm8974_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz" };
++static const char *wm8974_eqmode[] = {"Capture", "Playback" };
++static const char *wm8974_bw[] = {"Narrow", "Wide" };
++static const char *wm8974_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz" };
++static const char *wm8974_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz" };
++static const char *wm8974_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz" };
++static const char *wm8974_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" };
++static const char *wm8974_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz" };
++static const char *wm8974_alc[] = {"ALC", "Limiter" };
++
++static const struct soc_enum wm8974_enum[] = {
++	SOC_ENUM_SINGLE(WM8974_COMP, 1, 4, wm8974_companding), /* adc */
++	SOC_ENUM_SINGLE(WM8974_COMP, 3, 4, wm8974_companding), /* dac */
++	SOC_ENUM_SINGLE(WM8974_DAC,  4, 4, wm8974_deemp),
++	SOC_ENUM_SINGLE(WM8974_EQ1,  8, 2, wm8974_eqmode),
++
++	SOC_ENUM_SINGLE(WM8974_EQ1,  5, 4, wm8974_eq1),
++	SOC_ENUM_SINGLE(WM8974_EQ2,  8, 2, wm8974_bw),
++	SOC_ENUM_SINGLE(WM8974_EQ2,  5, 4, wm8974_eq2),
++	SOC_ENUM_SINGLE(WM8974_EQ3,  8, 2, wm8974_bw),
++
++	SOC_ENUM_SINGLE(WM8974_EQ3,  5, 4, wm8974_eq3),
++	SOC_ENUM_SINGLE(WM8974_EQ4,  8, 2, wm8974_bw),
++	SOC_ENUM_SINGLE(WM8974_EQ4,  5, 4, wm8974_eq4),
++	SOC_ENUM_SINGLE(WM8974_EQ5,  8, 2, wm8974_bw),
++
++	SOC_ENUM_SINGLE(WM8974_EQ5,  5, 4, wm8974_eq5),
++	SOC_ENUM_SINGLE(WM8974_ALC3,  8, 2, wm8974_alc),
++};
++
++static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" };
++
++static const struct soc_enum wm8974_auxmode =
++	SOC_ENUM_SINGLE(WM8974_INPUT,  3, 2, wm8974_auxmode_text);
++
++static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
++static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
++static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
++static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
++
++static const struct snd_kcontrol_new wm8974_snd_controls[] = {
++
++SOC_SINGLE("Digital Loopback Switch", WM8974_COMP, 0, 1, 0),
++
++SOC_ENUM("DAC Companding", wm8974_enum[1]),
++SOC_ENUM("ADC Companding", wm8974_enum[0]),
++
++SOC_ENUM("Playback De-emphasis", wm8974_enum[2]),
++SOC_SINGLE("DAC Inversion Switch", WM8974_DAC, 0, 1, 0),
++
++SOC_SINGLE_TLV("PCM Volume", WM8974_DACVOL, 0, 255, 0, digital_tlv),
++
++SOC_SINGLE("High Pass Filter Switch", WM8974_ADC, 8, 1, 0),
++SOC_SINGLE("High Pass Cut Off", WM8974_ADC, 4, 7, 0),
++SOC_SINGLE("ADC Inversion Switch", WM8974_ADC, 0, 1, 0),
++
++SOC_SINGLE_TLV("Capture Volume", WM8974_ADCVOL,  0, 255, 0, digital_tlv),
++
++SOC_ENUM("Equaliser Function", wm8974_enum[3]),
++SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]),
++SOC_SINGLE_TLV("EQ1 Volume", WM8974_EQ1,  0, 24, 1, eq_tlv),
++
++SOC_ENUM("Equaliser EQ2 Bandwith", wm8974_enum[5]),
++SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]),
++SOC_SINGLE_TLV("EQ2 Volume", WM8974_EQ2,  0, 24, 1, eq_tlv),
++
++SOC_ENUM("Equaliser EQ3 Bandwith", wm8974_enum[7]),
++SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]),
++SOC_SINGLE_TLV("EQ3 Volume", WM8974_EQ3,  0, 24, 1, eq_tlv),
++
++SOC_ENUM("Equaliser EQ4 Bandwith", wm8974_enum[9]),
++SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]),
++SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4,  0, 24, 1, eq_tlv),
++
++SOC_ENUM("Equaliser EQ5 Bandwith", wm8974_enum[11]),
++SOC_ENUM("EQ5 Cut Off", wm8974_enum[12]),
++SOC_SINGLE_TLV("EQ5 Volume", WM8974_EQ5,  0, 24, 1, eq_tlv),
++
++SOC_SINGLE("DAC Playback Limiter Switch", WM8974_DACLIM1,  8, 1, 0),
++SOC_SINGLE("DAC Playback Limiter Decay", WM8974_DACLIM1,  4, 15, 0),
++SOC_SINGLE("DAC Playback Limiter Attack", WM8974_DACLIM1,  0, 15, 0),
++
++SOC_SINGLE("DAC Playback Limiter Threshold", WM8974_DACLIM2,  4, 7, 0),
++SOC_SINGLE("DAC Playback Limiter Boost", WM8974_DACLIM2,  0, 15, 0),
++
++SOC_SINGLE("ALC Enable Switch", WM8974_ALC1,  8, 1, 0),
++SOC_SINGLE("ALC Capture Max Gain", WM8974_ALC1,  3, 7, 0),
++SOC_SINGLE("ALC Capture Min Gain", WM8974_ALC1,  0, 7, 0),
++
++SOC_SINGLE("ALC Capture ZC Switch", WM8974_ALC2,  8, 1, 0),
++SOC_SINGLE("ALC Capture Hold", WM8974_ALC2,  4, 15, 0),
++SOC_SINGLE("ALC Capture Target", WM8974_ALC2,  0, 15, 0),
++
++SOC_ENUM("ALC Capture Mode", wm8974_enum[13]),
++SOC_SINGLE("ALC Capture Decay", WM8974_ALC3,  4, 15, 0),
++SOC_SINGLE("ALC Capture Attack", WM8974_ALC3,  0, 15, 0),
++
++SOC_SINGLE("ALC Capture Noise Gate Switch", WM8974_NGATE,  3, 1, 0),
++SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8974_NGATE,  0, 7, 0),
++
++SOC_SINGLE("Capture PGA ZC Switch", WM8974_INPPGA,  7, 1, 0),
++SOC_SINGLE_TLV("Capture PGA Volume", WM8974_INPPGA,  0, 63, 0, inpga_tlv),
++
++SOC_SINGLE("Speaker Playback ZC Switch", WM8974_SPKVOL,  7, 1, 0),
++SOC_SINGLE("Speaker Playback Switch", WM8974_SPKVOL,  6, 1, 1),
++SOC_SINGLE_TLV("Speaker Playback Volume", WM8974_SPKVOL,  0, 63, 0, spk_tlv),
++
++SOC_ENUM("Aux Mode", wm8974_auxmode),
++
++SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST,  8, 1, 0),
++SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
++
++/* DAC / ADC oversampling */
++SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 3, 1, 0),
++SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 3, 1, 0),
++};
++
++/* Speaker Output Mixer */
++static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
++SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
++SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
++SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 0),
++};
++
++/* Mono Output Mixer */
++static const struct snd_kcontrol_new wm8974_mono_mixer_controls[] = {
++SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_MONOMIX, 1, 1, 0),
++SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_MONOMIX, 2, 1, 0),
++SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
++};
++
++static DECLARE_TLV_DB_SCALE(wm8974_boost_vol_tlv, -1500, 300, 1);
++/* Boost mixer */
++static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
++	SOC_DAPM_SINGLE("Mic PGA Switch", WM8974_INPPGA, 6, 1, 1),
++	SOC_DAPM_SINGLE_TLV("Aux Volume", WM8974_ADCBOOST,
++			    0, 7, 0, wm8974_boost_vol_tlv),
++	SOC_DAPM_SINGLE_TLV("Mic Volume", WM8974_ADCBOOST,
++			    4, 7, 0, wm8974_boost_vol_tlv),
++};
++
++/* Input PGA */
++static const struct snd_kcontrol_new wm8974_inpga[] = {
++SOC_DAPM_SINGLE("Aux Switch", WM8974_INPUT, 2, 1, 0),
++SOC_DAPM_SINGLE("MicN Switch", WM8974_INPUT, 1, 1, 0),
++SOC_DAPM_SINGLE("MicP Switch", WM8974_INPUT, 0, 1, 0),
++};
++
++static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = {
++SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0,
++	&wm8974_speaker_mixer_controls[0],
++	ARRAY_SIZE(wm8974_speaker_mixer_controls)),
++SND_SOC_DAPM_MIXER("Mono Mixer", WM8974_POWER3, 3, 0,
++	&wm8974_mono_mixer_controls[0],
++	ARRAY_SIZE(wm8974_mono_mixer_controls)),
++SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8974_POWER3, 0, 0),
++
++SND_SOC_DAPM_PGA("SpkN Out", WM8974_POWER3, 5, 0, NULL, 0),
++SND_SOC_DAPM_PGA("SpkP Out", WM8974_POWER3, 6, 0, NULL, 0),
++SND_SOC_DAPM_PGA("Mono Out", WM8974_POWER3, 7, 0, NULL, 0),
++SND_SOC_DAPM_OUTPUT("MONOOUT"),
++SND_SOC_DAPM_OUTPUT("SPKOUTP"),
++SND_SOC_DAPM_OUTPUT("SPKOUTN"),
++
++SND_SOC_DAPM_PGA("Aux Input", WM8974_POWER1, 6, 0, NULL, 0),
++SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8974_POWER2, 0, 0),
++SND_SOC_DAPM_MIXER("Input PGA", WM8974_POWER2, 2, 0, &wm8974_inpga[0],
++		   ARRAY_SIZE(wm8974_inpga)),
++SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0,
++		   &wm8974_boost_mixer[0], ARRAY_SIZE(wm8974_boost_mixer)),
++
++SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0),
++
++SND_SOC_DAPM_INPUT("MICN"),
++SND_SOC_DAPM_INPUT("MICP"),
++SND_SOC_DAPM_INPUT("AUX"),
++};
++
++static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
++	/* Mono output mixer */
++	{"Mono Mixer", "PCM Playback Switch", "DAC"},
++	{"Mono Mixer", "Aux Playback Switch", "Aux Input"},
++	{"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
++
++	/* Speaker output mixer */
++	{"Speaker Mixer", "PCM Playback Switch", "DAC"},
++	{"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
++	{"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
++
++	/* Outputs */
++	{"Mono Out", NULL, "Mono Mixer"},
++	{"MONOOUT", NULL, "Mono Out"},
++	{"SpkN Out", NULL, "Speaker Mixer"},
++	{"SpkP Out", NULL, "Speaker Mixer"},
++	{"SPKOUTN", NULL, "SpkN Out"},
++	{"SPKOUTP", NULL, "SpkP Out"},
++
++	/* Boost Mixer */
++	{"ADC", NULL, "Boost Mixer"},
++
++	{"Boost Mixer", "Aux Volume", "Aux Input"},
++	{"Boost Mixer", "Mic PGA Switch", "Input PGA"},
++	{"Boost Mixer", "Mic Volume", "MICP"},
++
++	/* Input PGA */
++	{"Input PGA", "Aux Switch", "AUX"},
++	{"Input PGA", "MicN Switch", "MICN"},
++	{"Input PGA", "MicP Switch", "MICP"},
++
++	/* Inputs */
++	//{"Aux Input", NULL, "AUX"},
++};
++
++struct pll_ {
++	unsigned int pre_div:1;
++	unsigned int n:4;
++	unsigned int k;
++};
++
++/* The size in bits of the pll divide multiplied by 10
++ * to allow rounding later */
++#define FIXED_PLL_SIZE ((1 << 24) * 10)
++
++static void pll_factors(struct pll_ *pll_div,
++			unsigned int target, unsigned int source)
++{
++	unsigned long long Kpart;
++	unsigned int K, Ndiv, Nmod;
++
++	/* There is a fixed divide by 4 in the output path */
++	target *= 4;
++
++	Ndiv = target / source;
++	if (Ndiv < 6) {
++		source /= 2;
++		pll_div->pre_div = 1;
++		Ndiv = target / source;
++	} else
++		pll_div->pre_div = 0;
++
++	if ((Ndiv < 6) || (Ndiv > 12))
++		printk(KERN_WARNING
++			"WM8974 N value %u outwith recommended range!\n",
++			Ndiv);
++
++	pll_div->n = Ndiv;
++	Nmod = target % source;
++	Kpart = FIXED_PLL_SIZE * (long long)Nmod;
++
++	do_div(Kpart, source);
++
++	K = Kpart & 0xFFFFFFFF;
++
++	/* Check if we need to round */
++	if ((K % 10) >= 5)
++		K += 5;
++
++	/* Move down to proper range now rounding is done */
++	K /= 10;
++
++	pll_div->k = K;
++}
++
++static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct pll_ pll_div;
++	u16 reg;
++
++	if (freq_in == 0 || freq_out == 0) {
++		/* Clock CODEC directly from MCLK */
++		reg = snd_soc_read(codec, WM8974_CLOCK);
++		snd_soc_write(codec, WM8974_CLOCK, reg & 0x0ff);
++
++		/* Turn off PLL */
++		reg = snd_soc_read(codec, WM8974_POWER1);
++		snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
++		return 0;
++	}
++
++	pll_factors(&pll_div, freq_out, freq_in);
++
++	snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
++	snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
++	snd_soc_write(codec, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff);
++	snd_soc_write(codec, WM8974_PLLK3, pll_div.k & 0x1ff);
++	reg = snd_soc_read(codec, WM8974_POWER1);
++	snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
++
++	/* Run CODEC from PLL instead of MCLK */
++	reg = snd_soc_read(codec, WM8974_CLOCK);
++	snd_soc_write(codec, WM8974_CLOCK, reg | 0x100);
++
++	return 0;
++}
++
++static int wm8974_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++				 int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct wm8974_priv *wm8974 = snd_soc_codec_get_drvdata(codec);
++	u16 reg;
++
++	switch(clk_id) {
++	case WM8974_MCLKIN:
++		/* Clock CODEC directly from MCLK */
++		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x0fe;
++		snd_soc_write(codec, WM8974_CLOCK, reg);
++
++		/* Turn off PLL */
++		reg = snd_soc_read(codec, WM8974_POWER1);
++		snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
++		break;
++	case WM8974_PLLOUT:
++		/* Clock CODEC is generated by PLL */
++		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x0fe;
++		reg |= 0x100;
++		snd_soc_write(codec, WM8974_CLOCK, reg);
++
++		/* Turn on PLL */
++		reg = snd_soc_read(codec, WM8974_POWER1);
++		snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
++
++//		wm8974_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
++		break;
++	case WM8974_MCLKIN_BCLKOUT:
++		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x0fe;
++		reg |= 0x001;
++		snd_soc_write(codec, WM8974_CLOCK, reg);
++
++		/* Turn on PLL */
++		reg = snd_soc_read(codec, WM8974_POWER1);
++		snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
++
++//		wm8974_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
++		break;
++
++	}
++
++
++	wm8974->sysclk = freq;
++	return 0;
++}
++
++/*
++ * Configure WM8974 clock dividers.
++ */
++static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
++		int div_id, int div)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 reg;
++
++	switch (div_id) {
++	case WM8974_OPCLKDIV:
++		reg = snd_soc_read(codec, WM8974_GPIO) & 0x1cf;
++		snd_soc_write(codec, WM8974_GPIO, reg | div);
++		break;
++	case WM8974_MCLKDIV:
++		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
++		snd_soc_write(codec, WM8974_CLOCK, reg | div);
++		break;
++	case WM8974_BCLKDIV:
++		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
++		snd_soc_write(codec, WM8974_CLOCK, reg | div);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 iface = 0;
++	u16 clk = snd_soc_read(codec, WM8974_CLOCK) & 0x1fe;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		clk |= 0x0001;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		iface |= 0x0010;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		iface |= 0x0008;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		iface |= 0x00018;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_IB_IF:
++		iface |= 0x0180;
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		iface |= 0x0100;
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		iface |= 0x0080;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	snd_soc_write(codec, WM8974_IFACE, iface);
++	snd_soc_write(codec, WM8974_CLOCK, clk);
++	return 0;
++}
++
++static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
++				struct snd_pcm_hw_params *params,
++				struct snd_soc_dai *dai)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;
++	u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;
++
++	/* bit size */
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		iface |= 0x0020;
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		iface |= 0x0040;
++		break;
++	case SNDRV_PCM_FORMAT_S32_LE:
++		iface |= 0x0060;
++		break;
++	}
++
++	/* filter coefficient */
++	switch (params_rate(params)) {
++	case 8000:
++		adn |= (0x5 << 1);
++		break;
++	case 11025:
++	case 12000:
++		adn |= (0x4 << 1);
++		break;
++	case 16000:
++		adn |= (0x3 << 1);
++		break;
++	case 24000:
++	case 22050:
++		adn |= (0x2 << 1);
++		break;
++	case 32000:
++		adn |= (0x1 << 1);
++		break;
++	case 44100:
++	case 48000:
++		break;
++	}
++
++	snd_soc_write(codec, WM8974_IFACE, iface);
++	snd_soc_write(codec, WM8974_ADD, adn);
++	return 0;
++}
++
++static int wm8974_mute(struct snd_soc_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
++
++	if (mute)
++		snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
++	else
++		snd_soc_write(codec, WM8974_DAC, mute_reg);
++	return 0;
++}
++
++static int wm8974_set_bias_level(struct snd_soc_codec *codec,
++				 enum snd_soc_bias_level level)
++{
++	u16 val = 0;
++	u16 pwr_reg = snd_soc_read(codec, WM8974_POWER1) & 0x170;
++	int ret = 0;
++
++	//printk("****wm8974_set_bias_level: level: %d\n", level);
++	switch (level) {
++	case SND_SOC_BIAS_ON:
++		/* ensure bufioen and biasen and micben */
++		pwr_reg |= (1 << 2) | (1 << 3) | (1 << 4);
++		/* Enable thermal shutdown */
++		val = snd_soc_read(codec, WM8974_OUTPUT);
++		ret = snd_soc_write(codec, WM8974_OUTPUT, val | 0x2);
++		if (ret)
++			break;
++		/* set vmid to 50k */
++		ret = snd_soc_write(codec, WM8974_POWER1, pwr_reg | 0x1);
++		break;
++	case SND_SOC_BIAS_PREPARE:
++		/* ensure bufioen and biasen */
++		pwr_reg |= (1 << 2) | (1 << 3);
++		ret = snd_soc_write(codec, WM8974_POWER1, pwr_reg | 0x1);
++		break;
++	case SND_SOC_BIAS_STANDBY:
++		/* ensure bufioen and biasen */
++		pwr_reg |= (1 << 2) | (1 << 3);
++		/* set vmid to 300k for standby */
++		ret = snd_soc_write(codec, WM8974_POWER1, pwr_reg | 0x2);
++		break;
++	case SND_SOC_BIAS_OFF:
++		ret = snd_soc_write(codec, WM8974_POWER1, 0);
++		ret = snd_soc_write(codec, WM8974_POWER2, 0);
++		ret = snd_soc_write(codec, WM8974_POWER3, 0);
++		break;
++	}
++
++          codec->dapm.bias_level = level;
++
++	return ret;
++}
++
++#define WM8974_RATES (SNDRV_PCM_RATE_8000_48000)
++
++#define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
++	SNDRV_PCM_FMTBIT_S24_LE)
++
++static const struct snd_soc_dai_ops wm8974_ops = {
++	.hw_params = wm8974_pcm_hw_params,
++	.set_sysclk = wm8974_set_dai_sysclk,
++	.digital_mute = wm8974_mute,
++	.set_fmt = wm8974_set_dai_fmt,
++	.set_clkdiv = wm8974_set_dai_clkdiv,
++	.set_pll = wm8974_set_dai_pll,
++};
++
++static struct snd_soc_dai_driver wm8974_dai = {
++	.name = "wm8974-hifi",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,   /* Only 1 channel of data */
++		.rates = WM8974_RATES,
++		.formats = WM8974_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,   /* Only 1 channel of data */
++		.rates = WM8974_RATES,
++		.formats = WM8974_FORMATS,},
++	.ops = &wm8974_ops,
++	.symmetric_rates = 1,
++};
++
++static int wm8974_suspend(struct snd_soc_codec *codec)
++{
++	wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static int wm8974_resume(struct snd_soc_codec *codec)
++{
++	snd_soc_cache_sync(codec);
++	wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	return 0;
++}
++
++static int wm8974_probe(struct snd_soc_codec *codec)
++{
++	int ret = 0;
++	printk(KERN_NOTICE "wm8974 audio codec is provided by amba Wu Dongge\n");
++
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		return ret;
++	}
++
++	ret = wm8974_reset(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to issue reset\n");
++		return ret;
++	}
++
++	wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++	snd_soc_write(codec, WM8974_POWER1, 0x180);
++
++	/************************ RECORD PATH SETTINGS *******************************/
++	snd_soc_write(codec, WM8974_CLOCK, 0x0000);	/*set MCLK, MCLKDIV 1, BCLKDIV 1, BCLK and frame clock are inputs*/
++	snd_soc_write(codec, WM8974_GPIO, 0x0000);
++	snd_soc_write(codec, WM8974_ADD, 0x0000);
++	snd_soc_write(codec, WM8974_INPUT, 0x0103);
++	snd_soc_write(codec, WM8974_INPPGA, 0x003f);	/*set PGA gain max 35.25db*/
++	snd_soc_write(codec, WM8974_ADCBOOST, 0x0100);	/*set PGB2BOOST, MICP2BOOSTVOL gain*/
++	snd_soc_write(codec, WM8974_ADC, 0x0188);	/*Enable high pass filter, select audio mode*/
++	snd_soc_write(codec, WM8974_ADCVOL, 0x00ff);	/*Set ADC vol, 0db*/
++
++       snd_soc_write(codec, WM8974_ALC1, 0x00134);	/*Enable ALC, set max gain +29.25db and min gain +12db*/
++	snd_soc_write(codec, WM8974_ALC2, 0x003c);      /* disable zero cross switch, hold =  11ms,  target= -10.5db  */
++       snd_soc_write(codec, WM8974_ALC3, 0x0098);      /*  ALC mode, Decay = 9, attack = 8*/
++
++	snd_soc_write(codec, WM8974_NGATE, 0x000c);	/*Enable nosie gate and set threshold -63db*/
++
++	/************************ PLAYBACK PATH SETTINGS *******************************/
++	snd_soc_write(codec, WM8974_DAC, 0x0008);		/*Disable soft mute, Disable DAC auto mute, no inversion*/
++	snd_soc_write(codec, WM8974_DACVOL, 0x00ff);	/*Set DACVOL 0dB*/
++	snd_soc_write(codec, WM8974_DACLIM1, 0x0000);	/*Disable DAC Limiter*/
++	snd_soc_write(codec, WM8974_DACLIM2, 0x000c);	/*Set DAC boost 12dB*/
++	snd_soc_write(codec, WM8974_PLLN, 0x0080);		/*PLL power OFF*/
++	snd_soc_write(codec, WM8974_SPKMIX, 0x0001);	/*select output DAC to speaker mixer*/
++	snd_soc_write(codec, WM8974_SPKVOL, 0x003f);	/*Eable speaker out and set speaker volume +6dB*/
++	snd_soc_write(codec, WM8974_MONOMIX, 0x0000); /*Not select DAC to mono*/
++
++	ret = snd_soc_add_codec_controls(codec, wm8974_snd_controls,
++			     ARRAY_SIZE(wm8974_snd_controls));
++
++	return ret;
++}
++
++/* power down chip */
++static int wm8974_remove(struct snd_soc_codec *codec)
++{
++	wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	return 0;
++}
++
++static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
++	.probe = 	wm8974_probe,
++	.remove = 	wm8974_remove,
++	.suspend = 	wm8974_suspend,
++	.resume =	wm8974_resume,
++	.set_bias_level = wm8974_set_bias_level,
++	.reg_cache_size = ARRAY_SIZE(wm8974_reg),
++	.reg_word_size = sizeof(u16),
++	.reg_cache_default = wm8974_reg,
++	.reg_cache_step = 1,
++	.dapm_widgets = wm8974_dapm_widgets,
++	.num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
++	.dapm_routes = wm8974_dapm_routes,
++	.num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
++};
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static int wm8974_i2c_probe(struct i2c_client *i2c,
++				      const struct i2c_device_id *id)
++{
++	struct wm8974_priv *wm8974;
++
++	wm8974 = devm_kzalloc(&i2c->dev, sizeof(struct wm8974_priv), GFP_KERNEL);
++	if (wm8974 == NULL)
++		return -ENOMEM;
++
++	i2c_set_clientdata(i2c, wm8974);
++
++	return snd_soc_register_codec(&i2c->dev,
++			&soc_codec_dev_wm8974, &wm8974_dai, 1);
++}
++
++static int wm8974_i2c_remove(struct i2c_client *client)
++{
++	snd_soc_unregister_codec(&client->dev);
++	return 0;
++}
++
++static struct of_device_id wm8974_of_match[] = {
++	{ .compatible = "ambarella,wm8974",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, wm8974_of_match);
++
++
++static const struct i2c_device_id wm8974_i2c_id[] = {
++	{ "wm8974", 0 },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
++
++static struct i2c_driver wm8974_i2c_driver = {
++	.driver = {
++		.name = "wm8974-codec",
++		.owner = THIS_MODULE,
++		.of_match_table = wm8974_of_match,
++	},
++	.probe =    wm8974_i2c_probe,
++	.remove =   wm8974_i2c_remove,
++	.id_table = wm8974_i2c_id,
++};
++#endif
++
++static int __init wm8974_modinit(void)
++{
++	int ret = 0;
++
++	printk(KERN_INFO "wm8974_amb.c :: __init wm8974_modinit(void)\n");
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&wm8974_i2c_driver);
++	if (ret != 0) {
++		printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
++		       ret);
++	}
++#endif
++	return ret;
++}
++module_init(wm8974_modinit);
++
++static void __exit wm8974_exit(void)
++{
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	i2c_del_driver(&wm8974_i2c_driver);
++#endif
++}
++module_exit(wm8974_exit);
++
++MODULE_DESCRIPTION("ASoC WM8974 driver");
++MODULE_AUTHOR("Wu Dongge");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/wm8974_amb.h b/sound/soc/codecs/wm8974_amb.h
+new file mode 100644
+index 00000000..b82e31b8
+--- /dev/null
++++ b/sound/soc/codecs/wm8974_amb.h
+@@ -0,0 +1,94 @@
++/*
++ * wm8974_amb.h  --  WM8974 Soc Audio driver
++ *
++ * 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.
++ */
++
++#ifndef _WM8974_AMB_H
++#define _WM8974_AMB_H
++
++/* WM8974 register space */
++
++#define WM8974_RESET		0x0
++#define WM8974_POWER1		0x1
++#define WM8974_POWER2		0x2
++#define WM8974_POWER3		0x3
++#define WM8974_IFACE		0x4
++#define WM8974_COMP		0x5
++#define WM8974_CLOCK		0x6
++#define WM8974_ADD		0x7
++#define WM8974_GPIO		0x8
++#define WM8974_DAC		0xa
++#define WM8974_DACVOL		0xb
++#define WM8974_ADC		0xe
++#define WM8974_ADCVOL		0xf
++#define WM8974_EQ1		0x12
++#define WM8974_EQ2		0x13
++#define WM8974_EQ3		0x14
++#define WM8974_EQ4		0x15
++#define WM8974_EQ5		0x16
++#define WM8974_DACLIM1		0x18
++#define WM8974_DACLIM2		0x19
++#define WM8974_NOTCH1		0x1b
++#define WM8974_NOTCH2		0x1c
++#define WM8974_NOTCH3		0x1d
++#define WM8974_NOTCH4		0x1e
++#define WM8974_ALC1		0x20
++#define WM8974_ALC2		0x21
++#define WM8974_ALC3		0x22
++#define WM8974_NGATE		0x23
++#define WM8974_PLLN		0x24
++#define WM8974_PLLK1		0x25
++#define WM8974_PLLK2		0x26
++#define WM8974_PLLK3		0x27
++#define WM8974_ATTEN		0x28
++#define WM8974_INPUT		0x2c
++#define WM8974_INPPGA		0x2d
++#define WM8974_ADCBOOST		0x2f
++#define WM8974_OUTPUT		0x31
++#define WM8974_SPKMIX		0x32
++#define WM8974_SPKVOL		0x36
++#define WM8974_MONOMIX		0x38
++
++#define WM8974_CACHEREGNUM 	57
++
++/* Clock divider Id's */
++#define WM8974_OPCLKDIV		0
++#define WM8974_MCLKDIV		1
++#define WM8974_BCLKDIV		2
++
++/* Clock source */
++#define WM8974_MCLKIN		0
++#define WM8974_PLLOUT		1
++#define WM8974_MCLKIN_BCLKOUT	2
++
++/* PLL Out dividers */
++#define WM8974_OPCLKDIV_1	(0 << 4)
++#define WM8974_OPCLKDIV_2	(1 << 4)
++#define WM8974_OPCLKDIV_3	(2 << 4)
++#define WM8974_OPCLKDIV_4	(3 << 4)
++
++/* BCLK clock dividers */
++#define WM8974_BCLKDIV_1	(0 << 2)
++#define WM8974_BCLKDIV_2	(1 << 2)
++#define WM8974_BCLKDIV_4	(2 << 2)
++#define WM8974_BCLKDIV_8	(3 << 2)
++#define WM8974_BCLKDIV_16	(4 << 2)
++#define WM8974_BCLKDIV_32	(5 << 2)
++
++/* MCLK clock dividers */
++#define WM8974_MCLKDIV_1	(0 << 5)
++#define WM8974_MCLKDIV_1_5	(1 << 5)
++#define WM8974_MCLKDIV_2	(2 << 5)
++#define WM8974_MCLKDIV_3	(3 << 5)
++#define WM8974_MCLKDIV_4	(4 << 5)
++#define WM8974_MCLKDIV_6	(5 << 5)
++#define WM8974_MCLKDIV_8	(6 << 5)
++#define WM8974_MCLKDIV_12	(7 << 5)
++
++#define WM8974_SYSCLK	0
++
++
++#endif
+diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
+index cda3cf23..8d62148b 100644
+--- a/sound/soc/codecs/wm8994.c
++++ b/sound/soc/codecs/wm8994.c
+@@ -4218,7 +4218,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
+ 		break;
+ 	}
+ 
+-	wm_hubs_add_analogue_routes(codec, 0, 0);
++	wm_hubs_add_analogue_routes(codec, control->pdata.lineout1_diff,
++				    control->pdata.lineout2_diff);
+ 	snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+ 
+ 	switch (control->type) {
+diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
+index 7a0466eb..875e211f 100644
+--- a/sound/soc/codecs/wm_hubs.c
++++ b/sound/soc/codecs/wm_hubs.c
+@@ -1104,8 +1104,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
+ };
+ 
+ static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
+-	{ "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" },
+-	{ "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" },
++	{ "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
++	{ "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
+ 	{ "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
+ 
+ 	{ "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
+diff --git a/sound/soc/codecs/zl380tw.c b/sound/soc/codecs/zl380tw.c
+new file mode 100644
+index 00000000..328252ac
+--- /dev/null
++++ b/sound/soc/codecs/zl380tw.c
+@@ -0,0 +1,3114 @@
++/*
++ * zl380tw.c  --  zl380tw ALSA Soc Audio driver
++ *
++ * Copyright 2014 Microsemi Inc.
++ *   History:
++ *        2015/02/15  - created driver that combines a CHAR,
++                           an ASLSA and a SPI/I2C driver in on single module
++ *        2015/03/24  - Added compatibility to linux kernel 2.6.x to 3.x.x
++ *                      - Verified with Linux kernels 2.6.38, and 3.10.50
++ *        2015/09/30  - Added option to compile the firmware/config in c format with the kernel
++ *        2015/10/7   - Updated the save config to flash to allow saving multiple config to flash
++ * This program is free software you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option)any later version.
++ */
++
++#define DEBUG
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include <linux/sysfs.h>
++#include <linux/slab.h>
++#include <linux/kthread.h>
++#include <linux/version.h>
++#include <linux/err.h>
++#include <linux/list.h>
++#include <linux/errno.h>
++#include <linux/gpio.h>
++#include <linux/of_gpio.h>
++
++#include "zl380tw.h"
++#ifdef ZL380XX_TW_UPDATE_FIRMWARE
++#ifdef ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
++#include <linux/firmware.h>
++#else
++/*compile the firmware.c and config.c in*/
++#include "zl380tw_firmware.c"
++#include "zl380tw_config.c"
++#endif  /*ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB*/
++#endif  /*ZL380XX_TW_UPDATE_FIRMWARE*/
++
++#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
++#include <linux/compat.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#endif /*SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING*/
++
++#ifdef MICROSEMI_HBI_SPI
++#include <linux/spi/spi.h>
++#endif
++
++#ifdef MICROSEMI_HBI_I2C
++#include <linux/i2c.h>
++#endif
++
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/initval.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/pcm_params.h>
++#include <sound/tlv.h>
++#endif
++
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++#include <linux/fs.h>
++#include <linux/cdev.h>
++#include <linux/uaccess.h>
++#endif
++
++/*define this macro for critical region protection*/
++#ifdef PROTECT_CRITICAL_SECTION
++#include <linux/mutex.h>
++#endif
++
++#define MSCCDEBUG
++#undef MSCCDEBUG2
++
++#ifdef MSCCDEBUG
++#define TW_DEBUG1(s, args...) \
++	pr_err("%s %d: "s, __func__, __LINE__, ##args);
++
++#else
++#define TW_DEBUG1(s, args...)
++#endif
++
++#ifdef MSCCDEBUG2
++#define TW_DEBUG2(s, args...) \
++	pr_err("%s %d: "s, __func__, __LINE__, ##args);
++
++#else
++#define TW_DEBUG2(s, args...)
++#endif
++
++
++/*TWOLF HBI ACCESS MACROS-------------------------------*/
++#define HBI_PAGED_READ(offset,length) \
++    ((u16)(((u16)(offset) << 8) | (length)))
++#define HBI_DIRECT_READ(offset,length) \
++    ((u16)(0x8000 | ((u16)(offset) << 8) | (length)))
++#define HBI_PAGED_WRITE(offset,length) \
++    ((u16)(HBI_PAGED_READ(offset,length) | 0x0080))
++#define HBI_DIRECT_WRITE(offset,length) \
++    ((u16)(HBI_DIRECT_READ(offset,length) | 0x0080))
++#define HBI_GLOBAL_DIRECT_WRITE(offset,length) \
++    ((u16)(0xFC00 | ((offset) << 4) | (length)))
++#define HBI_CONFIGURE(pinConfig) \
++    ((u16)(0xFD00 | (pinConfig)))
++#define HBI_SELECT_PAGE(page) \
++    ((u16)(0xFE00 | (page)))
++#define HBI_NO_OP \
++    ((u16)0xFFFF)
++
++/*HBI access type*/
++#define TWOLF_HBI_READ 0
++#define TWOLF_HBI_WRITE 1
++/*HBI address type*/
++#define TWOLF_HBI_DIRECT 2
++#define TWOLF_HBI_PAGED  3
++
++/* driver private data */
++struct zl380tw {
++#ifdef MICROSEMI_HBI_SPI
++	struct spi_device	*spi;
++#endif
++#ifdef MICROSEMI_HBI_I2C
++	struct i2c_client   *i2c;
++#endif
++	u8  *pData;
++	int sysclk_rate;
++#ifdef PROTECT_CRITICAL_SECTION
++	struct list_head	device_entry;
++#endif
++	u8 flag;
++	u8 init_done;
++	int pwr_pin;
++	unsigned int pwr_active;
++	int rst_pin;
++	unsigned int rst_active;
++
++} *zl380tw_priv;
++
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++dev_t t_dev;
++
++/* For registration of character device */
++static struct cdev c_dev;
++static ioctl_zl380tw zl380tw_ioctl_buf;
++#endif
++static int module_usage_count;
++
++static unsigned twHBImaxTransferSize =(MAX_TWOLF_ACCESS_SIZE_IN_BYTES);
++module_param(twHBImaxTransferSize, uint, S_IRUGO);
++MODULE_PARM_DESC(twHBImaxTransferSize, "total number of data bytes >= 264");
++
++#ifdef ZL380XX_TW_UPDATE_FIRMWARE
++#ifdef ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
++static char *zl380tw_firmware_name = ZLS380TW0_TWOLF;
++module_param(zl380tw_firmware_name, charp, 0000);
++MODULE_PARM_DESC(zl380tw_firmware_name, "A character string");
++#ifdef ZL380XX_TW_UPDATE_CONFIG
++static char *zl380tw_config_name = ZLS380TW0_TWOLF_CRK;
++module_param(zl380tw_config_name, charp, 0000);
++MODULE_PARM_DESC(zl380tw_config_name, "A character string");
++#endif /*ZL380XX_TW_UPDATE_CONFIG*/
++#endif /*ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB*/
++#endif /*ZL380XX_TW_UPDATE_FIRMWARE*/
++
++/* if mutual exclusion is required for your particular platform
++ * then add mutex lock/unlock to this driver
++ */
++#ifdef PROTECT_CRITICAL_SECTION
++static DEFINE_MUTEX(lock);
++static DEFINE_MUTEX(zl380tw_list_lock);
++static LIST_HEAD(zl380tw_list);
++#endif
++
++/* if mutual exclusion is required for your particular platform
++ * then add mutex lock/unlock to this driver
++ */
++
++static void zl380twEnterCritical(void)
++{
++#ifdef PROTECT_CRITICAL_SECTION
++    mutex_lock(&lock);
++#endif
++}
++
++static void zl380twExitCritical(void)
++{
++#ifdef PROTECT_CRITICAL_SECTION
++    mutex_unlock(&lock);
++#endif
++}
++
++
++/*  write up to 252 bytes data */
++/*  zl380tw_nbytes_wr()- rewrite one or up to 252 bytes to the device
++ *  \param[in]     ptwdata     pointer to the data to write
++ *  \param[in]     numbytes    the number of bytes to write
++ *
++  *  return ::status = the total number of bytes transferred successfully
++ *                    or a negative error code
++ */
++static int
++zl380tw_nbytes_wr(struct zl380tw *zl380tw,
++                  int numbytes, u8 *pData)
++{
++
++    int status;
++#ifdef MICROSEMI_HBI_SPI
++    struct spi_message msg;
++	struct spi_transfer xfer = {
++		.len = numbytes,
++		.tx_buf = pData,
++	};
++
++	spi_message_init(&msg);
++	spi_message_add_tail(&xfer, &msg);
++	status = spi_sync(zl380tw->spi, &msg);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++    status = i2c_master_send(zl380tw->i2c, pData, numbytes);
++#endif
++	if (status < 0)
++	    return -EFAULT;
++
++    return 0;
++}
++
++/* zl38040_hbi_rd16()- Decode the 16-bit T-WOLF Regs Host address into
++ * page, offset and build the 16-bit command acordingly to the access type.
++ * then read the 16-bit word data and store it in pdata
++ *  \param[in]
++ *                .addr     the 16-bit HBI address
++ *                .pdata    pointer to the data buffer read or write
++ *
++ *  return ::status
++ */
++static int zl380tw_hbi_rd16(struct zl380tw *zl380tw,
++                             u16 addr, u16 *pdata)
++{
++
++	u16 cmd;
++	u8 page;
++	u8 offset;
++    u8 i = 0;
++    u8 buf[4] = {0, 0, 0, 0};
++
++    int status =0;
++#ifdef MICROSEMI_HBI_I2C
++    struct  i2c_msg     msg[2];
++#endif
++
++	page = addr >> 8;
++	offset = (addr & 0xFF)>>1;
++
++	if (page == 0) /*Direct page access*/
++	{
++	    cmd = HBI_DIRECT_READ(offset, 0);/*build the cmd*/
++	    buf[i++] = (cmd >> 8) & 0xFF;
++	    buf[i++] = (cmd & 0xFF);
++
++	} else { /*indirect page access*/
++	    if (page != 0xFF) {
++	        page  -=  1;
++	    }
++	    cmd = HBI_SELECT_PAGE(page);
++	    i = 0;
++    	/*select the page*/
++	    buf[i++] = (cmd >> 8) & 0xFF;
++	    buf[i++] = (cmd & 0xFF);
++    	cmd = HBI_PAGED_READ(offset, 0); /*build the cmd*/
++	    buf[i++] = (cmd >> 8) & 0xFF;
++	    buf[i++] = (cmd & 0xFF);
++	}
++	/*perform the HBI access*/
++
++#ifdef MICROSEMI_HBI_SPI
++	status = spi_write_then_read(zl380tw->spi, buf, i, buf, 2);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++	memset(msg,0,sizeof(msg));
++
++    /* Make write msg 1st with write command */
++    msg[0].addr    = zl380tw->i2c->addr;
++    msg[0].len     = i;
++    msg[0].buf     = buf;
++//    TW_DEBUG2("i2c addr = 0x%04x\n", msg[0].addr);
++//    TW_DEBUG2("numbytes:%d, cmdword = 0x%02x, %02x\n", numbytes, msg[0].buf[0], msg[0].buf[1]);
++    /* Make read msg */
++    msg[1].addr = zl380tw->i2c->addr;
++    msg[1].len  = 2;
++    msg[1].buf  = buf;
++    msg[1].flags = I2C_M_RD;
++    status = i2c_transfer(zl380tw->i2c->adapter, msg, 2);
++#endif
++	if (status <0)
++	    return status;
++
++    *pdata = (buf[0]<<8) | buf[1] ; /* Byte_HI, Byte_LO */
++    return 0;
++}
++
++/* zl38040_hbi_wr16()- this function is used for single word access by the
++ * ioctl read. It decodes the 16-bit T-WOLF Regs Host address into
++ * page, offset and build the 16-bit command acordingly to the access type.
++ * then write the command and data to the device
++ *  \param[in]
++ *                .addr      the 16-bit HBI address
++ *                .data      the 16-bit word to write
++ *
++ *  return ::status
++ */
++static int zl380tw_hbi_wr16(struct zl380tw *zl380tw,
++                             u16 addr, u16 data)
++{
++
++	u16 cmd;
++	u8 page;
++	u8 offset;
++    u8 i =0;
++    u8 buf[6] = {0, 0, 0, 0, 0, 0};
++    int status =0;
++	page = addr >> 8;
++	offset = (addr & 0xFF)>>1;
++
++	if (page == 0) /*Direct page access*/
++	{
++	    cmd = HBI_DIRECT_WRITE(offset, 0);/*build the cmd*/
++	    buf[i++] = (cmd >> 8) & 0xFF;
++	    buf[i++] = (cmd & 0xFF);
++
++	} else { /*indirect page access*/
++	    if (page != 0xFF) {
++	        page  -=  1;
++	    }
++	    cmd = HBI_SELECT_PAGE(page);
++	    i = 0;
++    	/*select the page*/
++	    buf[i++] = (cmd >> 8) & 0xFF;
++	    buf[i++] = (cmd & 0xFF);
++    	cmd = HBI_PAGED_WRITE(offset, 0); /*build the cmd*/
++	    buf[i++] = (cmd >> 8) & 0xFF;
++	    buf[i++] = (cmd & 0xFF);
++	}
++    buf[i++] = (data >> 8) & 0xFF ;
++    buf[i++] = (data & 0xFF) ;
++
++    status = zl380tw_nbytes_wr(zl380tw, i, buf);
++	if (status <0)
++	    return status;
++    return 0;
++}
++
++/*poll a specific bit of a register for clearance
++* [paran in] addr: the 16-bit register to poll
++* [paran in] bit: the bit position (0-15) to poll
++* [paran in] timeout: the if bit is not cleared within timeout exit loop
++*/
++static int zl380tw_monitor_bit(struct zl380tw *zl380tw, u16 addr, u8 bit, u16 timeout)
++{
++	u16 data = 0xBAD;
++    do {
++		zl380tw_hbi_rd16(zl380tw, addr, &data);
++		msleep(10);
++   } while ((((data & (1 << bit))>>bit) > 0) &&  (timeout-- >0));
++
++	if (timeout <= 0) {
++		TW_DEBUG1(" Operation Mode, in timeout = %d \n", timeout);
++		return -1;
++    }
++
++	return 0;
++}
++
++/* zl380tw_reset(): use this function to reset the device.
++ *
++ *
++ * Input Argument: mode  - the supported reset modes:
++ *         VPROC_ZL38040_RST_HARDWARE_ROM,
++ *         VPROC_ZL38040_RST_HARDWARE_ROM,
++ *         VPROC_ZL38040_RST_SOFT,
++ *         VPROC_ZL38040_RST_AEC
++ *         VPROC_ZL38040_RST_TO_BOOT
++ * Return:  type error code (0 = success, else= fail)
++ */
++static int zl380tw_reset(struct zl380tw *zl380tw,
++                         u16 mode)
++{
++
++    u16 addr = CLK_STATUS_REG;
++    u16 data = 0;
++    int monitor_bit = -1; /*the bit (range 0 - 15) of that register to monitor*/
++
++    /*PLATFORM SPECIFIC code*/
++    if (mode  == ZL38040_RST_HARDWARE_RAM) {       /*hard reset*/
++	    /*hard reset*/
++        data = 0x0005;
++    } else if (mode == ZL38040_RST_HARDWARE_ROM) {  /*power on reset*/
++	    /*hard reset*/
++        data = 0x0009;
++	} else if (mode == ZL38040_RST_AEC) { /*AEC method*/
++        addr = 0x0300;
++        data = 0x0001;
++        monitor_bit = 0;
++    } else if (mode == ZL38040_RST_SOFTWARE) { /*soft reset*/
++        addr = 0x0006;
++        data = 0x0002;
++        monitor_bit = 1;
++    } else if (mode == ZL38040_RST_TO_BOOT) { /*reset to bootrom mode*/
++        data = 0x0001;
++    } else {
++        TW_DEBUG1("Invalid reset type\n");
++        return -EINVAL;
++    }
++    if (zl380tw_hbi_wr16(zl380tw, addr, data) < 0)
++        return -EFAULT;
++    msleep(50); /*wait for the HBI to settle*/
++
++    if (monitor_bit >= 0) {
++        if (zl380tw_monitor_bit(zl380tw, addr, monitor_bit, 1000) < 0)
++           return -EFAULT;
++    }
++    return 0;
++}
++
++
++/* tw_mbox_acquire(): use this function to
++ *   check whether the host or the device owns the mailbox right
++ *
++ * Input Argument: None
++ * Return: error code (0 = success, else= fail)
++ */
++static int zl380tw_mbox_acquire(struct zl380tw *zl380tw)
++{
++
++    int status =0;
++   /*Check whether the host owns the command register*/
++    u16 i=0;
++    u16 temp = 0x0BAD;
++
++    for (i = 0; i < TWOLF_MBCMDREG_SPINWAIT; i++) {
++        status = zl380tw_hbi_rd16(zl380tw, ZL38040_SW_FLAGS_REG, &temp);
++        if ((status < 0)) {
++            TW_DEBUG1("ERROR %d: \n", status);
++            return status;
++        }
++        if (!(temp & ZL38040_SW_FLAGS_CMD)) {break;}
++        msleep(10); /*release*/
++        TW_DEBUG2("cmdbox =0x%04x timeout count = %d: \n", temp, i);
++    }
++    TW_DEBUG2("timeout count = %d: \n", i);
++    if ((i>= TWOLF_MBCMDREG_SPINWAIT) && (temp != ZL38040_SW_FLAGS_CMD)) {
++        return -EBUSY;
++    }
++    /*read the Host Command register*/
++    return 0;
++}
++
++/* zl380tw_cmdreg_acquire(): use this function to
++ *   check whether the last command is completed
++ *
++ * Input Argument: None
++ * Return: error code (0 = success, else= fail)
++ */
++static int zl380tw_cmdreg_acquire(struct zl380tw *zl380tw)
++{
++
++    int status =0;
++    /*Check whether the host owns the command register*/
++    u16 i=0;
++    u16 temp = 0x0BAD;
++
++    for (i = 0; i < TWOLF_MBCMDREG_SPINWAIT; i++) {
++        status = zl380tw_hbi_rd16(zl380tw, ZL38040_CMD_REG, &temp);
++        if ((status < 0)) {
++            TW_DEBUG1("ERROR %d: \n", status);
++            return status;
++        }
++        if (temp == ZL38040_CMD_IDLE) {break;}
++        msleep(10); /*wait*/
++        TW_DEBUG2("cmdReg =0x%04x timeout count = %d: \n", temp, i);
++    }
++    TW_DEBUG2("timeout count = %d: \n", i);
++    if ((i>= TWOLF_MBCMDREG_SPINWAIT) && (temp != ZL38040_CMD_IDLE)) {
++        return -EBUSY;
++    }
++    /*read the Host Command register*/
++    return 0;
++}
++
++/* zl380tw_write_cmdreg(): use this function to
++ *   access the host command register (mailbox access type)
++ *
++ * Input Argument: cmd - the command to send
++ * Return: error code (0 = success, else= fail)
++ */
++
++static int zl380tw_write_cmdreg(struct zl380tw *zl380tw, u16 cmd)
++{
++
++    int status = 0;
++    u16 buf = cmd;
++    /*Check whether the host owns the command register*/
++
++    status = zl380tw_mbox_acquire(zl380tw);
++    if ((status < 0)) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    /*write the command into the Host Command register*/
++
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_REG, buf);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    if ((cmd & 0x8000) >> 15)
++        buf = ZL38040_SW_FLAGS_CMD_NORST;
++    else
++        buf = ZL38040_SW_FLAGS_CMD;
++
++    /*Release the command reg*/
++    buf = ZL38040_SW_FLAGS_CMD;
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_SW_FLAGS_REG, buf);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    return zl380tw_cmdreg_acquire(zl380tw);
++}
++
++/* Write 16bit HBI Register */
++/* zl380tw_wr16()- write a 16bit word
++ *  \param[in]     cmdword  the 16-bit word to write
++ *
++ *  return ::status
++ */
++static int zl380tw_wr16(struct zl380tw *zl380tw,
++                        u16 cmdword)
++{
++
++	u8 buf[2] = {(cmdword >> 8) & 0xFF, (cmdword & 0xFF)};
++	int status = 0;
++#ifdef MICROSEMI_HBI_SPI
++	struct spi_message msg;
++	struct spi_transfer xfer = {
++		.len = 2,
++		.tx_buf = buf,
++	};
++
++	spi_message_init(&msg);
++
++	spi_message_add_tail(&xfer, &msg);
++	status = spi_sync(zl380tw->spi, &msg);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++    status = i2c_master_send(zl380tw->i2c, buf, 2);
++#endif
++	return status;
++}
++
++/*To initialize the Twolf HBI interface
++ * Param[in] - cmd_config  : the 16-bit HBI init command ored with the
++ *                           8-bit configuration.
++ *              The command format is cmd_config = 0xFD00 | CONFIG_VAL
++ *              CONFIG_VAL: is you desired HBI config value
++ *              (see device datasheet)
++ */
++static int zl380tw_hbi_init(struct zl380tw *zl380tw,
++                            u16 cmd_config)
++{
++	return zl380tw_wr16(zl380tw, HBI_CONFIGURE(cmd_config));
++}
++
++
++#if defined(ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER) || defined(ZL380XX_TW_UPDATE_FIRMWARE)
++
++
++static int zl380tw_cmdresult_check(struct zl380tw *zl380tw)
++{
++    int status = 0;
++    u16 buf;
++    status = zl380tw_hbi_rd16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, &buf);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    if (buf !=0) {
++        TW_DEBUG1("Command failed...Resultcode = 0x%04x\n", buf);
++        return buf;
++    }
++    return 0;
++}
++
++/*stop_fwr_to_bootmode - use this function to stop the firmware currently
++ *running
++ * And set the device in boot mode
++ * \param[in] none
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_stop_fwr_to_bootmode(struct zl380tw *zl380tw)
++{
++    return zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_FWR_STOP);
++}
++
++/*start_fwr_from_ram - use this function to start/restart the firmware
++ * previously stopped with VprocTwolfFirmwareStop()
++ * \param[in] none
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_start_fwr_from_ram(struct zl380tw *zl380tw)
++{
++    if (zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_FWR_GO) < 0) {
++        return -EFAULT;
++    }
++    zl380tw->init_done = 1; /*firmware is running in the device*/
++    return 0;
++}
++
++/*tw_init_check_flash - use this function to check if there is a flash on board
++ * and initialize it
++ * \param[in] none
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_init_check_flash(struct zl380tw *zl380tw)
++{
++     /*if there is a flash on board initialize it*/
++    return zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_HOST_FLASH_INIT);
++}
++
++/*tw_erase_flash - use this function to erase all firmware image
++* and related  config from flash
++ * previously stopped with VprocTwolfFirmwareStop()
++ * \param[in] none
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_erase_flash(struct zl380tw *zl380tw)
++{
++
++    int status =0;
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    /*erase all config/fwr*/
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, 0xAA55);
++    if (status < 0) {
++        return status;
++    }
++
++    /*erase firmware*/
++    return zl380tw_write_cmdreg(zl380tw, 0x0009);
++
++}
++/*erase_fwrcfg_from_flash - use this function to erase a psecific firmware image
++* and related  config from flash
++ * previously stopped with VprocTwolfFirmwareStop()
++ * Input Argument: image_number   - (range 1-14)
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_erase_fwrcfg_from_flash(struct zl380tw *zl380tw,
++                                                           u16 image_number)
++{
++    int status = 0;
++    if (image_number <= 0) {
++        return -EINVAL;
++    }
++    /*save the config/fwr to flash position image_number */
++    status = zl380tw_stop_fwr_to_bootmode(zl380tw);
++    if (status < 0) {
++        return status;
++    }
++    msleep(50);
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
++    if (status < 0) {
++        return status;
++    }
++    status  = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_CFG_ERASE);
++    if (status < 0) {
++        return status;
++    }
++
++    return zl380tw_cmdresult_check(zl380tw);
++}
++
++
++/* tw_save_image_to_flash(): use this function to
++ *     save both the config record and the firmware to flash. It Sets the bit
++ *     which initiates a firmware save to flash when the device
++ *     moves from a STOPPED state to a RUNNING state (by using the GO bit)
++ *
++ * Input Argument: None
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int zl380tw_save_image_to_flash(struct zl380tw *zl380tw)
++{
++    int status = 0;
++    /*Save firmware to flash*/
++
++#if 0
++     /*delete all applications on flash*/
++    status = zl380tw_erase_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: tw_erase_flash\n", status);
++        return status;
++    }
++#else
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++#endif
++    /*save the image to flash*/
++    status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_CFG_SAVE);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: zl380tw_write_cmdreg\n", status);
++        return status;
++    }
++    return zl380tw_cmdresult_check(zl380tw);
++    /*return status;*/
++}
++
++/*load_fwr_from_flash - use this function to load a specific firmware image
++* from flash
++ * previously stopped with VprocTwolfFirmwareStop()
++ * Input Argument: image_number   - (range 1-14)
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_load_fwr_from_flash(struct zl380tw *zl380tw,
++                                                       u16 image_number)
++{
++    int status = 0;
++
++    if (image_number <= 0) {
++        return -EINVAL;
++    }
++
++    status = zl380tw_stop_fwr_to_bootmode(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    /*load the fwr to flash position image_number */
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_LOAD);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    return zl380tw_start_fwr_from_ram(zl380tw);
++}
++
++/*zl380tw_load_fwrcfg_from_flash - use this function to load a specific firmware image
++* related and config from flash
++ * previously stopped with VprocTwolfFirmwareStop()
++ * Input Argument: image_number   - (range 1-14)
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_load_fwrcfg_from_flash(struct zl380tw *zl380tw,
++                                                  u16 image_number)
++{
++
++    int status = 0;
++    if (image_number <= 0) {
++        return -EINVAL;
++    }
++    status = zl380tw_stop_fwr_to_bootmode(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    /*save the config to flash position image_number */
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_CFG_LOAD);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    return zl380tw_start_fwr_from_ram(zl380tw);
++}
++
++
++
++/*zl380tw_load_cfg_from_flash - use this function to load a specific firmware image
++* from flash
++ *  * Input Argument: image_number   - (range 1-14)
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_load_cfg_from_flash(struct zl380tw *zl380tw,
++                                                    u16 image_number)
++{
++    int status = 0;
++
++    if (image_number <= 0) {
++        return -EINVAL;
++    }
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    /*load the config from flash position image_number */
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    return zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_CFG_LOAD);
++}
++
++/* save_cfg_to_flash(): use this function to
++ *     save the config record to flash. It Sets the bit
++ *     which initiates a config save to flash when the device
++ *     moves from a STOPPED state to a RUNNING state (by using the GO bit)
++ *
++ * \retval ::0 success
++ * \retval ::-EINVAL or device error code
++ */
++static int  zl380tw_save_cfg_to_flash(struct zl380tw *zl380tw, u16 image_number)
++{
++    int status = 0;
++    u16 buf = 0;
++    /*Save config to flash*/
++
++     /*if there is a flash on board initialize it*/
++    status = zl380tw_init_check_flash(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    /*check if a firmware exists on the flash*/
++    status = zl380tw_hbi_rd16(zl380tw, ZL38040_FWR_COUNT_REG, &buf);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    if (buf ==0)
++        return -EBADSLT; /*There is no firmware on flash position image_number to save config for*/
++
++    /*save the config to flash position */
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    /*save the config to flash position */
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_REG, 0x8002);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    /*save the config to flash position */
++    status = zl380tw_hbi_wr16(zl380tw, ZL38040_SW_FLAGS_REG, 0x0004);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    status = zl380tw_cmdreg_acquire(zl380tw);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: tw_cmdreg_acquire\n", status);
++        return status;
++    }
++    /*Verify wheter the operation completed sucessfully*/
++    return zl380tw_cmdresult_check(zl380tw);
++}
++
++/*AsciiHexToHex() - to convert ascii char hex to integer hex
++ * pram[in] - str - pointer to the char to convert.
++ * pram[in] - len - the number of character to convert (2:u8, 4:u16, 8:u32).
++
++ */
++static unsigned int AsciiHexToHex(const char * str, unsigned char len)
++{
++    unsigned int val = 0;
++    char c;
++    unsigned char i = 0;
++    for (i = 0; i< len; i++)
++    {
++        c = *str++;
++		val <<= 4;
++
++        if (c >= '0' && c <= '9')
++        {
++            val += c & 0x0F;
++            continue;
++        }
++
++        c &= 0xDF;
++        if (c >= 'A' && c <= 'F')
++        {
++            val += (c & 0x07) + 9;
++            continue;
++        }
++        return 0;
++    }
++    return val;
++}
++
++/* These 3 functions provide an alternative method to loading an *.s3
++ *  firmware image into the device
++ * Procedure:
++ * 1- Call zl380tw_boot_prepare() to put the device in boot mode
++ * 2- Call the zl380tw_boot_Write() repeatedly by passing it a pointer
++ *    to one line of the *.s3 image at a time until the full image (all lines)
++ *    are transferred to the device successfully.
++ *    When the transfer of a line is complete, this function will return the sta-
++ *    tus VPROC_STATUS_BOOT_LOADING_MORE_DATA. Then when all lines of the image
++ *    are transferred the function will return the status
++ *         VPROC_STATUS_BOOT_LOADING_CMP
++ * 3- zl380tw_boot_conclude() to complete and verify the completion status of
++ *    the image boot loading process
++ *
++ */
++static int zl380tw_boot_prepare(struct zl380tw *zl380tw)
++{
++
++    u16 buf = 0;
++    int status = 0;
++	status = zl380tw_hbi_wr16(zl380tw, CLK_STATUS_REG, 1); /*go to boot rom mode*/
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++    msleep(50); /*required for the reset to cmplete*/
++    /*check whether the device has gone into boot mode as ordered*/
++    status = zl380tw_hbi_rd16(zl380tw, (u16)ZL38040_CMD_PARAM_RESULT_REG, &buf);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    if ((buf != 0xD3D3)) {
++        TW_DEBUG1("ERROR: HBI is not accessible, cmdResultCheck = 0x%04x\n",
++		buf);
++        return  -EFAULT;
++    }
++	return 0;
++}
++/*----------------------------------------------------------------------------*/
++
++static int zl380tw_boot_conclude(struct zl380tw *zl380tw)
++{
++    int status = 0;
++	status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_HOST_LOAD_CMP); /*loading complete*/
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: \n", status);
++        return status;
++    }
++
++    /*check whether the device has gone into boot mode as ordered*/
++    return zl380tw_cmdresult_check(zl380tw);
++}
++
++/*----------------------------------------------------------------------------*/
++/*  Read up to 256 bytes data */
++/*  slave_zl380xx_nbytesrd()- read one or up to 256 bytes from the device
++ *  \param[in]     ptwdata     pointer to the data read
++ *  \param[in]     numbytes    the number of bytes to read
++ *
++ *  return ::status = the total number of bytes received successfully
++ *                   or a negative error code
++ */
++static int
++zl380tw_nbytes_rd(struct zl380tw *zl380tw, u8 numbytes, u8 *pData, u8 hbiAddrType)
++{
++    int status = 0;
++    int tx_len = (hbiAddrType == TWOLF_HBI_PAGED) ? 4 : 2;
++	u8 tx_buf[4] = {pData[0], pData[1], pData[2], pData[3]};
++
++#ifdef MICROSEMI_HBI_SPI
++    struct spi_message msg;
++
++	struct spi_transfer txfer = {
++		.len = tx_len,
++		.tx_buf = tx_buf,
++	};
++    struct spi_transfer rxfer = {
++		.len = numbytes,
++		.rx_buf = zl380tw->pData,
++	};
++
++	spi_message_init(&msg);
++	spi_message_add_tail(&txfer, &msg);
++	spi_message_add_tail(&rxfer, &msg);
++	status = spi_sync(zl380tw->spi, &msg);
++
++#endif
++#ifdef MICROSEMI_HBI_I2C
++    struct  i2c_msg     msg[2];
++	memset(msg,0,sizeof(msg));
++
++    msg[0].addr    = zl380tw->i2c->addr;
++    msg[0].len     = tx_len;
++    msg[0].buf     = tx_buf;
++
++    msg[1].addr = zl380tw->i2c->addr;
++    msg[1].len  = numbytes;
++    msg[1].buf  = zl380tw->pData;
++    msg[1].flags = I2C_M_RD;
++    status = i2c_transfer(zl380tw->i2c->adapter, msg, 2);
++#endif
++	if (status <0)
++	    return status;
++
++#ifdef MSCCDEBUG2
++    {
++        int i = 0;
++        printk("RD: Numbytes = %d, addrType = %d\n", numbytes, hbiAddrType);
++        for(i=0;i<numbytes;i++)
++        {
++            printk("0x%02x, ", zl380tw->pData[i]);
++        }
++        printk("\n");
++    }
++#endif
++    return 0;
++}
++
++
++static int
++zl380tw_hbi_access(struct zl380tw *zl380tw,
++       u16 addr, u16 numbytes, u8 *pData, u8 hbiAccessType)
++{
++
++	u16 cmd;
++	u8 page = addr >> 8;
++	u8 offset = (addr & 0xFF)>>1;
++	int i = 0;
++	u8 hbiAddrType = 0;
++	u8 buf[MAX_TWOLF_ACCESS_SIZE_IN_BYTES];
++	int status = 0;
++
++	u8 numwords = (numbytes/2);
++
++#ifdef MICROSEMI_HBI_SPI
++	if (zl380tw->spi == NULL) {
++	    TW_DEBUG1("spi device is not available \n");
++	    return -EFAULT;
++    }
++#endif
++#ifdef MICROSEMI_HBI_I2C
++	if (zl380tw->i2c == NULL) {
++	    TW_DEBUG1("i2c device is not available \n");
++	    return -EFAULT;
++    }
++#endif
++	if ((numbytes > MAX_TWOLF_ACCESS_SIZE_IN_BYTES) || (numbytes ==0))
++	    return -EINVAL;
++
++	if (pData == NULL)
++	    return -EINVAL;
++
++    if (!((hbiAccessType == TWOLF_HBI_WRITE) ||
++          (hbiAccessType == TWOLF_HBI_READ)))
++         return -EINVAL;
++
++	if (page == 0) /*Direct page access*/
++	{
++	    if (hbiAccessType == TWOLF_HBI_WRITE)
++           cmd = HBI_DIRECT_WRITE(offset, numwords-1);/*build the cmd*/
++        else
++           cmd = HBI_DIRECT_READ(offset, numwords-1);/*build the cmd*/
++
++	    buf[i++] = (cmd >> 8) & 0xFF ;
++        buf[i++] = (cmd & 0xFF) ;
++        hbiAddrType = TWOLF_HBI_DIRECT;
++	} else { /*indirect page access*/
++	    i = 0;
++	    if (page != 0xFF) {
++	        page  -=  1;
++	    }
++	    cmd = HBI_SELECT_PAGE(page);
++    	/*select the page*/
++		buf[i++] = (cmd >> 8) & 0xFF ;
++        buf[i++] = (cmd & 0xFF) ;
++
++        /*address on the page to access*/
++        if (hbiAccessType == TWOLF_HBI_WRITE)
++    	   cmd = HBI_PAGED_WRITE(offset, numwords-1);
++        else
++    	   cmd = HBI_PAGED_READ(offset, numwords-1);/*build the cmd*/
++
++		 buf[i++] = (cmd >> 8) & 0xFF ;
++         buf[i++] = (cmd & 0xFF) ;
++    	 hbiAddrType = TWOLF_HBI_PAGED;
++	}
++	memcpy(&buf[i], pData, numbytes);
++#ifdef MSCCDEBUG2
++    {
++        int j = 0;
++        int displaynum = numbytes;
++        if (hbiAccessType == TWOLF_HBI_WRITE)
++        	displaynum = numbytes;
++        else
++        	displaynum = i;
++
++        printk("SENDING:: Numbytes = %d, accessType = %d\n", numbytes, hbiAccessType);
++        for(j=0;j<numbytes;j++)
++        {
++            printk("0x%02x, ", pData[j]);
++        }
++        printk("\n");
++    }
++#endif
++	if (hbiAccessType == TWOLF_HBI_WRITE)
++       status = zl380tw_nbytes_wr(zl380tw, numbytes+i, buf);
++    else
++       status = zl380tw_nbytes_rd(zl380tw, numbytes, buf, hbiAddrType);
++    if (status < 0)
++        return -EFAULT;
++
++    return status;
++}
++/*
++ * __ Upload a romcode  by blocks
++ * the user app will call this function by passing it one line from the *.s3
++ * file at a time.
++ * when the firmware boot loading process find the execution address
++ * in that block of data it will return the number 23
++ * indicating that the transfer on the image data is completed, otherwise,
++ * it will return 22 indicating tha tit expect more data.
++ * If error, then a negative error code will be reported
++ */
++static int zl380tw_boot_Write(struct zl380tw *zl380tw,
++                              char *blockOfFwrData) /*0: HBI; 1:FLASH*/
++{
++
++/*Use this method to load the actual *.s3 file line by line*/
++    int status = 0;
++    int rec_type, i=0, j=0;
++    u8 numbytesPerLine = 0;
++    u8 buf[MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES];
++    unsigned long address = 0;
++    u8 page255Offset = 0x00;
++    u16 cmd = 0;
++
++    TW_DEBUG2("firmware line# = %d :: blockOfFwrData = %s\n",++myCounter, blockOfFwrData);
++
++    if (blockOfFwrData == NULL) {
++       TW_DEBUG1("blockOfFwrData[0] = %c\n", blockOfFwrData[0]);
++       return -EINVAL;
++    }
++    /* if this line is not an srecord skip it */
++    if (blockOfFwrData[0] != 'S') {
++        TW_DEBUG1("blockOfFwrData[0] = %c\n", blockOfFwrData[0]);
++        return -EINVAL;
++    }
++    /* get the srecord type */
++    rec_type = blockOfFwrData[1] - '0';
++
++    numbytesPerLine = AsciiHexToHex(&blockOfFwrData[2], 2);
++    //TW_DEBUG2("numbytesPerLine = %d\n", numbytesPerLine);
++    if (numbytesPerLine == 0) {
++         TW_DEBUG1("blockOfFwrData[3] = %c\n", blockOfFwrData[3]);
++         return -EINVAL;
++    }
++
++    /* skip non-existent srecord types and block header */
++    if ((rec_type == 4) || (rec_type == 5) || (rec_type == 6) ||
++                                              (rec_type == 0)) {
++        return TWOLF_STATUS_NEED_MORE_DATA;
++    }
++
++    /* get the info based on srecord type (skip checksum) */
++    address = AsciiHexToHex(&blockOfFwrData[4], 8);
++    buf[0] = (u8)((address >> 24) & 0xFF);
++    buf[1] = (u8)((address >> 16) & 0xFF);
++    buf[2] = (u8)((address >> 8) & 0xFF);
++    buf[3] = 0;
++    page255Offset = (u8)(address & 0xFF);
++    /* store the execution address */
++    if ((rec_type == 7) || (rec_type == 8) || (rec_type == 9)) {
++        /* the address is the execution address for the program */
++        //TW_DEBUG2("execAddr = 0x%08lx\n", address);
++        /* program the program's execution start register */
++        buf[3] = (u8)(address & 0xFF);
++        status = zl380tw_hbi_access(zl380tw,
++                       ZL38040_FWR_EXEC_REG, 4, buf, TWOLF_HBI_WRITE);
++
++        if(status < 0) {
++            TW_DEBUG1("ERROR % d: unable to program page 1 execution address\n", status);
++            return status;
++        }
++        TW_DEBUG2("Loading firmware data complete...\n");
++        return TWOLF_STATUS_BOOT_COMPLETE;  /*BOOT_COMPLETE Sucessfully*/
++    }
++
++    /* put the address into our global target addr */
++
++
++    //TW_DEBUG2("TW_DEBUG2:gTargetAddr = 0x%08lx: \n", address);
++    status = zl380tw_hbi_access(zl380tw,
++                       PAGE_255_BASE_HI_REG, 4, buf, TWOLF_HBI_WRITE);
++    if (status < 0) {
++        TW_DEBUG1("ERROR %d: gTargetAddr = 0x%08lx: \n", status, address);
++        return -EFAULT;
++    }
++
++    /* get the data bytes */
++    j = 12;
++    //TW_DEBUG2("buf[]= 0x%02x, 0x%02x, \n", buf[0], buf[1]);
++    for (i = 0; i < numbytesPerLine - 5; i++) {
++        buf[i] = AsciiHexToHex(&blockOfFwrData[j], 2);
++        j +=2;
++        //TW_DEBUG2("0x%02x, ", buf[i+4]);
++    }
++    /* write the data to the device */
++    cmd = (u16)(0xFF<<8) | (u16)page255Offset;
++    status = zl380tw_hbi_access(zl380tw,
++                       cmd, (numbytesPerLine - 5), buf, TWOLF_HBI_WRITE);
++    if(status < 0) {
++        return status;
++    }
++
++    //TW_DEBUG2("Provide next block of data...\n");
++    return TWOLF_STATUS_NEED_MORE_DATA; /*REQUEST STATUS_MORE_DATA*/
++}
++
++#endif
++
++
++/*----------------------------------------------------------------------*
++ *   The kernel driver functions are defined below
++ *-------------------------DRIVER FUNCTIONs-----------------------------*/
++/* zl380tw_ldfwr()
++ * This function basically  will load the firmware into the Timberwolf device
++ * at power up. this is convenient for host pluging system that does not have
++ * a slave EEPROM/FLASH to store the firmware, therefore, and that
++ * requires the device to be fully operational at power up
++*/
++#ifdef ZL380XX_TW_UPDATE_FIRMWARE
++#ifdef ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
++static int zl380tw_ldfwr(struct zl380tw *zl380tw)
++{
++
++    int status = 0;
++
++    const struct firmware *twfw;
++    u8 numbytesPerLine = 0;
++    u32 j =0;
++    u8 block_size = 0;
++
++    zl380twEnterCritical();
++
++    if (ZLS380TW0_TWOLF == NULL){
++          TW_DEBUG1("err %d, invalid firmware filename %s\n",
++                                                       status, ZLS380TW0_TWOLF);
++          zl380twExitCritical();
++          return -EINVAL;
++    }
++
++    status = request_firmware(&twfw, ZLS380TW0_TWOLF,
++#ifdef MICROSEMI_HBI_SPI
++    &zl380tw->spi->dev
++#endif
++#ifdef MICROSEMI_HBI_I2C
++    &zl380tw->i2c->dev
++#endif
++    );
++    if (status) {
++          TW_DEBUG1("err %d, request_firmware failed to load %s\n",
++                                                       status, ZLS380TW0_TWOLF);
++          zl380twExitCritical();
++          return -EINVAL;
++    }
++
++    /*check validity of the S-record firmware file*/
++    if (twfw->data[0] != 'S') {
++         TW_DEBUG1("Invalid S-record %s file for this device\n", ZLS380TW0_TWOLF);
++          release_firmware(twfw);
++          zl380twExitCritical();
++          return -EINVAL;
++    }
++
++    /* Allocating memory for the data buffer if not already done*/
++    if (!zl380tw->pData) {
++        zl380tw->pData  = kmalloc(MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES, GFP_KERNEL);
++        if (!zl380tw->pData) {
++    		TW_DEBUG1("can't allocate memory\n");
++            release_firmware(twfw);
++            zl380twExitCritical();
++            return -ENOMEM;
++        }
++        memset(zl380tw->pData, 0, MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES);
++    }
++
++    status = zl380tw_boot_prepare(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, tw boot prepare failed\n", status);
++          goto fwr_cleanup;
++    }
++
++    TW_DEBUG1("loading firmware %s into the device ...\n", ZLS380TW0_TWOLF);
++
++    do {
++		numbytesPerLine = AsciiHexToHex(&twfw->data[j+2], 2);
++        block_size = (4 + (2*numbytesPerLine));
++
++        memcpy(zl380tw->pData, &twfw->data[j], block_size);
++		j += (block_size+2);
++
++        status = zl380tw_boot_Write(zl380tw, zl380tw->pData);
++        if ((status != (int)TWOLF_STATUS_NEED_MORE_DATA) &&
++            (status != (int)TWOLF_STATUS_BOOT_COMPLETE)) {
++              TW_DEBUG1("err %d, tw boot write failed\n", status);
++              goto fwr_cleanup;
++        }
++
++    } while ((j < twfw->size) && (status != TWOLF_STATUS_BOOT_COMPLETE));
++
++    status = zl380tw_boot_conclude(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, twfw->size = %d, tw boot conclude -firmware loading failed\n", status, twfw->size);
++          goto fwr_cleanup;
++    }
++#ifdef ZL38040_SAVE_FWR_TO_FLASH
++    status = zl380tw_save_image_to_flash(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, twfw->size = %d, saving firmware failed\n", status, twfw->size);
++          goto fwr_cleanup;
++    }
++#endif  /*ZL38040_SAVE_FWR_TO_FLASH*/
++    status = zl380tw_start_fwr_from_ram(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, twfw->size = %d, starting firmware failed\n", status, twfw->size);
++          goto fwr_cleanup;
++    }
++/*loading the configuration record*/
++#ifdef ZL380XX_TW_UPDATE_CONFIG
++   {
++        u16 reg = 0  ,val =0;
++        release_firmware(twfw);
++        j = 6; /*skip the CR2K key word*/
++        numbytesPerLine = 10;
++        status = request_firmware(&twfw, ZLS380TW0_TWOLF_CRK,
++    #ifdef MICROSEMI_HBI_SPI
++        &zl380tw->spi->dev
++    #endif
++    #ifdef MICROSEMI_HBI_I2C
++        &zl380tw->i2c->dev
++    #endif
++        );
++        if (status) {
++              TW_DEBUG1("err %d, request_firmware failed to load %s\n",
++                                                           status, ZLS380TW0_TWOLF_CRK);
++              goto fwr_cleanup;
++        }
++        TW_DEBUG1("loading config %s into the device ...\n", ZLS380TW0_TWOLF_CRK);
++
++        do {
++            if(twfw->data[j] == 'E')
++                 break;
++
++            if((twfw->data[j] != 'C') && (twfw->data[j+1] != 'R')) {
++        		reg = AsciiHexToHex(&twfw->data[j], 4);
++                val = AsciiHexToHex(&twfw->data[j+6], 4);
++                status = zl380tw_hbi_wr16(zl380tw, reg, val);
++                if (status < 0) {
++                      TW_DEBUG1("err %d, tw config write failed\n", status);
++                      goto fwr_cleanup;
++                }
++                //TW_DEBUG1("reg = 0x%04x, val=0x%04x\n", reg, val);
++            }
++    		j += 12;   /*move to next pair of values*/
++
++        } while (j < twfw->size);
++#ifdef ZL38040_SAVE_FWR_TO_FLASH
++    	if (zl380tw_hbi_rd16(zl380tw, ZL38040_FWR_COUNT_REG, &val) < 0) {
++    		return -EIO;
++        }
++        if (val == 0) {
++             TW_DEBUG1("err: there is no firmware on flash\n");
++             return -1;
++        }
++
++        status = zl380tw_save_cfg_to_flash(zl380tw, val);
++        if (status < 0) {
++              TW_DEBUG1("err %d, tw save config to flash failed\n", status);
++        }
++        TW_DEBUG1("zl380tw image/cfg saved to flash position %d - success...\n", val);
++
++#endif   /*ZL38040_SAVE_FWR_TO_FLASH*/
++    }
++#endif  /*ZL380XX_TW_UPDATE_CONFIG*/
++	 /*status = zl380tw_reset(zl380tw, ZL38040_RST_SOFTWARE); */
++    goto fwr_cleanup;
++
++fwr_cleanup:
++    zl380twExitCritical();
++    release_firmware(twfw);
++
++    return status;
++}
++#else
++/*VprocTwolfLoadConfig() - use this function to load a custom or new config
++ * record into the device RAM to override the default config
++ * \retval ::VPROC_STATUS_SUCCESS
++ * \retval ::VPROC_STATUS_ERR_HBI
++ */
++static int zl380tw_load_config(struct zl380tw *zl380tw,
++    dataArr *pCr2Buf,
++    unsigned short numElements)
++{
++    int status = 0;
++    int i;
++    u8 buf[MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES];
++    /*stop the current firmware but do not reset the device and do not go to boot mode*/
++
++    /*send the config to the device RAM*/
++    for (i=0; i<numElements; i++) {
++        u8 j=0, k=0;
++        for (k = 0; k < ZL380XX_CFG_BLOCK_SIZE; k++) {
++            buf[j] = (u8)((st_twConfig[i].value[k] >> 8) & 0xFF);
++            buf[j+1] = (u8)((st_twConfig[i].value[k]) & 0xFF);
++            j +=2;
++        }
++        status = zl380tw_hbi_access(zl380tw, st_twConfig[i].reg, ZL380XX_CFG_BLOCK_SIZE*2, buf, TWOLF_HBI_WRITE);
++    }
++
++    return status;
++}
++/* zl380tw_boot_alt Use this alternate method to load the st_twFirmware.c
++ *(converted *.s3 to c code) to the device
++ */
++static int zl380tw_ldfwr(struct zl380tw *zl380tw)
++{
++    u16 index = 0;
++    u8 buf[MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES];
++    u8 page255Offset = 0x00;
++
++    int status = 0;
++
++    TW_DEBUG1("Using the firmware-config c code loading ...\n");
++    zl380twEnterCritical();
++    status = zl380tw_boot_prepare(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, tw boot prepare failed\n", status);
++          zl380twExitCritical();
++          return -1;
++    }
++
++    while (index < firmwareStreamLen) {
++        int i=0, j=0;
++		/* put the address into our global target addr */
++        buf[0] = (u8)((st_twFirmware[index].targetAddr >> 24) & 0xFF);
++        buf[1] = (u8)((st_twFirmware[index].targetAddr >> 16) & 0xFF);
++        buf[2] = (u8)((st_twFirmware[index].targetAddr >> 8) & 0xFF);
++        buf[3] = 0;
++		page255Offset = (u8)(st_twFirmware[index].targetAddr & 0xFF);
++		/* write the data to the device */
++		if (st_twFirmware[index].numWords != 0) {
++
++
++            status = zl380tw_hbi_access(zl380tw,
++                       PAGE_255_BASE_HI_REG, 4, buf, TWOLF_HBI_WRITE);
++            if (status < 0) {
++                TW_DEBUG1("ERROR %d: gTargetAddr = 0x%08lx: \n", status, st_twFirmware[index].targetAddr);
++                zl380twExitCritical();
++                return -EFAULT;
++            }
++
++
++
++            for (i = 0; i < st_twFirmware[index].numWords; i++) {
++                buf[j] = (u8)((st_twFirmware[index].buf[i] >> 8) & 0xFF);
++                buf[j+1] = (u8)((st_twFirmware[index].buf[i]) & 0xFF);
++                j+=2;
++                //TW_DEBUG2("0x%02x, ", buf[i+4]);
++            }
++            /* write the data to the device */
++
++            status = zl380tw_hbi_access(zl380tw,((u16)(0xFF<<8) | (u16)page255Offset),
++                               (st_twFirmware[index].numWords*2), buf, TWOLF_HBI_WRITE);
++            if(status < 0) {
++                zl380twExitCritical();
++                return status;
++            }
++		}
++		index++;
++    }
++
++    /*
++     * convert the number of bytes to two 16 bit
++     * values and write them to the requested page register
++     */
++    /* even number of bytes required */
++
++    /* program the program's execution start register */
++    buf[0] = (u8)((executionAddress >> 24) & 0xFF);
++    buf[1] = (u8)((executionAddress >> 16) & 0xFF);
++    buf[2] = (u8)((executionAddress >> 8) & 0xFF);
++    buf[3] = (u8)(executionAddress & 0xFF);
++    status = zl380tw_hbi_access(zl380tw,
++                   ZL38040_FWR_EXEC_REG, 4, buf, TWOLF_HBI_WRITE);
++
++    if(status < 0) {
++        TW_DEBUG1("ERROR % d: unable to program page 1 execution address\n", status);
++        zl380twExitCritical();
++        return status;
++    }
++
++    /* print out the srecord program info */
++    TW_DEBUG2("prgmBase 0x%08lx\n", programBaseAddress);
++    TW_DEBUG2("execAddr 0x%08lx\n", executionAddress);
++
++    status = zl380tw_boot_conclude(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, tw boot conclude -firmware loading failed\n", status);
++          zl380twExitCritical();
++          return -1;
++    }
++
++#ifdef ZL38040_SAVE_FWR_TO_FLASH
++    status = zl380tw_save_image_to_flash(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, saving firmware to flash failed\n", status);
++          zl380twExitCritical();
++          return status;
++    }
++#endif  /*ZL38040_SAVE_FWR_TO_FLASH*/
++    status = zl380tw_start_fwr_from_ram(zl380tw);
++    if (status < 0) {
++          TW_DEBUG1("err %d, starting firmware failed\n", status);
++          zl380twExitCritical();
++          return status;
++    }
++#ifdef ZL380XX_TW_UPDATE_CONFIG
++    zl380tw_load_config(zl380tw, (dataArr *)st_twConfig, (u16)configStreamLen);
++    if (status < 0) {
++          TW_DEBUG1("err %d, loading config failed\n", status);
++          zl380twExitCritical();
++          return status;
++    }
++#ifdef ZL38040_SAVE_FWR_TO_FLASH
++    {
++    	u16 val = 0;
++        if (zl380tw_hbi_rd16(zl380tw, ZL38040_FWR_COUNT_REG, &val) < 0) {
++    		return -EIO;
++        }
++        if (val == 0) {
++             TW_DEBUG1("err: there is no firmware on flash\n");
++             return -1;
++        }
++        status = zl380tw_save_cfg_to_flash(zl380tw, val);
++        if (status < 0) {
++              TW_DEBUG1("err %d, tw save config to flash failed\n", status);
++              zl380twExitCritical();
++              return status;
++        }
++        TW_DEBUG1("zl380tw image/cfg saved to flash position %d - success...\n", val);
++    }
++#endif   /*ZL38040_SAVE_FWR_TO_FLASH*/
++#endif   /*ZL380XX_TW_UPDATE_CONFIG*/
++    TW_DEBUG1("zl380tw boot init complete - success...\n");
++    zl380twExitCritical();
++    return 0;
++}
++#endif  /*ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB*/
++#endif  /*ZL380XX_TW_UPDATE_FIRMWARE*/
++
++
++/*--------------------------------------------------------------------
++ *    ALSA  SOC CODEC driver
++ *--------------------------------------------------------------------*/
++
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++
++/* ALSA soc codec default Timberwolf register settings
++ * 3 Example audio cross-point configurations
++ */
++/* ALSA soc codec default Timberwolf register settings
++ * 3 Example audio cross-point configurations
++ */
++#define CODEC_CONFIG_REG_NUM 42
++
++u8 reg_stereo[] ={ 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
++
++
++/*4-port m
++ode with AEC enabled  - ROUT to DAC1
++ * MIC1 -> SIN (ADC)
++ * I2S-L -> RIN (TDM Rx path)
++ * SOUT -> I2S-L
++ * ROUT -> DACx
++ *reg 0x202 - 0x22A
++ */
++u8 reg_cache_default[CODEC_CONFIG_REG_NUM] ={0x0c, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++                0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x0d,
++                0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x06, 0x05, 0x00, 0x02, 0x00, 0x00};
++
++
++
++/*Formatting for the Audio*/
++#define zl380tw_DAI_RATES            (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000)
++#define zl380tw_DAI_FORMATS          (SNDRV_PCM_FMTBIT_S16_LE)
++#define zl380tw_DAI_CHANNEL_MIN      1
++#define zl380tw_DAI_CHANNEL_MAX      2
++
++static void zl380tw_fill_codec_cache(struct snd_soc_codec *codec,
++            u8* pData, int numbytes)
++{
++     int i = 0;
++     u8* cache = codec->reg_cache;
++     for (i=0; i< numbytes; i++) {
++         cache[i] = pData[i];
++         //dev_info(codec->dev, "pData[%d]=0x%02x, cache[%d]=0x%02x\n", i, pData[i], i, cache[i]);
++    }
++}
++
++static u16 zl380tw_read_codec_cache(struct snd_soc_codec *codec, u16 reg)
++{
++     u8 i = reg - ZL38040_CACHED_ADDR_LO;
++     if (i < CODEC_CONFIG_REG_NUM) {
++         u8* cache = codec->reg_cache;
++         //dev_info(codec->dev, "cache: 0x%04x = 0x%04x\n", reg, (cache[i] << 8) | cache[i+1]);
++         return (cache[i] << 8) | cache[i+1];
++     }
++    return 0xFBAD;
++}
++
++static int zl380tw_find_index_codec_cache(struct snd_soc_codec *codec, u8 val)
++{
++     int i = 0;
++     u8* cache = codec->reg_cache;
++     /*start the search from reg 210h*/
++     for (i=14; i< CODEC_CONFIG_REG_NUM; i++) {
++         if (cache[i] == val) {
++             //dev_info(codec->dev, "cache[%d]=0x%02x\n", i, cache[i]);
++             if (i%2)
++               --i;
++             return i;
++         }
++    }
++    return -1;
++}
++
++static unsigned int zl380tw_reg_read(struct snd_soc_codec *codec,
++            unsigned int reg)
++{
++    unsigned int value = 0;
++
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++    u16 buf;
++	if (zl380tw_hbi_rd16(zl380tw, reg, &buf) < 0) {
++		return -EIO;
++    }
++    value = buf;
++
++    return value;
++
++}
++
++static int zl380tw_reg_write(struct snd_soc_codec *codec,
++            unsigned int reg, unsigned int value)
++{
++	struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++
++	if (zl380tw_hbi_wr16(zl380tw, reg, value) < 0) {
++		return -EIO;
++    }
++    return 0;
++}
++
++
++/*ALSA- soc codec I2C/SPI read control functions*/
++static int zl380tw_control_read(struct snd_kcontrol *kcontrol,
++		struct snd_ctl_elem_value *ucontrol)
++{
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++	struct soc_mixer_control *mc =
++		(struct soc_mixer_control *)kcontrol->private_value;
++	unsigned int reg = mc->reg;
++	unsigned int shift = mc->shift;
++	unsigned int mask = mc->max;
++	unsigned int invert = mc->invert;
++	u16 val;
++
++
++	zl380twEnterCritical();
++	if (zl380tw_hbi_rd16(zl380tw, reg, &val)) {
++	    zl380twExitCritical();
++		return -EIO;
++    }
++    zl380twExitCritical();
++
++	ucontrol->value.integer.value[0] = ((val >> shift) & mask);
++
++	if (invert)
++		ucontrol->value.integer.value[0] =
++			mask - ucontrol->value.integer.value[0];
++
++	return 0;
++}
++/*ALSA- soc codec I2C/SPI write control functions*/
++static int zl380tw_control_write(struct snd_kcontrol *kcontrol,
++		struct snd_ctl_elem_value *ucontrol)
++{
++
++    struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++
++	struct soc_mixer_control *mc =
++		(struct soc_mixer_control *)kcontrol->private_value;
++	unsigned int reg = mc->reg;
++	unsigned int shift = mc->shift;
++	unsigned int mask = mc->max;
++	unsigned int invert = mc->invert;
++	unsigned int val = (ucontrol->value.integer.value[0] & mask);
++    u16 valt;
++
++	if (invert)
++		val = mask - val;
++
++	zl380twEnterCritical();
++	if (zl380tw_hbi_rd16(zl380tw, reg, &valt) < 0) {
++	    zl380twExitCritical();
++		return -EIO;
++    }
++	if (((valt >> shift) & mask) == val) {
++	    zl380twExitCritical();
++		return 0;
++	}
++	valt &= ~(mask << shift);
++	valt |= val << shift;
++
++	if (zl380tw_reg_write(codec, reg, valt) < 0) {
++	    zl380twExitCritical();
++		return -EIO;
++    }
++    zl380twExitCritical();
++
++	return 0;
++}
++
++
++int zl380tw_mute_r(struct snd_soc_codec *codec, int on)
++{
++
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++	u16 val;
++
++	zl380twEnterCritical();
++
++	if (zl380tw_hbi_rd16(zl380tw, ZL38040_AEC_CTRL_REG0, &val) < 0){
++		zl380twExitCritical();
++		return -EIO;
++	}
++	if (((val >> 7) & 1) == on){
++		zl380twExitCritical();
++		return 0;
++	}
++	val &= ~(1 << 7);
++	val |= on << 7;
++
++	if (zl380tw_reg_write(codec, ZL38040_AEC_CTRL_REG0, val) < 0){
++		zl380twExitCritical();
++		return -EIO;
++	}
++
++    zl380twExitCritical();
++	return 0;
++}
++
++int zl380tw_mute_s(struct snd_soc_codec *codec, int on)
++{
++	u16 val;
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++
++	zl380twEnterCritical();
++
++	if (zl380tw_hbi_rd16(zl380tw, ZL38040_AEC_CTRL_REG0, &val)){
++		zl380twExitCritical();
++		return -EIO;
++	}
++	if (((val >> 8) & 1) == on){
++		zl380twExitCritical();
++		return 0;
++	}
++	val &= ~(1 << 8);
++	val |= on << 8;
++
++	if (zl380tw_reg_write(codec, ZL38040_AEC_CTRL_REG0, val)){
++		zl380twExitCritical();
++		return -EIO;
++	}
++
++	zl380twExitCritical();
++	return 0;
++}
++
++/* configure_codec() - configure the cross-point to either pure 2-channel stereo
++ * or for 4-port mode with Achoustic Echo Canceller
++ * mode: 0 -> Stereo bypass
++ *       1 -> 4-port mode AEC
++ *       2 ->
++ */
++static int zl380tw_configure_codec(struct snd_soc_codec *codec, u8 mode)
++{
++
++
++ 	struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++    u8 *pData;
++
++ 	switch (mode) {
++		case ZL38040_CR2_DEFAULT: {
++		    pData = codec->reg_cache;
++		    return zl380tw_hbi_access(zl380tw, ZL38040_OUTPUT_PATH_EN_REG, CODEC_CONFIG_REG_NUM, pData, TWOLF_HBI_WRITE);
++		}
++		case ZL38040_CR2_STEREO_BYPASS: {
++
++		    u16 rin_src = zl380tw_read_codec_cache(codec, ZL38040_RIN_IN_PATH_REG);
++		    u16 sin1_src = zl380tw_read_codec_cache(codec, ZL38040_SIN_IN_PATH_REG);
++
++            pData = reg_stereo;
++		    if ((rin_src != 0) || (sin1_src != 0))
++		          zl380tw_hbi_access(zl380tw, ZL38040_DAC1_IN_PATH_REG, 28, pData, TWOLF_HBI_WRITE);
++		    if (rin_src != 0) {
++		        int rout_crp = zl380tw_find_index_codec_cache(codec, ZL38040_ROUT_PATH);
++		        /*find where ROUT is going*/
++		        if (rout_crp >=0) {
++		             zl380tw_hbi_wr16(zl380tw, ZL38040_CACHED_ADDR_LO+rout_crp, (rin_src & 0xFF));
++		             //dev_info(codec->dev, "reg[rout]=0x%04x <-- rin_src = 0x%04x\n", ZL38040_CACHED_ADDR_LO+rout_crp, rin_src);
++		        }
++            }
++
++		    if (sin1_src != 0) {
++		        int sout_crp = zl380tw_find_index_codec_cache(codec, ZL38040_SOUT_PATH);
++		        /*find where ROUT is going*/
++		        if (sout_crp >=0) {
++		            zl380tw_hbi_wr16(zl380tw, ZL38040_CACHED_ADDR_LO+sout_crp, sin1_src);
++		            //dev_info(codec->dev, "reg[sout]=0x%04x <-- sin1_src=0x%04x\n", ZL38040_CACHED_ADDR_LO+sout_crp, sin1_src);
++		        }
++            }
++
++	        return 0;
++	    }
++
++		default: {
++		    return -EINVAL;
++		}
++	}
++
++}
++/*The DACx, I2Sx, TDMx Gains can be used in both AEC mode or Stereo bypass mode
++ * however the AEC Gains can only be used when AEC is active.
++ * Each input source of the cross-points has two input sources A and B.
++ * The Gain for each source can be controlled independantly.
++ */
++static const struct snd_kcontrol_new zl380tw_snd_controls[] = {
++		SOC_SINGLE_EXT("DAC1 GAIN INA", ZL38040_DAC1_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("DAC2 GAIN INA", ZL38040_DAC2_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S1L GAIN INA", ZL38040_I2S1L_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S1R GAIN INA", ZL38040_I2S1R_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S2L GAIN INA", ZL38040_I2S2L_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S2R GAIN INA", ZL38040_I2S2R_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMA3 GAIN INA", ZL38040_TDMA3_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMA4 GAIN INA", ZL38040_TDMA4_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMB3 GAIN INA", ZL38040_TDMB3_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMB4 GAIN INA", ZL38040_TDMB4_GAIN_REG, 0, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("DAC1 GAIN INB", ZL38040_DAC1_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("DAC2 GAIN INB", ZL38040_DAC2_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S1L GAIN INB", ZL38040_I2S1L_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S1R GAIN INB", ZL38040_I2S1R_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S2L GAIN INB", ZL38040_I2S2L_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("I2S2R GAIN INB", ZL38040_I2S2R_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMA3 GAIN INB", ZL38040_TDMA3_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMA4 GAIN INB", ZL38040_TDMA4_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMB3 GAIN INB", ZL38040_TDMB3_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("TDMB4 GAIN INB", ZL38040_TDMB4_GAIN_REG, 8, 0x6, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC ROUT GAIN", ZL38040_USRGAIN, 0, 0x78, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC ROUT GAIN EXT", ZL38040_USRGAIN, 7, 0x7, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC SOUT GAIN", ZL38040_SYSGAIN, 8, 0xf, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC SIN GAIN", ZL38040_SYSGAIN, 0, 0x1f, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC MIC GAIN", ZL38040_MICGAIN, 0, 0x7, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("MUTE SPEAKER ROUT", ZL38040_AEC_CTRL_REG0, 7, 1, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("MUTE MIC SOUT", ZL38040_AEC_CTRL_REG0, 8, 1, 0,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC Bypass", ZL38040_AEC_CTRL_REG0, 4, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC Audio enh bypass", ZL38040_AEC_CTRL_REG0, 5, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC Master Bypass", ZL38040_AEC_CTRL_REG0, 1, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("ALC GAIN", ZL38040_AEC_CTRL_REG1, 12, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("ALC Disable", ZL38040_AEC_CTRL_REG1, 10, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC Tail disable", ZL38040_AEC_CTRL_REG1, 12, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC Comfort Noise", ZL38040_AEC_CTRL_REG1, 6, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("NLAEC Disable", ZL38040_AEC_CTRL_REG1, 14, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("AEC Adaptation", ZL38040_AEC_CTRL_REG1, 1, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("NLP Disable", ZL38040_AEC_CTRL_REG1, 5, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("Noise Inject", ZL38040_AEC_CTRL_REG1, 6, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("LEC Disable", ZL38040_LEC_CTRL_REG, 4, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++		SOC_SINGLE_EXT("LEC Adaptation", ZL38040_LEC_CTRL_REG, 1, 1, 1,
++				zl380tw_control_read, zl380tw_control_write),
++
++};
++
++
++int zl380tw_add_controls(struct snd_soc_codec *codec)
++{
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
++	return snd_soc_add_controls(codec, zl380tw_snd_controls,
++			ARRAY_SIZE(zl380tw_snd_controls));
++#else
++	return snd_soc_add_codec_controls(codec, zl380tw_snd_controls,
++			ARRAY_SIZE(zl380tw_snd_controls));
++#endif
++}
++
++static int zl380tw_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_codec *codec = rtd->codec;
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++#ifdef MICROSEMI_DEMO_PLATFORM
++
++ 	unsigned int buf2, buf3, buf4;
++
++ 	unsigned int buf0 = zl380tw_reg_read(codec, ZL38040_TDMA_CLK_CFG_REG);
++
++    zl380twEnterCritical();
++ 	buf2 = zl380tw_reg_read(codec, ZL38040_TDMA_CH1_CFG_REG);
++ 	buf3 = zl380tw_reg_read(codec, ZL38040_TDMA_CH2_CFG_REG);
++ 	buf4 = zl380tw_reg_read(codec, ZL38040_AEC_CTRL_REG0);
++
++    if ((buf2 == 0x0BAD) || (buf3 == 0x0BAD)) {
++	   	zl380twExitCritical();
++        return -1;
++    }
++ 	switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			buf2 |= (ZL38040_TDMA_16BIT_LIN);
++			buf3 |= (ZL38040_TDMA_16BIT_LIN);
++			buf3 |= 2;  /*If PCM use 2 timeslots*/
++			break;
++		case SNDRV_PCM_FORMAT_MU_LAW:
++		    buf2 |= (ZL38040_TDMA_8BIT_ULAW);
++			buf3 |= (ZL38040_TDMA_8BIT_ULAW);
++			buf3 |= 1;  /*If PCM use 1 timeslots*/
++		    break;
++		case SNDRV_PCM_FORMAT_A_LAW:
++		    buf2 |= (ZL38040_TDMA_8BIT_ALAW );
++			buf3 |= (ZL38040_TDMA_8BIT_ALAW);
++			buf3 |= 1;  /*If PCM use 1 timeslots*/
++		    break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			break;
++		default: {
++			zl380twExitCritical();
++			return -EINVAL;
++		}
++	}
++    zl380tw_reg_write(codec, ZL38040_TDMA_CLK_CFG_REG, buf0);
++
++	zl380tw_reg_write(codec, ZL38040_TDMA_CH1_CFG_REG, buf2);
++	zl380tw_reg_write(codec, ZL38040_TDMA_CH2_CFG_REG, buf3);
++	zl380twExitCritical();
++#endif
++    /* If the ZL38040 TDM is configured as a slace I2S/PCM,
++	 * The rate settings are not necessary. The Zl38040 has the ability to
++	 * auto-detect the master rate and configure itself accordingly
++	 * If configured as master, the rate must be set acccordingly
++	 */
++    zl380twEnterCritical();
++
++    //dev_info(codec->dev, "b4: init_done=%d, flag=%d\n", zl380tw->init_done , zl380tw->flag);
++    /*initialize codec cache to default config*/
++    if((zl380tw->init_done) /*&& (codec->reg_cache==NULL)*/) {
++
++        u8* cache = codec->reg_cache;
++        if(zl380tw_hbi_access(zl380tw, ZL38040_OUTPUT_PATH_EN_REG, CODEC_CONFIG_REG_NUM, cache, TWOLF_HBI_READ) < 0)
++        {
++              zl380twExitCritical();
++              return -EFAULT;
++        }
++        zl380tw_fill_codec_cache(codec, zl380tw->pData, CODEC_CONFIG_REG_NUM);
++        zl380tw->init_done = 0;
++        zl380tw->flag = 1;
++    }
++    //dev_info(codec->dev, "aft: init_done=%d, flag=%d\n", zl380tw->init_done , zl380tw->flag);
++    switch (params_rate(params)) {
++	    case 8000:
++	    case 16000:
++	        if (zl380tw->flag > 1) {
++	             if (zl380tw_configure_codec(codec, ZL38040_CR2_DEFAULT) >=0)
++	                 zl380tw->flag = 1;
++	        }
++		    break;
++		/*case 44100:  */
++	    case 48000:
++	        if (zl380tw->flag ==1) {
++		         zl380tw_configure_codec(codec, ZL38040_CR2_STEREO_BYPASS);
++		         zl380tw->flag = 2;
++		    }
++		    break;
++		default: {
++			zl380twExitCritical();
++			return -EINVAL;
++		}
++    }
++	zl380tw_reset(zl380tw, ZL38040_RST_SOFTWARE);
++    zl380twExitCritical();
++
++	return 0;
++}
++
++static int zl380tw_mute(struct snd_soc_dai *codec_dai, int mute)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	/*zl380tw_mute_s(codec, mute);*/
++	return zl380tw_mute_r(codec, mute);
++}
++
++static int zl380tw_set_dai_fmt(struct snd_soc_dai *codec_dai,
++		unsigned int fmt)
++{
++#ifdef MICROSEMI_DEMO_PLATFORM
++    struct snd_soc_codec *codec = codec_dai->codec;
++    struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++    unsigned int buf, buf0;
++
++    zl380twEnterCritical();
++    buf = zl380tw_reg_read(codec, ZL38040_TDMA_CFG_REG);
++    buf0 = zl380tw_reg_read(codec, ZL38040_TDMA_CLK_CFG_REG);
++    if ((buf == 0x0BAD) || (buf0 == 0x0BAD)) {
++	   	zl380twExitCritical();
++        return -1;
++    }
++
++	dev_info(codec_dai->dev, "zl380tw_set_dai_fmt\n");
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++		case SND_SOC_DAIFMT_DSP_B:
++			break;
++		case SND_SOC_DAIFMT_DSP_A:
++			break;
++		case SND_SOC_DAIFMT_RIGHT_J:
++			if ((buf & ZL38040_TDMA_FSALIGN) >> 1)
++		        buf &= (~ZL38040_TDMA_FSALIGN);
++			break;
++		case SND_SOC_DAIFMT_LEFT_J:
++			if (!((buf & ZL38040_TDMA_FSALIGN) >> 1))
++		        buf |= (ZL38040_TDMA_FSALIGN);
++			break;
++		case SND_SOC_DAIFMT_I2S:
++	        if (!((buf & ZL38040_TDM_I2S_CFG_VAL) >> 1)) {
++                buf |= (ZL38040_TDM_I2S_CFG_VAL );
++             }
++			break;
++		default: {
++			zl380twExitCritical();
++			return -EINVAL;
++		}
++	}
++
++	/* set master/slave TDM interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++		case SND_SOC_DAIFMT_CBM_CFM:
++			buf0 |= ZL38040_TDM_TDM_MASTER_VAL;
++			break;
++		case SND_SOC_DAIFMT_CBS_CFS:
++			if ((buf0 & ZL38040_TDM_TDM_MASTER_VAL) >> 1) {
++			    buf0 &= (~ZL38040_TDM_TDM_MASTER_VAL);
++           }
++			break;
++		default: {
++			zl380twExitCritical();
++			return -EINVAL;
++		}
++	}
++
++    zl380tw_reg_write(codec, ZL38040_TDMA_CFG_REG, buf);
++    zl380tw_reg_write(codec, ZL38040_TDMA_CLK_CFG_REG, buf0);
++	zl380tw_reset(zl380tw, ZL38040_RST_SOFTWARE);
++	zl380twExitCritical();
++#endif
++	return 0;
++}
++
++static int zl380tw_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
++		unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++
++ 	zl380tw->sysclk_rate = freq;
++
++	return 0;
++}
++
++static const struct snd_soc_dai_ops zl380tw_dai_ops = {
++		.set_fmt        = zl380tw_set_dai_fmt,
++		.set_sysclk     = zl380tw_set_dai_sysclk,
++		.hw_params   	= zl380tw_hw_params,
++		.digital_mute   = zl380tw_mute,
++
++};
++
++static struct snd_soc_dai_driver zl380tw_dai = {
++		.name = "zl380tw-hifi",
++		.playback = {
++				.stream_name = "Playback",
++				.channels_min = zl380tw_DAI_CHANNEL_MIN,
++				.channels_max = zl380tw_DAI_CHANNEL_MAX,
++				.rates = zl380tw_DAI_RATES,
++				.formats = zl380tw_DAI_FORMATS,
++		},
++		.capture = {
++				.stream_name = "Capture",
++				.channels_min = zl380tw_DAI_CHANNEL_MIN,
++				.channels_max = zl380tw_DAI_CHANNEL_MAX,
++				.rates = zl380tw_DAI_RATES,
++				.formats = zl380tw_DAI_FORMATS,
++		},
++		.ops = &zl380tw_dai_ops,
++};
++EXPORT_SYMBOL(zl380tw_dai);
++
++static int zl380tw_set_bias_level(struct snd_soc_codec *codec,
++    enum snd_soc_bias_level level)
++{
++	struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
++
++    zl380twEnterCritical();
++    switch (level) {
++	case SND_SOC_BIAS_ON:
++		break;
++	case SND_SOC_BIAS_PREPARE:
++		break;
++	case SND_SOC_BIAS_STANDBY:
++		/*wake up from sleep*/
++		zl380tw_hbi_init(zl380tw, (HBI_CONFIG_VAL | HBI_CONFIG_WAKE));
++        msleep(10);
++		/*Clear the wake up bit*/
++	    zl380tw_hbi_init(zl380tw, HBI_CONFIG_VAL);
++
++		break;
++	case SND_SOC_BIAS_OFF:
++		 /*Low power sleep mode*/
++		zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_APP_SLEEP);
++
++		break;
++	}
++	zl380twExitCritical();
++
++	//codec->dapm.bias_level = level;
++	return 0;
++}
++
++static int zl380tw_suspend(struct snd_soc_codec *codec
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
++   , pm_message_t state
++#endif
++)
++{
++	zl380twEnterCritical();
++	zl380tw_set_bias_level(codec, SND_SOC_BIAS_OFF);
++	zl380twExitCritical();
++	return 0;
++}
++
++static int zl380tw_resume(struct snd_soc_codec *codec)
++{
++	zl380twEnterCritical();
++	zl380tw_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++    zl380twExitCritical();
++	return 0;
++}
++
++static void zl380tw_sub_probe_clean(void);
++
++static int zl380tw_probe(struct snd_soc_codec *codec)
++{
++	dev_info(codec->dev, "Probing zl380tw SoC CODEC driver\n");
++	return zl380tw_add_controls(codec);
++}
++
++static int zl380tw_remove(struct snd_soc_codec *codec)
++{
++	return 0;
++}
++
++static struct snd_soc_codec_driver soc_codec_dev_zl380tw = {
++	.probe =	zl380tw_probe,
++	.remove =	zl380tw_remove,
++	.suspend =	zl380tw_suspend,
++	.resume =	zl380tw_resume,
++    .read  = zl380tw_reg_read,
++	.write = zl380tw_reg_write,
++	.set_bias_level = zl380tw_set_bias_level,
++	.reg_cache_size = CODEC_CONFIG_REG_NUM,
++	.reg_word_size = sizeof(u8),
++	.reg_cache_default = reg_cache_default,
++	.reg_cache_step = 1,
++};
++EXPORT_SYMBOL(soc_codec_dev_zl380tw);
++#endif /*ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER*/
++
++/*--------------------------------------------------------------------
++ *    ALSA  SOC CODEC driver  - END
++ *--------------------------------------------------------------------*/
++
++
++/*--------------------------------------------------------------------
++ *    CHARACTER type Host Interface driver
++ *--------------------------------------------------------------------*/
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++
++/* read 16bit HBI Register */
++/* slave_rd16()- read a 16bit word
++ *  \param[in]     pointer the to where to store the data
++ *
++ *  return ::status
++ */
++static int zl380tw_rd16(struct zl380tw *zl380tw, u16 *pdata)
++{
++	u8 buf[2] = {0, 0};
++	int status = 0;
++#ifdef MICROSEMI_HBI_SPI
++	struct spi_message msg;
++	struct spi_transfer xfer = {
++		.len = 2,
++		.rx_buf = buf,
++	};
++
++	spi_message_init(&msg);
++
++	spi_message_add_tail(&xfer, &msg);
++	status = spi_sync(zl380tw->spi, &msg);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++    status = i2c_master_recv(zl380tw->i2c, buf, 2);
++#endif
++	if (status < 0) {
++		return status;
++	}
++
++    *pdata = (buf[0]<<8) | buf[1] ; /* Byte_HI, Byte_LO */
++	return 0;
++}
++
++
++ static long zl380tw_io_ioctl(
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
++   struct inode *i,
++#endif
++   struct file *filp,
++   unsigned int cmd, unsigned long arg)
++{
++	int retval =0;
++	u16 buf =0;
++	struct zl380tw *zl380tw = filp->private_data;
++
++	switch (cmd) {
++
++	case TWOLF_HBI_WR16:
++		if (copy_from_user(&zl380tw_ioctl_buf,
++			               (ioctl_zl380tw *)arg,
++			                sizeof(ioctl_zl380tw)))
++			return -EFAULT;
++		zl380twEnterCritical();
++		retval = zl380tw_hbi_wr16(zl380tw, (u16)zl380tw_ioctl_buf.addr,
++                                     zl380tw_ioctl_buf.data);
++        zl380twExitCritical();
++	break;
++	case TWOLF_HBI_RD16:
++		if (copy_from_user(&zl380tw_ioctl_buf,
++			               (ioctl_zl380tw *)arg,
++			                sizeof(ioctl_zl380tw)))
++			return -EFAULT;
++		zl380twEnterCritical();
++		retval = zl380tw_hbi_rd16(zl380tw, (u16)zl380tw_ioctl_buf.addr,
++                                    &zl380tw_ioctl_buf.data);
++        zl380twExitCritical();
++		if (!retval) {
++			if (copy_to_user((ioctl_zl380tw *)arg,
++			                  &zl380tw_ioctl_buf,
++                              sizeof(ioctl_zl380tw)))
++				return -EFAULT;
++		} else
++			return -EAGAIN;
++	break;
++	case TWOLF_BOOT_PREPARE :
++        zl380twEnterCritical();
++	    retval = zl380tw_boot_prepare(zl380tw);
++	    zl380twExitCritical();
++	break;
++	case TWOLF_BOOT_SEND_MORE_DATA: {
++		if (copy_from_user(zl380tw->pData,
++			               (char *)arg,
++			                MAX_TWOLF_ACCESS_SIZE_IN_BYTES))
++			return -EFAULT;
++		zl380twEnterCritical();
++		retval = zl380tw_boot_Write(zl380tw, zl380tw->pData);
++        zl380twExitCritical();
++	    break;
++	}
++	case TWOLF_BOOT_CONCLUDE :
++        zl380twEnterCritical();
++	    retval = zl380tw_boot_conclude(zl380tw);
++	    zl380twExitCritical();
++	break;
++
++	case TWOLF_CMD_PARAM_REG_ACCESS :
++		retval = __get_user(buf, (u16 __user *)arg);
++		if (retval ==0) {
++		    zl380twEnterCritical();
++		    retval = zl380tw_write_cmdreg(zl380tw, buf);
++		    zl380twExitCritical();
++        }
++	break;
++	case TWOLF_CMD_PARAM_RESULT_CHECK :
++        zl380twEnterCritical();
++	    retval = zl380tw_cmdresult_check(zl380tw);
++	    zl380twExitCritical();
++	break;
++	case TWOLF_RESET :
++		retval = __get_user(buf, (u16 __user *)arg);
++		if (retval ==0) {
++	       zl380twEnterCritical();
++		   retval = zl380tw_reset(zl380tw, buf);
++		   zl380twExitCritical();
++        }
++	break;
++	case TWOLF_SAVE_FWR_TO_FLASH :
++         zl380twEnterCritical();
++		 retval = zl380tw_save_image_to_flash(zl380tw);
++		 zl380twExitCritical();
++	break;
++	case TWOLF_LOAD_FWR_FROM_FLASH :
++         retval = __get_user(buf, (u16 __user *)arg);
++         if (retval ==0) {
++             zl380twEnterCritical();
++		     retval = zl380tw_load_fwr_from_flash(zl380tw, buf);
++		     zl380twExitCritical();
++         }
++	break;
++	case TWOLF_SAVE_CFG_TO_FLASH :
++         retval = __get_user(buf, (u16 __user *)arg);
++         if (retval ==0) {
++             zl380twEnterCritical();
++		     retval = zl380tw_save_cfg_to_flash(zl380tw, buf);
++		     zl380twExitCritical();
++         }
++	break;
++	case TWOLF_LOAD_CFG_FROM_FLASH :
++         retval = __get_user(buf, (u16 __user *)arg);
++         if (retval ==0) {
++             zl380twEnterCritical();
++		     retval = zl380tw_load_cfg_from_flash(zl380tw, buf);
++		     zl380twExitCritical();
++         }
++	break;
++	case TWOLF_ERASE_IMGCFG_FLASH :
++         retval = __get_user(buf, (u16 __user *)arg);
++         if (retval ==0) {
++             zl380twEnterCritical();
++		     retval = zl380tw_erase_fwrcfg_from_flash(zl380tw, buf);
++		     zl380twExitCritical();
++         }
++	break;
++	case TWOLF_LOAD_FWRCFG_FROM_FLASH :
++         retval = __get_user(buf, (u16 __user *)arg);
++         if (retval ==0) {
++             zl380twEnterCritical();
++		     retval = zl380tw_load_fwrcfg_from_flash(zl380tw, buf);
++		     zl380twExitCritical();
++         }
++	break;
++	case TWOLF_HBI_WR_ARB_SINGLE_WORD :
++        retval = __get_user(buf, (u16 __user *)arg);
++        if (retval ==0) {
++            zl380twEnterCritical();
++		    retval = zl380tw_wr16(zl380tw, buf);
++		    zl380twExitCritical();
++        }
++	break;
++	case TWOLF_HBI_RD_ARB_SINGLE_WORD :
++         zl380twEnterCritical();
++		 retval = zl380tw_rd16(zl380tw, &buf);
++		 zl380twExitCritical();
++         if (retval ==0)
++            retval = __put_user(buf, (__u16 __user *)arg);
++	break;
++	case TWOLF_HBI_INIT :
++         retval = __get_user(buf, (u16 __user *)arg);
++         if (retval ==0) {
++            zl380twEnterCritical();
++		    retval = zl380tw_hbi_init(zl380tw, buf);
++		    zl380twExitCritical();
++         }
++	break;
++	case TWOLF_ERASE_ALL_FLASH :
++         zl380twEnterCritical();
++         retval = zl380tw_reset(zl380tw, ZL38040_RST_TO_BOOT);
++         if (retval ==0)
++		     retval = zl380tw_erase_flash(zl380tw);
++		 zl380twExitCritical();
++	break;
++	case TWOLF_STOP_FWR :
++         zl380twEnterCritical();
++		 retval = zl380tw_stop_fwr_to_bootmode(zl380tw);
++		 zl380twExitCritical();
++	break;
++	case TWOLF_START_FWR :
++         zl380twEnterCritical();
++		 retval = zl380tw_start_fwr_from_ram(zl380tw);
++		 zl380twExitCritical();
++	break;
++
++	default:
++		printk(KERN_DEBUG "ioctl: Invalid Command Value");
++		retval = -EINVAL;
++	}
++	return retval;
++}
++
++
++
++/*----------------------------------------------------------------------*
++ *   The ZL38040/05x/06x/08x kernel specific aceess functions are defined below
++ *-------------------------ZL380xx FUNCTIONs-----------------------------*/
++
++/* This function is best used to simply retrieve pending data following a
++ * previously sent write command
++ * The data is returned in bytes format. Up to 256 data bytes.
++ */
++
++static ssize_t zl380tw_io_read(struct file *filp, char __user *buf, size_t count,
++                                                           loff_t *f_pos)
++{
++    /* This access uses the spi/i2c command frame format - where both
++     * the whole data is read in one active chip_select
++     */
++
++	struct zl380tw	*zl380tw = filp->private_data;
++
++	int	status = 0;
++    u16 cmd = 0;
++	if (count > twHBImaxTransferSize)
++		return -EMSGSIZE;
++
++#ifdef MICROSEMI_HBI_SPI
++	if (zl380tw->spi == NULL) {
++	    TW_DEBUG1("spi device is not available \n");
++	    return -ESHUTDOWN;
++    }
++#endif
++#ifdef MICROSEMI_HBI_I2C
++	if (zl380tw->i2c == NULL) {
++	    TW_DEBUG1("zl380tw_io_read::i2c device is not available \n");
++	    return -ESHUTDOWN;
++    }
++
++#endif
++    zl380twEnterCritical();
++	if (copy_from_user(zl380tw->pData, buf, count)) {
++       zl380twExitCritical();
++	   return -EFAULT;
++    }
++    cmd = (*(zl380tw->pData + 0) << 8) | (*(zl380tw->pData + 1));
++    /*read the data*/
++    status = zl380tw_hbi_access(zl380tw,
++                       cmd, count, zl380tw->pData, TWOLF_HBI_READ);
++	if (status < 0) {
++          zl380twExitCritical();
++          return -EFAULT;
++    }
++	if (copy_to_user(buf, zl380tw->pData, count)) {
++          zl380twExitCritical();
++		  return -EFAULT;
++    }
++    zl380twExitCritical();
++	return 0;
++}
++
++/* Write multiple bytes (up to 254) to the device
++ * the data should be formatted as follows
++ * cmd_type,
++ * cmd_byte_low,
++ * cmd_byte_hi,
++ * data0_byte_low,
++ * data0_byte_hi
++ *  ...
++ * datan_byte_low, datan_byte_hi   (n < 254)
++ */
++
++static ssize_t zl380tw_io_write(struct file *filp, const char __user *buf,
++		size_t count, loff_t *f_pos)
++{
++    /* This access use the spi/i2c command frame format - where both
++     * the command and the data to write are sent in one active chip_select
++     */
++	struct zl380tw	*zl380tw = filp->private_data;
++
++	int status = 0;
++	u16 cmd = 0;
++
++	if (count > twHBImaxTransferSize)
++		return -EMSGSIZE;
++    zl380twEnterCritical();
++	if (copy_from_user(zl380tw->pData, buf, count)) {
++        zl380twExitCritical();
++	    return -EFAULT;
++    }
++	cmd = (*(zl380tw->pData + 0) << 8) | (*(zl380tw->pData + 1));
++    TW_DEBUG2("count = %d\n",count);
++    /*remove the cmd numbytes from the count*/
++    status = zl380tw_hbi_access(zl380tw,
++                       cmd, count-2, (zl380tw->pData+2), TWOLF_HBI_WRITE);
++    if (status < 0) {
++       zl380twExitCritical();
++       return -EFAULT;
++    }
++    zl380twExitCritical();
++	return status;
++}
++
++static int zl380tw_io_open(struct inode *inode, struct file *filp)
++{
++
++    if (module_usage_count) {
++		printk(KERN_ERR "microsemi_slave_zl380xx device alrady opened\n");
++		return -EBUSY;
++	}
++
++	module_usage_count++;
++	filp->private_data = zl380tw_priv;
++
++	return 0;
++}
++
++static int zl380tw_io_close(struct inode *inode, struct file *filp)
++{
++
++	//struct zl380tw *zl380tw = filp->private_data;
++	filp->private_data = NULL;
++
++	if (module_usage_count) {
++		module_usage_count--;
++	}
++
++	return 0;
++}
++
++static const struct file_operations zl380tw_fops = {
++	.owner =	THIS_MODULE,
++	.open =		zl380tw_io_open,
++	.read =     zl380tw_io_read,
++	.write =    zl380tw_io_write,
++	.release =	zl380tw_io_close,
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
++	.ioctl =	zl380tw_io_ioctl
++#else
++	.unlocked_ioctl =	zl380tw_io_ioctl
++#endif
++};
++
++/*----------------------------------------------------------------------------*/
++
++
++
++static struct class *zl380tw_class;
++#endif /*ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER */
++ /*--------------------------------------------------------------------
++ *    CHARACTER type Host Interface driver - END
++ *--------------------------------------------------------------------*/
++
++#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
++/*IMPORTANT note: Change this controller string maching accordingly per your *.dts or *dtsi compatible definition file*/
++static struct of_device_id zl380tw_of_match[] = {
++	{ .compatible = "ambarella,zl380tw",},
++	{},
++};
++MODULE_DEVICE_TABLE(of, zl380tw_of_match);
++#endif /*SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING*/
++
++static int zl380tw_sub_probe(void)
++{
++	/* Allocate driver data */
++	zl380tw_priv = kzalloc(sizeof(*zl380tw_priv), GFP_KERNEL);
++	if (zl380tw_priv == NULL)
++		return -ENOMEM;
++
++    /* Allocating memory for the data buffer */
++    zl380tw_priv->pData  = kmalloc(twHBImaxTransferSize, GFP_KERNEL);
++    if (!zl380tw_priv->pData) {
++        printk(KERN_ERR "Error allocating %d bytes pdata memory",
++                                                 twHBImaxTransferSize);
++        kfree(zl380tw_priv);
++		return -ENOMEM;
++    }
++    memset(zl380tw_priv->pData, 0, twHBImaxTransferSize);
++    return 0;
++}
++
++static void zl380tw_sub_probe_clean(void)
++{
++        kfree(zl380tw_priv);
++	    kfree((void *)zl380tw_priv->pData);
++	    zl380tw_priv->pData = NULL;
++}
++
++
++#ifdef ZL380TW_DEV_BIND_SLAVE_TO_MASTER
++/* Bind the client driver to a master (SPI or I2C) adapter */
++
++static int zl380xx_slaveMaster_binding(void) {
++#ifdef MICROSEMI_HBI_SPI
++    struct spi_board_info spi_device_info = {
++        .modalias = "zl380tw",
++        .max_speed_hz = SPIM_CLK_SPEED,
++        .bus_num = SPIM_BUS_NUM,
++        .chip_select = SPIM_CHIP_SELECT,
++        .mode = SPIM_MODE,
++    };
++    struct spi_device *client;
++    struct spi_master *master;
++    /* create a new slave device, given the master and device info
++	 * if another device is alread assigned to that bus.cs, then this will fail
++	 */
++    /* get the master device, given SPI the bus number*/
++    master = spi_busnum_to_master( spi_device_info.bus_num );
++    if( !master )
++        return -ENODEV;
++    printk(KERN_INFO "SPI master device found at bus = %d\n", master->bus_num);
++
++    client = spi_new_device( master, &spi_device_info );
++    if( !client )
++        return -ENODEV;
++    printk(KERN_INFO "SPI slave device %s, module alias %s added at bus = %d, cs =%d\n",
++           client->dev.driver->name, client->modalias, client->master->bus_num, client->chip_select);
++#endif
++#ifdef MICROSEMI_HBI_I2C /*#ifdef MICROSEMI_HBI_I2C*/
++    struct i2c_board_info i2c_device_info = {
++    	I2C_BOARD_INFO("zl380tw", MICROSEMI_I2C_ADDR),
++    	.platform_data	= NULL,
++    };
++    struct i2c_client   *client;
++    /*create a new client for that adapter*/
++    /*get the i2c adapter*/
++    struct i2c_adapter *master = i2c_get_adapter(CONTROLLER_I2C_BUS_NUM);
++    if( !master )
++        return -ENODEV;
++    printk(KERN_INFO "found I2C master device %s \n", master->name);
++
++    client = i2c_new_device( master, &i2c_device_info);
++    if( !client)
++        return -ENODEV;
++
++    printk(KERN_INFO "I2C slave device %s, module alias %s attached to I2C master device %s\n",
++           client->dev.driver->name, client->name, master->name);
++
++    i2c_put_adapter(master);
++#endif /*MICROSEMI_HBI_SPI/I2C interface selection macro*/
++
++    return 0;
++
++}
++
++static int zl380tw_slaveMaster_unbind(void)
++{
++#ifdef MICROSEMI_HBI_SPI
++        spi_unregister_device(zl380tw_priv->spi);
++#endif
++#ifdef MICROSEMI_HBI_I2C /*#ifdef MICROSEMI_HBI_I2C*/
++        i2c_unregister_device(zl380tw_priv->i2c);
++#endif
++
++	return 0;
++}
++
++#endif //ZL380TW_DEV_BIND_SLAVE_TO_MASTER
++/*--------------------------------------------------------------------
++* SPI driver registration
++*--------------------------------------------------------------------*/
++
++#ifdef MICROSEMI_HBI_SPI
++static int zl380tw_spi_probe(struct spi_device *spi)
++{
++
++	int err, ret;
++	enum of_gpio_flags flags;
++
++	err = zl380tw_sub_probe();
++	if (err < 0) {
++		return err;
++	}
++	dev_dbg(&spi->dev, "probing zl380tw spi device\n");
++
++	spi->master->bus_num = 1;//SPIM_BUS_NUM;
++	spi->mode = SPI_MODE_0;
++	spi->max_speed_hz = SPIM_CLK_SPEED;
++	spi->chip_select = SPIM_CHIP_SELECT;
++	spi->bits_per_word = 8;
++
++	err = spi_setup(spi);
++	if (err < 0) {
++        zl380tw_sub_probe_clean();
++		return err;
++	}
++
++	/* Initialize the driver data */
++	spi_set_drvdata(spi, zl380tw_priv);
++	zl380tw_priv->spi = spi;
++
++	zl380tw_priv->pwr_pin = of_get_named_gpio_flags(spi->dev.of_node, "zl380,pwr-gpio", 0, &flags);
++	zl380tw_priv->pwr_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	if(zl380tw_priv->pwr_pin < 0 || !gpio_is_valid(zl380tw_priv->pwr_pin)) {
++		printk(KERN_ERR "zl380 power pin is invalid\n");
++		zl380tw_priv->pwr_pin = -1;
++		return -1;
++	}
++
++	if(gpio_is_valid(zl380tw_priv->pwr_pin)) {
++		ret = devm_gpio_request(&spi->dev, zl380tw_priv->pwr_pin, "zl380xx pwr");
++		if(ret < 0) {
++			dev_err(&spi->dev, "Failed to request pwr pin for zl380xx: %d\n", ret);
++			return ret;
++		}
++		gpio_direction_output(zl380tw_priv->pwr_pin, zl380tw_priv->pwr_active);
++	}
++
++	zl380tw_priv->rst_pin = of_get_named_gpio_flags(spi->dev.of_node, "zl380,rst-gpio", 0, &flags);
++	zl380tw_priv->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
++
++	if(zl380tw_priv->rst_pin < 0 || !gpio_is_valid(zl380tw_priv->rst_pin)) {
++		printk(KERN_ERR "zl380 power pin is invalid\n");
++		zl380tw_priv->rst_pin = -1;
++		return -1;
++	}
++
++	if(gpio_is_valid(zl380tw_priv->rst_pin)) {
++		ret = devm_gpio_request(&spi->dev, zl380tw_priv->rst_pin, "zl380xx reset");
++		if(ret < 0) {
++			dev_err(&spi->dev, "Failed to request reset pin for zl380xx: %d\n", ret);
++			return ret;
++		}
++		gpio_direction_output(zl380tw_priv->rst_pin, zl380tw_priv->rst_active);
++		msleep(10);
++		gpio_direction_output(zl380tw_priv->rst_pin, !zl380tw_priv->rst_active);
++	}
++
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++    {
++        u16 buf = 0;
++
++        zl380tw_priv->flag = 0;
++
++        zl380tw_hbi_rd16(zl380tw_priv, ZL38040_DEVICE_ID_REG, &buf);
++        if((buf > 38000)  && (buf < 38090)) {
++              zl380tw_priv->init_done =1;
++              printk("SPI slave device %d found at bus::cs = %d::%d\n", buf, spi->master->bus_num, spi->chip_select);
++
++        } else {
++			zl380tw_priv->init_done =0;
++        }
++    }
++
++	err = snd_soc_register_codec(&spi->dev, &soc_codec_dev_zl380tw, &zl380tw_dai, 1);
++	if(err < 0) {
++		zl380tw_sub_probe_clean();
++		dev_dbg(&spi->dev, "zl380tw spi device not created!!!\n");
++		return err;
++	}
++#endif
++
++#ifdef ZL380XX_TW_UPDATE_FIRMWARE
++    if (zl380tw_ldfwr(zl380tw_priv) < 0) {
++        dev_dbg(&spi->dev, "error loading the firmware into the codec\n");
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++        snd_soc_unregister_codec(&spi->dev);
++#endif
++        zl380tw_sub_probe_clean();
++        return -ENODEV;
++    }
++#endif
++    dev_dbg(&spi->dev, "zl380tw codec device created...\n");
++
++	return 0;
++}
++
++static int  zl380tw_spi_remove(struct spi_device *spi)
++{
++
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++	snd_soc_unregister_codec(&spi->dev);
++#endif
++	kfree(spi_get_drvdata(spi));
++	if (!module_usage_count) {
++
++	   kfree((void *)zl380tw_priv->pData);
++	   zl380tw_priv->pData = NULL;
++    }
++	return 0;
++}
++
++static struct spi_driver zl380tw_spi_driver = {
++	.driver = {
++		.name = "zl380tw",
++		.owner = THIS_MODULE,
++#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
++        .of_match_table = zl380tw_of_match,
++#endif
++	},
++	.probe = zl380tw_spi_probe,
++	.remove = zl380tw_spi_remove,
++};
++#endif
++
++#ifdef MICROSEMI_HBI_I2C
++
++static int zl380tw_i2c_probe(struct i2c_client *i2c,
++			    const struct i2c_device_id *id)
++{
++    int err = zl380tw_sub_probe();
++	if (err < 0) {
++		return err;
++    }
++
++	dev_dbg(&i2c->dev, "probing zl380tw I2C device\n");
++    //i2c->addr = MICROSEMI_I2C_ADDR;
++
++	i2c_set_clientdata(i2c, zl380tw_priv);
++	zl380tw_priv->i2c = i2c;
++	printk(KERN_ERR "i2c slave device address = 0x%04x\n", i2c->addr);
++
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++    {
++        u16 buf = 0;
++
++        zl380tw_priv->flag = 0;
++
++        zl380tw_hbi_rd16(zl380tw_priv, ZL38040_DEVICE_ID_REG, &buf);
++        if((buf > 38000)  && (buf < 38090)) {
++              zl380tw_priv->init_done =1;
++              printk(KERN_ERR "I2C slave device %d found at address = 0x%04x\n", buf, i2c->addr);
++
++        } else {
++              zl380tw_priv->init_done =0;
++        }
++    }
++
++	err = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_zl380tw, &zl380tw_dai, 1);
++	if(err < 0) {
++		zl380tw_sub_probe_clean();
++		dev_dbg(&i2c->dev, "zl380tw I2c device not created!!!\n");
++		return err;
++	}
++#endif
++
++#ifdef ZL380XX_TW_UPDATE_FIRMWARE
++    if (zl380tw_ldfwr(zl380tw_priv) < 0) {
++        dev_dbg(&i2c->dev, "error loading the firmware into the codec\n");
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++        snd_soc_unregister_codec(&i2c->dev);
++#endif
++        zl380tw_sub_probe_clean();
++        return -ENODEV;
++    }
++#endif
++    dev_dbg(&i2c->dev, "zl380tw I2C codec device created...\n");
++	return err;
++}
++
++static int zl380tw_i2c_remove(struct i2c_client *i2c)
++{
++
++#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
++	snd_soc_unregister_codec(&i2c->dev);
++#endif
++	kfree(i2c_get_clientdata(i2c));
++	if (!module_usage_count) {
++
++	   kfree((void *)zl380tw_priv->pData);
++	   zl380tw_priv->pData = NULL;
++    }
++	return 0;
++}
++
++static struct i2c_device_id zl380tw_id_table[] = {
++    {"zl380tw", 0 },
++    {}
++ };
++
++static struct i2c_driver zl380tw_i2c_driver = {
++	.driver = {
++		.name	= "zl380tw",
++		.owner = THIS_MODULE,
++#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
++        .of_match_table = zl380tw_of_match,
++#endif
++	},
++	.probe = zl380tw_i2c_probe,
++	.remove = zl380tw_i2c_remove,
++	.id_table = zl380tw_id_table,
++};
++
++#endif
++
++
++static int __init zl380tw_init(void)
++{
++    int status;
++
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++	struct device *dev;
++	status = alloc_chrdev_region(&t_dev, FIRST_MINOR, NUMBER_OF_ZL380xx_DEVICES,
++                                                 "zl380tw");
++	if (status < 0) {
++		printk(KERN_ERR "Failed to register character device");
++        return status;
++    }
++
++    /*create the device class*/
++	zl380tw_class = class_create(THIS_MODULE, "zl380tw");
++	if (zl380tw_class == NULL) {
++        printk(KERN_ERR "Error %d creating class zl380tw", status);
++		unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
++		return -1;
++	}
++
++	/* registration of character device */
++	dev = device_create(zl380tw_class, NULL,
++                    t_dev, NULL, "zl380tw");
++	if (IS_ERR(dev)) {
++        printk(KERN_ERR "Error %d creating device zl380tw", status);
++        class_destroy(zl380tw_class);
++		unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
++    }
++    status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
++    if (status  == 0) {
++    	/* Initialize of character device */
++    	cdev_init(&c_dev, &zl380tw_fops);
++    	/* addding character device */
++    	status = cdev_add(&c_dev, t_dev, NUMBER_OF_ZL380xx_DEVICES);
++    	if (status < 0) {
++    		printk(KERN_ERR "Error %d adding zl380tw", status);
++            class_destroy(zl380tw_class);
++            device_destroy(zl380tw_class, t_dev);
++            cdev_del(&c_dev);
++    		unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
++    		return -1;
++    	}
++    }
++#endif
++#ifdef MICROSEMI_HBI_SPI
++	status = spi_register_driver(&zl380tw_spi_driver);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++    status = i2c_add_driver(&zl380tw_i2c_driver);
++#endif
++    if (status < 0) {
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++        class_destroy(zl380tw_class);
++        cdev_del(&c_dev);
++        unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
++#endif
++    }
++#ifdef ZL380TW_DEV_BIND_SLAVE_TO_MASTER
++    status =  zl380xx_slaveMaster_binding();
++    if (status < 0) {
++        printk(KERN_ERR "error =%d\n", status);
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++        class_destroy(zl380tw_class);
++        device_destroy(zl380tw_class, t_dev);
++        cdev_del(&c_dev);
++		unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
++#endif
++#ifdef MICROSEMI_HBI_SPI
++	    spi_unregister_driver(&zl380tw_spi_driver);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++	    i2c_del_driver(&zl380tw_i2c_driver);
++#endif
++        return -1;
++	}
++    status =0;
++#endif
++    return status;
++}
++module_init(zl380tw_init);
++
++static void __exit zl380tw_exit(void)
++{
++#ifdef ZL380TW_DEV_BIND_SLAVE_TO_MASTER
++    zl380tw_slaveMaster_unbind();
++#endif
++#ifdef MICROSEMI_HBI_SPI
++	spi_unregister_driver(&zl380tw_spi_driver);
++#endif
++#ifdef MICROSEMI_HBI_I2C
++	i2c_del_driver(&zl380tw_i2c_driver);
++#endif
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++    device_destroy(zl380tw_class, t_dev);
++	class_destroy(zl380tw_class);
++	cdev_del(&c_dev);
++	unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
++#endif
++}
++module_exit(zl380tw_exit);
++
++MODULE_AUTHOR("Jean Bony <jean.bony@microsemi.com>");
++MODULE_DESCRIPTION(" Microsemi Timberwolf i2c/spi/char/alsa codec driver");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/zl380tw.h b/sound/soc/codecs/zl380tw.h
+new file mode 100644
+index 00000000..44aa7416
+--- /dev/null
++++ b/sound/soc/codecs/zl380tw.h
+@@ -0,0 +1,334 @@
++#ifndef __ZL380TW_H
++#define __ZL380TW_H
++
++#undef MICROSEMI_DEMO_PLATFORM /*leave this macro undefined unless requested by Microsemi*/
++/*-------------------------------------------------------------*
++ *    HOST MACROS - Define/undefine as desired
++ *    -----------------------------------------
++ *    Supported combinations:
++ *    ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER + ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER  + MICROSEMI_HBI_I2C or MICROSEMI_HBI_SPI
++ *    ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER + MICROSEMI_HBI_I2C or MICROSEMI_HBI_SPI
++ *    ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER  + MICROSEMI_HBI_I2C or MICROSEMI_HBI_SPI
++ *
++ *    all of the above can be used with the ZL380XX_TW_UPDATE_FIRMWARE
++ *-------------------------------------------------------------*/
++#define ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER /*Define this macro to create a /sound/soc ALSA codec device driver*/
++#define ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER   /*Define this macro to create a character device driver*/
++
++/*Enable either one of this macro to create a SPI or an I2C device driver
++*  to be used as the low-level transport for the ALSA and/or CHAR device read/write accesses
++*/
++#undef MICROSEMI_HBI_I2C          /*Enable this macro if the HBI interface between the host CPU and the Twolf is I2C*/
++#ifdef MICROSEMI_HBI_I2C
++    #undef MICROSEMI_HBI_SPI
++    #define MICROSEMI_I2C_ADDR 0x45  /*if DIN pin is tied to ground, else if DIN is tied to 3.3V address must be 0x52*/
++    #define CONTROLLER_I2C_BUS_NUM 0
++#else
++    #define MICROSEMI_HBI_SPI
++    /*Define the SPI master signal config*/
++    #define SPIM_CLK_SPEED  15000000
++    #define SPIM_CHIP_SELECT 0
++    #define SPIM_MODE SPI_MODE_0
++    #define SPIM_BUS_NUM 0
++#endif
++
++//#undef ZL380XX_TW_UPDATE_FIRMWARE /*define if you want to update current firmware with a new one at power up*/
++//#undef ZL380XX_TW_UPDATE_FIRMWARE
++#define ZL380XX_TW_UPDATE_FIRMWARE
++
++#ifdef ZL380XX_TW_UPDATE_FIRMWARE
++//#define ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
++/*NOTE: Rename the *s3 firmware file as per below or simply change the file name below as per the firmware file name
++*       If there is more than 1 device create new path name and pass them to the firmware loading function accordingly
++*/
++    #define  ZLS380TW0_TWOLF "ZLS38062.0_E1.1.0_App.s3" /*firmware for your zl380xx device 0*/
++
++#define ZL380XX_TW_UPDATE_CONFIG
++#ifdef ZL380XX_TW_UPDATE_CONFIG
++    #define  ZLS380TW0_TWOLF_CRK "ZLS38062_20151223_AMBA.CR2" /*configuration record for your zl380xx device 0*/
++#endif
++#endif /*ZL380XX_TW_UPDATE_FIRMWARE*/
++
++#undef ZL38040_SAVE_FWR_TO_FLASH  /*define if a slave flash is connected to the zl380tw and you want to save the loaded firmware/config to flash*/
++
++
++
++/*HBI access to the T-wolf must not be interrupted by another process*/
++#define PROTECT_CRITICAL_SECTION  /*define this macro to protect HBI critical section*/
++
++/*The zl380tw device registration can be done using the Linux device OF matching scheme or
++* or by using the old method via the board init file
++* This driver includes the method to auto-detect the SPI or I2C master and register itself to that
++* master as per the defined bus info above
++*/
++#define SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING  /*define this if you are using the linux device tree (*dts, *dtb, etc.. of maching lib*/
++#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
++#define CONTROLLER_DTS_STRING  "ambarella" /*Change the string name accordingly to your device tree controller/driver maching name*/
++#else
++/*define this macro if the board_info registration is not already done in your board init file
++* This macro will cause a new slave device (SPI or I2C) to be created and attached to the master
++* device controller
++* If you already assigned the ressource for this zl380tw driver in your board init file, then undef this macro.
++*/
++#define ZL380TW_DEV_BIND_SLAVE_TO_MASTER
++#endif
++
++
++/*Define the ZL380TW interrupt pin drive mode 1:TTL, 0: Open Drain(default)*/
++#define HBI_CONFIG_INT_PIN_DRIVE_MODE		0
++/*-------------------------------------------------------------*
++ *     HOST MACROS - end
++ *-------------------------------------------------------------*/
++
++
++/* local defines */
++#define MAX_TWOLF_ACCESS_SIZE_IN_BYTES 264 /*127 16-bit words*/
++#define MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES 128 /*128 8-bit words*/
++
++/*The timberwolf device reset modes*/
++#define ZL38040_RST_HARDWARE_RAM 0
++#define ZL38040_RST_HARDWARE_ROM 1
++#define ZL38040_RST_SOFTWARE     2
++#define ZL38040_RST_AEC          3
++#define ZL38040_RST_TO_BOOT      4
++
++#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
++
++#define NUMBER_OF_ZL380xx_DEVICES 1
++#define FIRST_MINOR 0
++/*structure for IOCL access*/
++typedef struct {
++	__u16	addr;
++	__u16	data;
++} ioctl_zl380tw;
++
++
++/* ioctl() calls that are permitted to the /dev/microsemi_spis_tw interface. */
++#define TWOLF_MAGIC 'q'            /*Change this accordingly to your system*/
++#define TWOLF_HBI_RD16		        _IOWR(TWOLF_MAGIC, 1,  ioctl_zl380tw *)
++#define TWOLF_HBI_WR16		        _IOW(TWOLF_MAGIC, 2, ioctl_zl380tw *)
++#define TWOLF_HBI_INIT		        _IOW(TWOLF_MAGIC, 3, __u16)
++#define TWOLF_RESET        	        _IOW(TWOLF_MAGIC, 4,  __u16)
++#define TWOLF_SAVE_FWR_TO_FLASH     _IO(TWOLF_MAGIC, 5)
++#define TWOLF_LOAD_FWR_FROM_FLASH   _IOW(TWOLF_MAGIC, 6,  __u16)
++#define TWOLF_SAVE_CFG_TO_FLASH     _IOW(TWOLF_MAGIC, 7,  __u16)
++#define TWOLF_LOAD_CFG_FROM_FLASH   _IOW(TWOLF_MAGIC, 8,  __u16)
++#define TWOLF_ERASE_IMGCFG_FLASH    _IOW(TWOLF_MAGIC, 9,  __u16)
++#define TWOLF_ERASE_ALL_FLASH       _IO(TWOLF_MAGIC, 10)
++#define TWOLF_STOP_FWR              _IO(TWOLF_MAGIC, 11)
++#define TWOLF_START_FWR             _IO(TWOLF_MAGIC, 12)
++#define TWOLF_LOAD_FWRCFG_FROM_FLASH    _IOW(TWOLF_MAGIC, 13,  __u16)
++#define TWOLF_HBI_WR_ARB_SINGLE_WORD    _IOW(TWOLF_MAGIC, 14, __u16)
++#define TWOLF_HBI_RD_ARB_SINGLE_WORD    _IOW(TWOLF_MAGIC, 15, __u16)
++#define TWOLF_CMD_PARAM_REG_ACCESS	    _IOW(TWOLF_MAGIC, 16, __u16)
++#define TWOLF_CMD_PARAM_RESULT_CHECK    _IO(TWOLF_MAGIC, 17)
++#define TWOLF_BOOT_PREPARE              _IO(TWOLF_MAGIC, 18)
++#define TWOLF_BOOT_SEND_MORE_DATA       _IOW(TWOLF_MAGIC, 19, int)
++#define TWOLF_BOOT_CONCLUDE             _IO(TWOLF_MAGIC, 20)
++#define TWOLF_LOAD_CFG		            _IOW(TWOLF_MAGIC, 21,  int)
++#endif
++/*------------------------------------------------------*/
++/*TWOLF REGisters*/
++#define ZL38040_CMD_REG             0x0032   /*Host Command register*/
++#define ZL38040_CMD_IDLE            0x0000  /*idle/ operation complete*/
++#define ZL38040_CMD_NO_OP           0x0001  /*no-op*/
++#define ZL38040_CMD_IMG_CFG_LOAD    0x0002  /*load firmware and CR from flash*/
++#define ZL38040_CMD_IMG_LOAD        0x0003  /*load firmware only from flash*/
++#define ZL38040_CMD_IMG_CFG_SAVE    0x0004  /*save a firmware and CR to flash*/
++#define ZL38040_CMD_IMG_CFG_ERASE   0x0005  /*erase a firmware and CR in flash*/
++#define ZL38040_CMD_CFG_LOAD        0x0006  /*Load CR from flash*/
++#define ZL38040_CMD_CFG_SAVE        0x0007  /*save CR to flash*/
++#define ZL38040_CMD_FWR_GO          0x0008  /*start/restart firmware (GO)*/
++#define ZL38040_CMD_HOST_LOAD_CMP   0x000D  /*Host Application Load Complete*/
++#define ZL38040_CMD_HOST_FLASH_INIT 0x000B  /*Host Application flash discovery*/
++#define ZL38040_CMD_FWR_STOP        0x8000  /*stop firmware */
++#define ZL38040_CMD_CMD_IN_PROGRESS 0xFFFF  /*wait command is in progress */
++#define ZL38040_CMD_APP_SLEEP		 0x8005  /*codec low power mode*/
++
++#define PAGE_255_CHKSUM_LO_REG  0x000A
++#define PAGE_255_CHKSUM_HI_REG  0x0008
++#define CLK_STATUS_REG          0x0014   /*Clock status register*/
++#define PAGE_255_BASE_LO_REG  0x000E
++#define PAGE_255_BASE_HI_REG  0x000C
++#define ZL38040_SW_FLAGS_REG     0x0006
++#define ZL38040_SW_FLAGS_CMD     0x0001
++#define ZL38040_SW_FLAGS_CMD_NORST     0x0004
++
++#define ZL38040_DEVICE_ID_REG  0x0022
++
++#define TWOLF_CLK_STATUS_HBI_BOOT       0x0001
++
++#define HBI_CONFIG_REG			0xFD00
++#define HBI_CONFIG_WAKE			1<<7
++#define HBI_CONFIG_VAL (HBI_CONFIG_INT_PIN_DRIVE_MODE<<1)
++
++#define ZL38040_CMD_PARAM_RESULT_REG   0x0034 /*Host Command Param/Result register*/
++#define ZL38040_FWR_COUNT_REG   0x0026 /*Fwr on flash count register*/
++#define ZL38040_FWR_EXEC_REG   0x012C  /*Fwr EXEC register*/
++
++#define TOTAL_FWR_DATA_WORD_PER_LINE 24
++#define TOTAL_FWR_DATA_BYTE_PER_LINE 128
++#define TWOLF_STATUS_NEED_MORE_DATA 22
++#define TWOLF_STATUS_BOOT_COMPLETE 23
++
++#define TWOLF_MBCMDREG_SPINWAIT  10000
++/*--------------------------------------------------------------------
++ *    ALSA
++ *--------------------------------------------------------------------*/
++ /*Macros to enable one of the pre-defined audio cross-points*/
++#define ZL38040_CR2_DEFAULT 0
++#define ZL38040_CR2_STEREO_BYPASS      1
++#define ZL38040_ADDA_LOOPBACK      2
++
++/*Cached register range*/
++#define ZL38040_CACHED_ADDR_LO  0x202
++#define ZL38040_CACHED_ADDR_HI  0x23E
++#define ZL38040_HBI_OFFSET_RANGE 128
++#define ZL38040_CACHE_INDEX_TO_ADDR(index) (ZL38040_CACHED_ADDR_LO+(2*index))
++#define ZL38040_ADDR_TO_CACHE_INDEX(addr) ((addr - ZL38040_CACHED_ADDR_LO)/2)
++
++
++/*Page 1 registers*/
++#define ZL38040_OUTPUT_PATH_EN_REG 	0x202
++#define ZL38040_DAC1_EN  	(1 << 0)
++#define ZL38040_DAC2_EN  	(1 << 1)
++#define ZL38040_TDMA1_EN 	(1 << 2)
++#define ZL38040_TDMA2_EN 	(1 << 3)
++#define ZL38040_TDMA3_EN 	(1 << 4)
++#define ZL38040_TDMA4_EN 	(1 << 5)
++#define ZL38040_TDMB1_EN 	(1 << 6)
++#define ZL38040_TDMB2_EN 	(1 << 7)
++#define ZL38040_TDMB3_EN 	(1 << 8)
++#define ZL38040_TDMB4_EN 	(1 << 9)
++#define ZL38040_MIC_SIN_EN 	(1 << 10)
++#define ZL38040_TDM_SOUT_EN (1 << 11)
++/*Cross-point Audio config registers*/
++#define ZL38040_DAC1_IN_PATH_REG 	0x210
++#define ZL38040_DAC2_IN_PATH_REG 	0x212
++#define ZL38040_TDM1L_IN_PATH_REG 	0x214
++#define ZL38040_TDM1R_IN_PATH_REG 	0x216
++#define ZL38040_TDMA3_IN_PATH_REG 	0x218
++#define ZL38040_TDMA4_IN_PATH_REG 	0x21A
++#define ZL38040_TDM2L_IN_PATH_REG 	0x21C
++#define ZL38040_TDM2R_IN_PATH_REG 	0x21E
++#define ZL38040_TDMB3_IN_PATH_REG 	0x220
++#define ZL38040_TDMB4_IN_PATH_REG 	0x222
++#define ZL38040_SIN_IN_PATH_REG 	0x224
++#define ZL38040_RIN_IN_PATH_REG 	0x226
++/*Cross-point Audio config values*/
++#define ZL38040_MIC1_PATH 	0x01
++#define ZL38040_MIC2_PATH 	0x02
++#define ZL38040_MIC3_PATH 	0x03
++#define ZL38040_MIC4_PATH 	0x04
++#define ZL38040_MIC_SELECT  ZL38040_MIC1_PATH  /*Change this accordingly*/
++#define ZL38040_TDMA1L_PATH 0x05
++#define ZL38040_TDMA1R_PATH 0x06
++#define ZL38040_TDMA3_PATH 	0x07
++#define ZL38040_TDMA4_PATH 	0x08
++#define ZL38040_TDMB2L_PATH 0x09
++#define ZL38040_TDMB2R_PATH 0x0A
++#define ZL38040_TDMB3_PATH 	0x0B
++#define ZL38040_TDMB4_PATH 	0x0C
++#define ZL38040_ROUT_PATH 	0x0D
++#define ZL38040_SOUT_PATH 	0x0E
++#define ZL38040_TGEN1_PATH 	0x0F
++#define ZL38040_TGEN2_PATH 	0x10
++
++#define ZL38040_TDMA_CFG_REG 		0x260
++#define ZL38040_TDM_I2S_CFG_VAL 0x8000
++#define ZL38040_TDM_PCM_CFG_VAL 0x0000
++#define ZL38040_TDM_CLK_POL_VAL 0x0004
++#define ZL38040_TDMA_FSALIGN 0x01     /*left justified*/
++#define ZL38040_TDMA_CLK_CFG_REG    	0x262
++#define ZL38040_TDM_TDM_MASTER_VAL (1<<15)
++#define ZL38040_TDMA_CH1_CFG_REG    	0x268
++#define ZL38040_TDMA_CH2_CFG_REG    	0x26A
++/*TDM -  Channel configuration*/
++#define ZL38040_TDMA_16BIT_LIN (1<<8)
++#define ZL38040_TDMA_8BIT_ALAW (2<<8)
++#define ZL38040_TDMA_8BIT_ULAW (3<<8)
++#define ZL38040_TDMA_8BIT_G722 (4<<8)
++#define ZL38040_TDMA_16BIT_LINHFS (6<<8)
++
++#define ZL38040_TDMA_FSRATE_8KHZ (1)
++#define ZL38040_TDMA_FSRATE_16KHZ (2)
++#define ZL38040_TDMA_FSRATE_24KHZ (3)
++#define ZL38040_TDMA_FSRATE_44_1KHZ (5)
++#define ZL38040_TDMA_FSRATE_48KHZ (6)
++
++#define ZL38040_MIC_EN_REG 			0x2B0
++#define ZL38040_MIC1_EN		0x01
++#define ZL38040_MIC2_EN		0x02
++#define ZL38040_MIC3_EN		0x04
++#define ZL38040_MIC4_EN		0x08
++
++#define ZL38040_LOW_POWER_REG  0x0206
++
++#define ZL38040_DAC1_EN_REG  0x02A0
++#define ZL38040_DAC2_EN_REG  0x02A2
++#define ZL38040_DACx_P_EN  (1<<15)
++#define ZL38040_DACx_M_EN  (1<<14)
++
++
++
++
++/*Page 2 registers*/
++#define ZL38040_USRGAIN		  0x30A
++#define ZL38040_SYSGAIN		  0x30C
++#define ZL38040_MICGAIN		  0x2B2 /*Range 0-7 step +/-1 = 6dB each*/
++
++#define ZL38040_DAC_CTRL_REG  0x030A   /*ROUT GAIN control*/
++#define ZL38040_DAC_VOL_MAX   0x78     /*Max volume control for Speaker +21dB*/
++#define ZL38040_DAC_VOL_MAX_EXT   0x82     /*Max volume control for Speaker +29dB*/
++#define ZL38040_DAC_VOL_MIN   0x00     /*Min volume control for Speaker -24dB*/
++#define ZL38040_DAC_VOL_STEP  0x01     /*volume step control for Speaker -/+0.375dB*/
++
++#define ZL38040_MIC_VOL_CTRL_REG  0x030C    /*SIN GAIN control*/
++#define ZL38040_MIC_VOL_MAX   0x1F     /*Max volume control for Speaker +22.5dB*/
++#define ZL38040_MIC_VOL_MIN   0x00     /*Min volume control for Speaker -24dB*/
++#define ZL38040_MIC_VOL_STEP  0x01     /*volume step control for Speaker -/+1.5dB*/
++#define ZL38040_SOUT_VOL_CTRL_REG  0x030C    /*SOUT DIGITAL GAIN control*/
++#define ZL38040_SOUT_VOL_MAX   0x0F     /*Max volume control for Speaker +21dB*/
++#define ZL38040_SOUT_VOL_MIN   0x00     /*Min volume control for Speaker -24dB*/
++#define ZL38040_SOUT_VOL_STEP  0x01     /*volume step control for Speaker -/+3.0dB*/
++
++#define ZL38040_DAC1_GAIN_REG  0x0238
++#define ZL38040_DAC2_GAIN_REG  0x023A
++#define ZL38040_I2S1L_GAIN_REG  0x023C
++#define ZL38040_I2S1R_GAIN_REG  0x023E
++#define ZL38040_I2S2L_GAIN_REG  0x0244
++#define ZL38040_I2S2R_GAIN_REG  0x0246
++#define ZL38040_TDMA3_GAIN_REG  0x0240
++#define ZL38040_TDMA4_GAIN_REG  0x0242
++#define ZL38040_TDMB3_GAIN_REG  0x0248
++#define ZL38040_TDMB4_GAIN_REG  0x024A
++
++
++
++#define ZL38040_AEC_CTRL_REG1  0x0302
++#define ZL38040_AEC_CTRL_REG0  0x0300
++#define ZL38040_EAC_RST_EN  (1 << 0)
++#define ZL38040_MASTER_BYPASS_EN  (1 << 1)
++#define ZL38040_EQ_RCV_DIS_EN  (1 << 2)
++#define ZL38040_AEC_BYPASS_EN  (1 << 4)
++#define ZL38040_AUD_ENH_BYPASS_EN  (1 << 5)
++#define ZL38040_SPKR_LIN_EN  (1 << 6)
++#define ZL38040_MUTE_ROUT_EN  (1 << 7)
++#define ZL38040_MUTE_SOUT_EN  (1 << 8)
++#define ZL38040_MUTE_ALL_EN   (ZL38040_MUTE_ROUT_EN | ZL38040_MUTE_SOUT_EN)
++#define ZL38040_RIN_HPF_DIS_EN  (1 << 9)
++#define ZL38040_SIN_HPF_DIS_EN  (1 << 10)
++#define ZL38040_HOWLING_DIS_EN  (1 << 11)
++#define ZL38040_AGC_DIS_EN  (1 << 12)
++#define ZL38040_NB_DIS_EN  (1 << 13)
++#define ZL38040_SATT_DIS_EN  (1 << 14)
++#define ZL38040_HOWLING_MB_DIS_EN  (1 << 15)
++#define ZL38040_HPF_DIS (ZL38040_RIN_HPF_DIS_EN | ZL38040_SIN_HPF_DIS_EN)
++
++#define ZL38040_LEC_CTRL_REG  0x037A
++
++#define ZL38040_AEC_HPF_NULL_REG  0x0310
++
++
++#endif /* __MICROSEMI_SPIS_TW_H */
++
+diff --git a/sound/soc/codecs/zl380tw_config.c b/sound/soc/codecs/zl380tw_config.c
+new file mode 100644
+index 00000000..e1e070b3
+--- /dev/null
++++ b/sound/soc/codecs/zl380tw_config.c
+@@ -0,0 +1,1032 @@
++/*Source file ZLS38051_defaults.cr2, modified: Thu Oct 08 12:11:44 2015
++ */ 
++#include "zl380tw_config.h"
++
++const dataArr st_twConfig[] ={
++	{0x0200, {0x0000}},
++	{0x0202, {0x1C0F}},
++	{0x0204, {0x0010}},
++	{0x0206, {0x0016}},
++	{0x0208, {0x0001}},
++	{0x020A, {0x0000}},
++	{0x020C, {0x0000}},
++	{0x020E, {0x0000}},
++	{0x0210, {0x000D}},
++	{0x0212, {0x000E}},
++	{0x0214, {0x000E}},
++	{0x0216, {0x0000}},
++	{0x0218, {0x0000}},
++	{0x021A, {0x0000}},
++	{0x021C, {0x0000}},
++	{0x021E, {0x0000}},
++	{0x0220, {0x0000}},
++	{0x0222, {0x0000}},
++	{0x0224, {0x0002}},
++	{0x0226, {0x0005}},
++	{0x0228, {0x0004}},
++	{0x022A, {0x0000}},
++	{0x022C, {0x0000}},
++	{0x022E, {0x0000}},
++	{0x0230, {0x0000}},
++	{0x0232, {0x0000}},
++	{0x0234, {0x0000}},
++	{0x0236, {0x0000}},
++	{0x0238, {0x0000}},
++	{0x023A, {0x0000}},
++	{0x023C, {0x0000}},
++	{0x023E, {0x0000}},
++	{0x0240, {0x0000}},
++	{0x0242, {0x0000}},
++	{0x0244, {0x0000}},
++	{0x0246, {0x0000}},
++	{0x0248, {0x0000}},
++	{0x024A, {0x0000}},
++	{0x024C, {0x0000}},
++	{0x024E, {0x0000}},
++	{0x0250, {0x0000}},
++	{0x0252, {0x0000}},
++	{0x0254, {0x0000}},
++	{0x0256, {0x0000}},
++	{0x0258, {0x0000}},
++	{0x025A, {0x0000}},
++	{0x025C, {0x0000}},
++	{0x025E, {0x0000}},
++	{0x0260, {0x8004}},
++	{0x0262, {0x01F2}},
++	{0x0264, {0xC0C0}},
++	{0x0266, {0x0000}},
++	{0x0268, {0x0100}},
++	{0x026A, {0x0101}},
++	{0x026C, {0x0004}},
++	{0x026E, {0x0006}},
++	{0x0270, {0x0000}},
++	{0x0272, {0x0000}},
++	{0x0274, {0x0000}},
++	{0x0276, {0x0000}},
++	{0x0278, {0x0000}},
++	{0x027A, {0x0000}},
++	{0x027C, {0x4040}},
++	{0x027E, {0x0000}},
++	{0x0280, {0x0000}},
++	{0x0282, {0x0002}},
++	{0x0284, {0x0004}},
++	{0x0286, {0x0006}},
++	{0x0288, {0x0000}},
++	{0x028A, {0x0000}},
++	{0x028C, {0x0000}},
++	{0x028E, {0x0000}},
++	{0x0290, {0x0000}},
++	{0x0292, {0x0000}},
++	{0x0294, {0x0000}},
++	{0x0296, {0x0000}},
++	{0x0298, {0x0000}},
++	{0x029A, {0x0000}},
++	{0x029C, {0x0000}},
++	{0x029E, {0x0000}},
++	{0x02A0, {0xC000}},
++	{0x02A2, {0xC000}},
++	{0x02A4, {0x0000}},
++	{0x02A6, {0x0000}},
++	{0x02A8, {0x0000}},
++	{0x02AA, {0x0000}},
++	{0x02AC, {0x0000}},
++	{0x02AE, {0x0000}},
++	{0x02B0, {0x000E}},
++	{0x02B2, {0x0004}},
++	{0x02B4, {0x000C}},
++	{0x02B6, {0x0000}},
++	{0x02B8, {0x815E}},
++	{0x02BA, {0xFFF1}},
++	{0x02BC, {0x81E0}},
++	{0x02BE, {0xFFF1}},
++	{0x02C0, {0x03EC}},
++	{0x02C2, {0xFFF6}},
++	{0x02C4, {0x0000}},
++	{0x02C6, {0x0000}},
++	{0x02C8, {0x0000}},
++	{0x02CA, {0x0000}},
++	{0x02CC, {0x0000}},
++	{0x02CE, {0x0000}},
++	{0x02D0, {0x0000}},
++	{0x02D2, {0x0000}},
++	{0x02D4, {0x0000}},
++	{0x02D6, {0x0000}},
++	{0x02D8, {0x0000}},
++	{0x02DA, {0x0000}},
++	{0x02DC, {0x0000}},
++	{0x02DE, {0x0000}},
++	{0x02E0, {0x0000}},
++	{0x02E2, {0x0000}},
++	{0x02E4, {0x0000}},
++	{0x02E6, {0x0000}},
++	{0x02E8, {0x0000}},
++	{0x02EA, {0x0000}},
++	{0x02EC, {0x0000}},
++	{0x02EE, {0x0000}},
++	{0x02F0, {0x0000}},
++	{0x02F2, {0x0000}},
++	{0x02F4, {0x0000}},
++	{0x02F6, {0x0000}},
++	{0x02F8, {0x0000}},
++	{0x02FA, {0x0000}},
++	{0x02FC, {0x0000}},
++	{0x02FE, {0x0000}},
++	{0x0300, {0xDC04}},
++	{0x0302, {0x5820}},
++	{0x0304, {0x0000}},
++	{0x0306, {0x0000}},
++	{0x0308, {0x0000}},
++	{0x030A, {0x0040}},
++	{0x030C, {0x0810}},
++	{0x030E, {0xA000}},
++	{0x0310, {0x0093}},
++	{0x0312, {0x7FFF}},
++	{0x0314, {0x0000}},
++	{0x0316, {0x7FFF}},
++	{0x0318, {0x0000}},
++	{0x031A, {0x0000}},
++	{0x031C, {0x7FFF}},
++	{0x031E, {0x7FFF}},
++	{0x0320, {0x7FFF}},
++	{0x0322, {0x7FFF}},
++	{0x0324, {0x0400}},
++	{0x0326, {0x001F}},
++	{0x0328, {0x3040}},
++	{0x032A, {0x0080}},
++	{0x032C, {0x0006}},
++	{0x032E, {0x0A1F}},
++	{0x0330, {0x08A1}},
++	{0x0332, {0x003F}},
++	{0x0334, {0x0020}},
++	{0x0336, {0x0400}},
++	{0x0338, {0x4801}},
++	{0x033A, {0x0096}},
++	{0x033C, {0x0002}},
++	{0x033E, {0x0004}},
++	{0x0340, {0x0000}},
++	{0x0342, {0x0400}},
++	{0x0344, {0x0000}},
++	{0x0346, {0x0005}},
++	{0x0348, {0x0000}},
++	{0x034A, {0x0000}},
++	{0x034C, {0x0000}},
++	{0x034E, {0x0000}},
++	{0x0350, {0x0000}},
++	{0x0352, {0x0000}},
++	{0x0354, {0x1122}},
++	{0x0356, {0x3344}},
++	{0x0358, {0x0806}},
++	{0x035A, {0x0228}},
++	{0x035C, {0xA000}},
++	{0x035E, {0x0000}},
++	{0x0360, {0x0026}},
++	{0x0362, {0x0F10}},
++	{0x0364, {0x0A00}},
++	{0x0366, {0x4000}},
++	{0x0368, {0x0026}},
++	{0x036A, {0x1A00}},
++	{0x036C, {0x0800}},
++	{0x036E, {0x0400}},
++	{0x0370, {0x0320}},
++	{0x0372, {0x0000}},
++	{0x0374, {0x0B0B}},
++	{0x0376, {0x0000}},
++	{0x0378, {0x0000}},
++	{0x037A, {0x0010}},
++	{0x037C, {0x00AA}},
++	{0x037E, {0x2008}},
++	{0x0380, {0x0400}},
++	{0x0382, {0x0200}},
++	{0x0384, {0x7801}},
++	{0x0386, {0x0280}},
++	{0x0388, {0x0023}},
++	{0x038A, {0x003C}},
++	{0x038C, {0x2801}},
++	{0x038E, {0x08A1}},
++	{0x0390, {0x0000}},
++	{0x0392, {0xA000}},
++	{0x0394, {0x0000}},
++	{0x0396, {0x0000}},
++	{0x0398, {0x0000}},
++	{0x039A, {0x0000}},
++	{0x039C, {0x0000}},
++	{0x039E, {0x0000}},
++	{0x03A0, {0x0000}},
++	{0x03A2, {0x0080}},
++	{0x03A4, {0x0002}},
++	{0x03A6, {0x0064}},
++	{0x03A8, {0x000F}},
++	{0x03AA, {0x3333}},
++	{0x03AC, {0x7FBE}},
++	{0x03AE, {0x3333}},
++	{0x03B0, {0x7EB8}},
++	{0x03B2, {0x7FFF}},
++	{0x03B4, {0x0001}},
++	{0x03B6, {0x7FDF}},
++	{0x03B8, {0x0002}},
++	{0x03BA, {0x7333}},
++	{0x03BC, {0x7333}},
++	{0x03BE, {0x0031}},
++	{0x03C0, {0x0000}},
++	{0x03C2, {0x6666}},
++	{0x03C4, {0x0001}},
++	{0x03C6, {0x6666}},
++	{0x03C8, {0x7FFF}},
++	{0x03CA, {0x0100}},
++	{0x03CC, {0x0002}},
++	{0x03CE, {0x0000}},
++	{0x03D0, {0x0000}},
++	{0x03D2, {0x7213}},
++	{0x03D4, {0x0002}},
++	{0x03D6, {0x6000}},
++	{0x03D8, {0x0CCC}},
++	{0x03DA, {0x0000}},
++	{0x03DC, {0x0000}},
++	{0x03DE, {0x0000}},
++	{0x03E0, {0x0000}},
++	{0x03E2, {0x0000}},
++	{0x03E4, {0x0000}},
++	{0x03E6, {0x0002}},
++	{0x03E8, {0x01F0}},
++	{0x03EA, {0x0078}},
++	{0x03EC, {0x0032}},
++	{0x03EE, {0x0004}},
++	{0x03F0, {0x01F0}},
++	{0x03F2, {0x0078}},
++	{0x03F4, {0x0032}},
++	{0x03F6, {0x087A}},
++	{0x03F8, {0x0000}},
++	{0x03FA, {0x0000}},
++	{0x03FC, {0x0004}},
++	{0x03FE, {0x000E}},
++	{0x0400, {0x0714}},
++	{0x0402, {0x0320}},
++	{0x0404, {0x0033}},
++	{0x0406, {0x0000}},
++	{0x0408, {0x0B27}},
++	{0x040A, {0x1358}},
++	{0x040C, {0x0C52}},
++	{0x040E, {0x1560}},
++	{0x0410, {0x0DA2}},
++	{0x0412, {0x17A2}},
++	{0x0414, {0x0F0E}},
++	{0x0416, {0x1A21}},
++	{0x0418, {0x123D}},
++	{0x041A, {0x170A}},
++	{0x041C, {0x0000}},
++	{0x041E, {0x0000}},
++	{0x0420, {0x0000}},
++	{0x0422, {0x0000}},
++	{0x0424, {0x0000}},
++	{0x0426, {0x0000}},
++	{0x0428, {0x0190}},
++	{0x042A, {0x0190}},
++	{0x042C, {0x0000}},
++	{0x042E, {0x0000}},
++	{0x0430, {0x0000}},
++	{0x0432, {0x0000}},
++	{0x0434, {0x0000}},
++	{0x0436, {0x0000}},
++	{0x0438, {0x0000}},
++	{0x043A, {0x7FFF}},
++	{0x043C, {0x0001}},
++	{0x043E, {0x0000}},
++	{0x0440, {0x0000}},
++	{0x0442, {0x0000}},
++	{0x0444, {0x0000}},
++	{0x0446, {0x0000}},
++	{0x0448, {0x0000}},
++	{0x044A, {0x0000}},
++	{0x044C, {0x0000}},
++	{0x044E, {0x0000}},
++	{0x0450, {0x0000}},
++	{0x0452, {0x0000}},
++	{0x0454, {0x0000}},
++	{0x0456, {0x0000}},
++	{0x0458, {0x0000}},
++	{0x045A, {0x0000}},
++	{0x045C, {0x0000}},
++	{0x045E, {0x3000}},
++	{0x0460, {0x3FFF}},
++	{0x0462, {0x020C}},
++	{0x0464, {0x0000}},
++	{0x0466, {0x0000}},
++	{0x0468, {0x0000}},
++	{0x046A, {0x0000}},
++	{0x046C, {0x0000}},
++	{0x046E, {0x0000}},
++	{0x0470, {0x0000}},
++	{0x0472, {0x0000}},
++	{0x0474, {0x0000}},
++	{0x0476, {0x0000}},
++	{0x0478, {0x0000}},
++	{0x047A, {0x0000}},
++	{0x047C, {0x0000}},
++	{0x047E, {0x0000}},
++	{0x0480, {0x0000}},
++	{0x0482, {0x0000}},
++	{0x0484, {0x0000}},
++	{0x0486, {0x0000}},
++	{0x0488, {0x00C8}},
++	{0x048A, {0x000F}},
++	{0x048C, {0x0000}},
++	{0x048E, {0x02BC}},
++	{0x0490, {0x0000}},
++	{0x0492, {0x0514}},
++	{0x0494, {0x0064}},
++	{0x0496, {0x1999}},
++	{0x0498, {0x0CCC}},
++	{0x049A, {0x0005}},
++	{0x049C, {0x0005}},
++	{0x049E, {0x4026}},
++	{0x04A0, {0x5A67}},
++	{0x04A2, {0x4026}},
++	{0x04A4, {0x7FB2}},
++	{0x04A6, {0x0104}},
++	{0x04A8, {0x2026}},
++	{0x04AA, {0x0CCC}},
++	{0x04AC, {0x78D6}},
++	{0x04AE, {0x0D8F}},
++	{0x04B0, {0x0004}},
++	{0x04B2, {0x0000}},
++	{0x04B4, {0x0000}},
++	{0x04B6, {0x0000}},
++	{0x04B8, {0x0000}},
++	{0x04BA, {0x0000}},
++	{0x04BC, {0x0000}},
++	{0x04BE, {0x0000}},
++	{0x04C0, {0x0002}},
++	{0x04C2, {0x003C}},
++	{0x04C4, {0x005A}},
++	{0x04C6, {0x0014}},
++	{0x04C8, {0x0000}},
++	{0x04CA, {0x0000}},
++	{0x04CC, {0x0000}},
++	{0x04CE, {0x7333}},
++	{0x04D0, {0x0029}},
++	{0x04D2, {0x0200}},
++	{0x04D4, {0x0008}},
++	{0x04D6, {0x000C}},
++	{0x04D8, {0x0011}},
++	{0x04DA, {0x2666}},
++	{0x04DC, {0x0A81}},
++	{0x04DE, {0x0020}},
++	{0x04E0, {0x0005}},
++	{0x04E2, {0x0000}},
++	{0x04E4, {0x0002}},
++	{0x04E6, {0x0000}},
++	{0x04E8, {0x0000}},
++	{0x04EA, {0x0000}},
++	{0x04EC, {0x0000}},
++	{0x04EE, {0x0000}},
++	{0x04F0, {0x0000}},
++	{0x04F2, {0x0000}},
++	{0x04F4, {0x0000}},
++	{0x04F6, {0x0000}},
++	{0x04F8, {0x0000}},
++	{0x04FA, {0x0000}},
++	{0x04FC, {0x0000}},
++	{0x04FE, {0x0000}},
++	{0x0500, {0x0000}},
++	{0x0502, {0x0000}},
++	{0x0504, {0x0009}},
++	{0x0506, {0x03E8}},
++	{0x0508, {0x0200}},
++	{0x050A, {0x0000}},
++	{0x050C, {0x0009}},
++	{0x050E, {0x03E8}},
++	{0x0510, {0x0200}},
++	{0x0512, {0x0000}},
++	{0x0514, {0x0009}},
++	{0x0516, {0x03E8}},
++	{0x0518, {0x0200}},
++	{0x051A, {0x0000}},
++	{0x051C, {0x0009}},
++	{0x051E, {0x03E8}},
++	{0x0520, {0x0200}},
++	{0x0522, {0x0000}},
++	{0x0524, {0x0009}},
++	{0x0526, {0x03E8}},
++	{0x0528, {0x0200}},
++	{0x052A, {0x0000}},
++	{0x052C, {0x0009}},
++	{0x052E, {0x03E8}},
++	{0x0530, {0x0200}},
++	{0x0532, {0x0000}},
++	{0x0534, {0x0009}},
++	{0x0536, {0x03E8}},
++	{0x0538, {0x0200}},
++	{0x053A, {0x0000}},
++	{0x053C, {0x0009}},
++	{0x053E, {0x03E8}},
++	{0x0540, {0x0200}},
++	{0x0542, {0x0000}},
++	{0x0544, {0x0003}},
++	{0x0546, {0x0000}},
++	{0x0548, {0x0002}},
++	{0x054A, {0x00C8}},
++	{0x054C, {0x00C0}},
++	{0x054E, {0x0000}},
++	{0x0550, {0x0002}},
++	{0x0552, {0x00C8}},
++	{0x0554, {0x00C0}},
++	{0x0556, {0x0000}},
++	{0x0558, {0x0009}},
++	{0x055A, {0x03E8}},
++	{0x055C, {0x0200}},
++	{0x055E, {0x0000}},
++	{0x0560, {0x0009}},
++	{0x0562, {0x03E8}},
++	{0x0564, {0x0200}},
++	{0x0566, {0x0000}},
++	{0x0568, {0x0009}},
++	{0x056A, {0x03E8}},
++	{0x056C, {0x0200}},
++	{0x056E, {0x0000}},
++	{0x0570, {0x0009}},
++	{0x0572, {0x03E8}},
++	{0x0574, {0x0200}},
++	{0x0576, {0x0000}},
++	{0x0578, {0x0009}},
++	{0x057A, {0x03E8}},
++	{0x057C, {0x0200}},
++	{0x057E, {0x0000}},
++	{0x0580, {0x0009}},
++	{0x0582, {0x03E8}},
++	{0x0584, {0x0200}},
++	{0x0586, {0x0000}},
++	{0x0588, {0x0000}},
++	{0x058A, {0x0000}},
++	{0x058C, {0x0000}},
++	{0x058E, {0x0000}},
++	{0x0590, {0x0000}},
++	{0x0592, {0x0000}},
++	{0x0594, {0x0000}},
++	{0x0596, {0x0000}},
++	{0x0598, {0x0000}},
++	{0x059A, {0x0000}},
++	{0x059C, {0x0000}},
++	{0x059E, {0x0000}},
++	{0x05A0, {0x0000}},
++	{0x05A2, {0x0000}},
++	{0x05A4, {0x0000}},
++	{0x05A6, {0x0000}},
++	{0x05A8, {0x0000}},
++	{0x05AA, {0x0000}},
++	{0x05AC, {0x0000}},
++	{0x05AE, {0x0000}},
++	{0x05B0, {0x0000}},
++	{0x05B2, {0x0000}},
++	{0x05B4, {0x0000}},
++	{0x05B6, {0x0000}},
++	{0x05B8, {0x0000}},
++	{0x05BA, {0x0000}},
++	{0x05BC, {0x0000}},
++	{0x05BE, {0x0000}},
++	{0x05C0, {0x0000}},
++	{0x05C2, {0x0000}},
++	{0x05C4, {0x0000}},
++	{0x05C6, {0x0000}},
++	{0x05C8, {0x0000}},
++	{0x05CA, {0x0000}},
++	{0x05CC, {0x0000}},
++	{0x05CE, {0x0000}},
++	{0x05D0, {0x0000}},
++	{0x05D2, {0x0000}},
++	{0x05D4, {0x0000}},
++	{0x05D6, {0x0000}},
++	{0x05D8, {0x0000}},
++	{0x05DA, {0x0000}},
++	{0x05DC, {0x0000}},
++	{0x05DE, {0x0000}},
++	{0x05E0, {0x0000}},
++	{0x05E2, {0x0000}},
++	{0x05E4, {0x0000}},
++	{0x05E6, {0x0000}},
++	{0x05E8, {0x0000}},
++	{0x05EA, {0x0000}},
++	{0x05EC, {0x0000}},
++	{0x05EE, {0x0000}},
++	{0x05F0, {0x0000}},
++	{0x05F2, {0x0000}},
++	{0x05F4, {0x0000}},
++	{0x05F6, {0x0000}},
++	{0x05F8, {0x0000}},
++	{0x05FA, {0x0000}},
++	{0x05FC, {0x0000}},
++	{0x05FE, {0x0000}},
++	{0x0600, {0x3E80}},
++	{0x0602, {0x0000}},
++	{0x0604, {0x0400}},
++	{0x0606, {0x0000}},
++	{0x0608, {0xF700}},
++	{0x060A, {0x0100}},
++	{0x060C, {0x0002}},
++	{0x060E, {0x0200}},
++	{0x0610, {0xD300}},
++	{0x0612, {0x0080}},
++	{0x0614, {0x0066}},
++	{0x0616, {0x0133}},
++	{0x0618, {0xFE00}},
++	{0x061A, {0x0600}},
++	{0x061C, {0x0002}},
++	{0x061E, {0x0200}},
++	{0x0620, {0x3E80}},
++	{0x0622, {0x0010}},
++	{0x0624, {0x0000}},
++	{0x0626, {0x0000}},
++	{0x0628, {0xF700}},
++	{0x062A, {0x0100}},
++	{0x062C, {0x0002}},
++	{0x062E, {0x0200}},
++	{0x0630, {0xD300}},
++	{0x0632, {0x0080}},
++	{0x0634, {0x0066}},
++	{0x0636, {0x0133}},
++	{0x0638, {0xFE00}},
++	{0x063A, {0x0600}},
++	{0x063C, {0x0002}},
++	{0x063E, {0x0200}},
++	{0x0640, {0x3E80}},
++	{0x0642, {0x0002}},
++	{0x0644, {0x0600}},
++	{0x0646, {0x0000}},
++	{0x0648, {0xF700}},
++	{0x064A, {0x0100}},
++	{0x064C, {0x0002}},
++	{0x064E, {0x0200}},
++	{0x0650, {0xD300}},
++	{0x0652, {0x0080}},
++	{0x0654, {0x0066}},
++	{0x0656, {0x0133}},
++	{0x0658, {0xFE00}},
++	{0x065A, {0x0500}},
++	{0x065C, {0x0001}},
++	{0x065E, {0x0200}},
++	{0x0660, {0x0000}},
++	{0x0662, {0xEE80}},
++	{0x0664, {0x0000}},
++	{0x0666, {0x0000}},
++	{0x0668, {0x0000}},
++	{0x066A, {0x0000}},
++	{0x066C, {0x0000}},
++	{0x066E, {0x0000}},
++	{0x0670, {0x0000}},
++	{0x0672, {0xEE80}},
++	{0x0674, {0x0000}},
++	{0x0676, {0x0000}},
++	{0x0678, {0x0000}},
++	{0x067A, {0x0000}},
++	{0x067C, {0x0000}},
++	{0x067E, {0x0000}},
++	{0x0680, {0x0000}},
++	{0x0682, {0xEE80}},
++	{0x0684, {0x0000}},
++	{0x0686, {0x0000}},
++	{0x0688, {0x0000}},
++	{0x068A, {0x0000}},
++	{0x068C, {0x0000}},
++	{0x068E, {0x0000}},
++	{0x0690, {0x0000}},
++	{0x0692, {0x0000}},
++	{0x0694, {0x0000}},
++	{0x0696, {0x0000}},
++	{0x0698, {0x0000}},
++	{0x069A, {0x0000}},
++	{0x069C, {0x0000}},
++	{0x069E, {0x0000}},
++	{0x06A0, {0x0000}},
++	{0x06A2, {0x0000}},
++	{0x06A4, {0x0000}},
++	{0x06A6, {0x0000}},
++	{0x06A8, {0x0000}},
++	{0x06AA, {0x0000}},
++	{0x06AC, {0x0000}},
++	{0x06AE, {0x0000}},
++	{0x06B0, {0x0000}},
++	{0x06B2, {0x0000}},
++	{0x06B4, {0x0000}},
++	{0x06B6, {0x0000}},
++	{0x06B8, {0x0000}},
++	{0x06BA, {0x0000}},
++	{0x06BC, {0x0000}},
++	{0x06BE, {0x0000}},
++	{0x06C0, {0x0000}},
++	{0x06C2, {0x0000}},
++	{0x06C4, {0x0000}},
++	{0x06C6, {0x0000}},
++	{0x06C8, {0x0000}},
++	{0x06CA, {0x0000}},
++	{0x06CC, {0x0000}},
++	{0x06CE, {0x0000}},
++	{0x06D0, {0x0000}},
++	{0x06D2, {0x0000}},
++	{0x06D4, {0x0000}},
++	{0x06D6, {0x0000}},
++	{0x06D8, {0x0000}},
++	{0x06DA, {0x0000}},
++	{0x06DC, {0x0000}},
++	{0x06DE, {0x0000}},
++	{0x06E0, {0x0000}},
++	{0x06E2, {0x0000}},
++	{0x06E4, {0x0000}},
++	{0x06E6, {0x0000}},
++	{0x06E8, {0x0000}},
++	{0x06EA, {0x0000}},
++	{0x06EC, {0x0000}},
++	{0x06EE, {0x0000}},
++	{0x06F0, {0x0000}},
++	{0x06F2, {0x0000}},
++	{0x06F4, {0x0000}},
++	{0x06F6, {0x0000}},
++	{0x06F8, {0x0000}},
++	{0x06FA, {0x0000}},
++	{0x06FC, {0x0000}},
++	{0x06FE, {0x0000}},
++	{0x0700, {0x0000}},
++	{0x0702, {0x0000}},
++	{0x0704, {0x0000}},
++	{0x0706, {0x0000}},
++	{0x0708, {0x0000}},
++	{0x070A, {0x0000}},
++	{0x070C, {0x0000}},
++	{0x070E, {0x0000}},
++	{0x0710, {0x0000}},
++	{0x0712, {0x0000}},
++	{0x0714, {0x0000}},
++	{0x0716, {0x0000}},
++	{0x0718, {0x0000}},
++	{0x071A, {0x0000}},
++	{0x071C, {0x0000}},
++	{0x071E, {0x0000}},
++	{0x0720, {0x0000}},
++	{0x0722, {0x0000}},
++	{0x0724, {0x0000}},
++	{0x0726, {0x0000}},
++	{0x0728, {0x0000}},
++	{0x072A, {0x0000}},
++	{0x072C, {0x0000}},
++	{0x072E, {0x0000}},
++	{0x0730, {0x0000}},
++	{0x0732, {0x0000}},
++	{0x0734, {0x0000}},
++	{0x0736, {0x0000}},
++	{0x0738, {0x0000}},
++	{0x073A, {0x0000}},
++	{0x073C, {0x0000}},
++	{0x073E, {0x0000}},
++	{0x0740, {0x0000}},
++	{0x0742, {0x0000}},
++	{0x0744, {0x0000}},
++	{0x0746, {0x0000}},
++	{0x0748, {0x0000}},
++	{0x074A, {0x0000}},
++	{0x074C, {0x0000}},
++	{0x074E, {0x0000}},
++	{0x0750, {0x0000}},
++	{0x0752, {0x0000}},
++	{0x0754, {0x0000}},
++	{0x0756, {0x0000}},
++	{0x0758, {0x0000}},
++	{0x075A, {0x0000}},
++	{0x075C, {0x0000}},
++	{0x075E, {0x0000}},
++	{0x0760, {0x0000}},
++	{0x0762, {0x0000}},
++	{0x0764, {0x0000}},
++	{0x0766, {0x0000}},
++	{0x0768, {0x0000}},
++	{0x076A, {0x0000}},
++	{0x076C, {0x0000}},
++	{0x076E, {0x0000}},
++	{0x0770, {0x0000}},
++	{0x0772, {0x0000}},
++	{0x0774, {0x0000}},
++	{0x0776, {0x0000}},
++	{0x0778, {0x0000}},
++	{0x077A, {0x0000}},
++	{0x077C, {0x0000}},
++	{0x077E, {0x0000}},
++	{0x0780, {0x0000}},
++	{0x0782, {0x0000}},
++	{0x0784, {0x0000}},
++	{0x0786, {0x0000}},
++	{0x0788, {0x0000}},
++	{0x078A, {0x0000}},
++	{0x078C, {0x0000}},
++	{0x078E, {0x0000}},
++	{0x0790, {0x0000}},
++	{0x0792, {0x0000}},
++	{0x0794, {0x0000}},
++	{0x0796, {0x0000}},
++	{0x0798, {0x0000}},
++	{0x079A, {0x0000}},
++	{0x079C, {0x0000}},
++	{0x079E, {0x0000}},
++	{0x07A0, {0x0000}},
++	{0x07A2, {0x0000}},
++	{0x07A4, {0x0000}},
++	{0x07A6, {0x0000}},
++	{0x07A8, {0x0000}},
++	{0x07AA, {0x0000}},
++	{0x07AC, {0x0000}},
++	{0x07AE, {0x0000}},
++	{0x07B0, {0x0000}},
++	{0x07B2, {0x0000}},
++	{0x07B4, {0x0000}},
++	{0x07B6, {0x0000}},
++	{0x07B8, {0x0000}},
++	{0x07BA, {0x0000}},
++	{0x07BC, {0x0000}},
++	{0x07BE, {0x0000}},
++	{0x07C0, {0x0000}},
++	{0x07C2, {0x0000}},
++	{0x07C4, {0x0000}},
++	{0x07C6, {0x0000}},
++	{0x07C8, {0x0000}},
++	{0x07CA, {0x0000}},
++	{0x07CC, {0x0000}},
++	{0x07CE, {0x0000}},
++	{0x07D0, {0x0000}},
++	{0x07D2, {0x0000}},
++	{0x07D4, {0x0000}},
++	{0x07D6, {0x0000}},
++	{0x07D8, {0x0000}},
++	{0x07DA, {0x0000}},
++	{0x07DC, {0x0000}},
++	{0x07DE, {0x0000}},
++	{0x07E0, {0x0000}},
++	{0x07E2, {0x0000}},
++	{0x07E4, {0x0000}},
++	{0x07E6, {0x0000}},
++	{0x07E8, {0x0000}},
++	{0x07EA, {0x0000}},
++	{0x07EC, {0x0000}},
++	{0x07EE, {0x0000}},
++	{0x07F0, {0x0000}},
++	{0x07F2, {0x0000}},
++	{0x07F4, {0x0000}},
++	{0x07F6, {0x0000}},
++	{0x07F8, {0x0000}},
++	{0x07FA, {0x0000}},
++	{0x07FC, {0x0000}},
++	{0x07FE, {0x0000}},
++	{0x0800, {0x0000}},
++	{0x0802, {0x0000}},
++	{0x0804, {0x0000}},
++	{0x0806, {0x0000}},
++	{0x0808, {0x0000}},
++	{0x080A, {0x0000}},
++	{0x080C, {0x0000}},
++	{0x080E, {0x0000}},
++	{0x0810, {0x0000}},
++	{0x0812, {0x0000}},
++	{0x0814, {0x0000}},
++	{0x0816, {0x0000}},
++	{0x0818, {0x0000}},
++	{0x081A, {0x0000}},
++	{0x081C, {0x0000}},
++	{0x081E, {0x0000}},
++	{0x0820, {0x0000}},
++	{0x0822, {0x0000}},
++	{0x0824, {0x0000}},
++	{0x0826, {0x0000}},
++	{0x0828, {0x0000}},
++	{0x082A, {0x0000}},
++	{0x082C, {0x0000}},
++	{0x082E, {0x0000}},
++	{0x0830, {0x0000}},
++	{0x0832, {0x0000}},
++	{0x0834, {0x0000}},
++	{0x0836, {0x0000}},
++	{0x0838, {0x0000}},
++	{0x083A, {0x0000}},
++	{0x083C, {0x0000}},
++	{0x083E, {0x0000}},
++	{0x0840, {0x0000}},
++	{0x0842, {0x0000}},
++	{0x0844, {0x0000}},
++	{0x0846, {0x0000}},
++	{0x0848, {0x0000}},
++	{0x084A, {0x0000}},
++	{0x084C, {0x0000}},
++	{0x084E, {0x0000}},
++	{0x0850, {0x0000}},
++	{0x0852, {0x0000}},
++	{0x0854, {0x0000}},
++	{0x0856, {0x0000}},
++	{0x0858, {0x0000}},
++	{0x085A, {0x0000}},
++	{0x085C, {0x0000}},
++	{0x085E, {0x0000}},
++	{0x0860, {0x0000}},
++	{0x0862, {0x0000}},
++	{0x0864, {0x0000}},
++	{0x0866, {0x0000}},
++	{0x0868, {0x0000}},
++	{0x086A, {0x0000}},
++	{0x086C, {0x0000}},
++	{0x086E, {0x0000}},
++	{0x0870, {0x0000}},
++	{0x0872, {0x0000}},
++	{0x0874, {0x0000}},
++	{0x0876, {0x0000}},
++	{0x0878, {0x0000}},
++	{0x087A, {0x0000}},
++	{0x087C, {0x0000}},
++	{0x087E, {0x0000}},
++	{0x0880, {0x0000}},
++	{0x0882, {0x0000}},
++	{0x0884, {0x0000}},
++	{0x0886, {0x0000}},
++	{0x0888, {0x0000}},
++	{0x088A, {0x0000}},
++	{0x088C, {0x0000}},
++	{0x088E, {0x0000}},
++	{0x0890, {0x0000}},
++	{0x0892, {0x0000}},
++	{0x0894, {0x0000}},
++	{0x0896, {0x0000}},
++	{0x0898, {0x0000}},
++	{0x089A, {0x0000}},
++	{0x089C, {0x0000}},
++	{0x089E, {0x0000}},
++	{0x08A0, {0x0000}},
++	{0x08A2, {0x0000}},
++	{0x08A4, {0x0000}},
++	{0x08A6, {0x0000}},
++	{0x08A8, {0x0000}},
++	{0x08AA, {0x0000}},
++	{0x08AC, {0x0000}},
++	{0x08AE, {0x0000}},
++	{0x08B0, {0x0000}},
++	{0x08B2, {0x0000}},
++	{0x08B4, {0x0000}},
++	{0x08B6, {0x0000}},
++	{0x08B8, {0x0000}},
++	{0x08BA, {0x0000}},
++	{0x08BC, {0x0000}},
++	{0x08BE, {0x0000}},
++	{0x08C0, {0x0000}},
++	{0x08C2, {0x0000}},
++	{0x08C4, {0x0000}},
++	{0x08C6, {0x0000}},
++	{0x08C8, {0x0000}},
++	{0x08CA, {0x0000}},
++	{0x08CC, {0x0000}},
++	{0x08CE, {0x0000}},
++	{0x08D0, {0x0000}},
++	{0x08D2, {0x0000}},
++	{0x08D4, {0x0000}},
++	{0x08D6, {0x0000}},
++	{0x08D8, {0x0000}},
++	{0x08DA, {0x0000}},
++	{0x08DC, {0x0000}},
++	{0x08DE, {0x0000}},
++	{0x08E0, {0x0000}},
++	{0x08E2, {0x0000}},
++	{0x08E4, {0x0000}},
++	{0x08E6, {0x0000}},
++	{0x08E8, {0x0000}},
++	{0x08EA, {0x0000}},
++	{0x08EC, {0x0000}},
++	{0x08EE, {0x0000}},
++	{0x08F0, {0x0000}},
++	{0x08F2, {0x0000}},
++	{0x08F4, {0x0000}},
++	{0x08F6, {0x0000}},
++	{0x08F8, {0x0000}},
++	{0x08FA, {0x0000}},
++	{0x08FC, {0x0000}},
++	{0x08FE, {0x0000}},
++	{0x0900, {0x0000}},
++	{0x0902, {0x0000}},
++	{0x0904, {0x0000}},
++	{0x0906, {0x0000}},
++	{0x0908, {0x0000}},
++	{0x090A, {0x0000}},
++	{0x090C, {0x0000}},
++	{0x090E, {0x0000}},
++	{0x0910, {0x0000}},
++	{0x0912, {0x0000}},
++	{0x0914, {0x0000}},
++	{0x0916, {0x0000}},
++	{0x0918, {0x0000}},
++	{0x091A, {0x0000}},
++	{0x091C, {0x0000}},
++	{0x091E, {0x0000}},
++	{0x0920, {0x0000}},
++	{0x0922, {0x0000}},
++	{0x0924, {0x0000}},
++	{0x0926, {0x0000}},
++	{0x0928, {0x0000}},
++	{0x092A, {0x0000}},
++	{0x092C, {0x0000}},
++	{0x092E, {0x0000}},
++	{0x0930, {0x0000}},
++	{0x0932, {0x0000}},
++	{0x0934, {0x0000}},
++	{0x0936, {0x0000}},
++	{0x0938, {0x0000}},
++	{0x093A, {0x0000}},
++	{0x093C, {0x0000}},
++	{0x093E, {0x0000}},
++	{0x0940, {0x0000}},
++	{0x0942, {0x0000}},
++	{0x0944, {0x0000}},
++	{0x0946, {0x0000}},
++	{0x0948, {0x0000}},
++	{0x094A, {0x0000}},
++	{0x094C, {0x0000}},
++	{0x094E, {0x0000}},
++	{0x0950, {0x0000}},
++	{0x0952, {0x0000}},
++	{0x0954, {0x0000}},
++	{0x0956, {0x0000}},
++	{0x0958, {0x0000}},
++	{0x095A, {0x0000}},
++	{0x095C, {0x0000}},
++	{0x095E, {0x0000}},
++	{0x0960, {0x0000}},
++	{0x0962, {0x0000}},
++	{0x0964, {0x0000}},
++	{0x0966, {0x0000}},
++	{0x0968, {0x0000}},
++	{0x096A, {0x0000}},
++	{0x096C, {0x0000}},
++	{0x096E, {0x0000}},
++	{0x0970, {0x0000}},
++	{0x0972, {0x0000}},
++	{0x0974, {0x0000}},
++	{0x0976, {0x0000}},
++	{0x0978, {0x0000}},
++	{0x097A, {0x0000}},
++	{0x097C, {0x0000}},
++	{0x097E, {0x0000}},
++	{0x0980, {0x0000}},
++	{0x0982, {0x0000}},
++	{0x0984, {0x0000}},
++	{0x0986, {0x0000}},
++	{0x0988, {0x0000}},
++	{0x098A, {0x0000}},
++	{0x098C, {0x0000}},
++	{0x098E, {0x0000}},
++	{0x0990, {0x0000}},
++	{0x0992, {0x0000}},
++	{0x0994, {0x0000}},
++	{0x0996, {0x0000}},
++	{0x0998, {0x0000}},
++	{0x099A, {0x0000}},
++	{0x099C, {0x0000}},
++	{0x099E, {0x0000}},
++	{0x09A0, {0x0000}},
++	{0x09A2, {0x0000}},
++	{0x09A4, {0x0000}},
++	{0x09A6, {0x0000}},
++	{0x09A8, {0x0000}},
++	{0x09AA, {0x0000}},
++	{0x09AC, {0x0000}},
++	{0x09AE, {0x0000}},
++	{0x09B0, {0x0000}},
++	{0x09B2, {0x0000}},
++	{0x09B4, {0x0000}},
++	{0x09B6, {0x0000}},
++	{0x09B8, {0x0000}},
++	{0x09BA, {0x0000}},
++	{0x09BC, {0x0000}},
++	{0x09BE, {0x0000}},
++	{0x09C0, {0x0000}},
++	{0x09C2, {0x0000}},
++	{0x09C4, {0x0000}},
++	{0x09C6, {0x0000}},
++	{0x09C8, {0x0000}},
++	{0x09CA, {0x0000}},
++	{0x09CC, {0x0000}},
++	{0x09CE, {0x0000}},
++	{0x09D0, {0x0000}},
++	{0x09D2, {0x0000}},
++	{0x09D4, {0x0000}},
++	{0x09D6, {0x0000}},
++	{0x09D8, {0x0000}},
++	{0x09DA, {0x0000}},
++	{0x09DC, {0x0000}},
++	{0x09DE, {0x0000}},
++	{0x09E0, {0x0000}},
++	{0x09E2, {0x0000}},
++	{0x09E4, {0x0000}},
++	{0x09E6, {0x0000}},
++	{0x09E8, {0x0000}},
++	{0x09EA, {0x0000}},
++	{0x09EC, {0x0000}},
++	{0x09EE, {0x0000}},
++	{0x09F0, {0x0000}},
++	{0x09F2, {0x0000}},
++	{0x09F4, {0x0000}},
++	{0x09F6, {0x0000}},
++	{0x09F8, {0x0000}},
++	{0x09FA, {0x0000}},
++	{0x09FC, {0x0000}},
++	{0x09FE, {0x0000}},
++};
++const unsigned short zl_configBlockSize = 1;
++const unsigned short configStreamLen = 1024;
+diff --git a/sound/soc/codecs/zl380tw_config.h b/sound/soc/codecs/zl380tw_config.h
+new file mode 100644
+index 00000000..c765c21e
+--- /dev/null
++++ b/sound/soc/codecs/zl380tw_config.h
+@@ -0,0 +1,13 @@
++#ifndef __ZL380TW_CONFIG_H_
++#define __ZL380TW_CONFIG_H_
++
++#define ZL380XX_CFG_BLOCK_SIZE 1
++typedef struct {
++   unsigned short reg;   /*the register */
++   unsigned short value[ZL380XX_CFG_BLOCK_SIZE]; /*the value to write into reg */
++} dataArr;
++
++extern const unsigned short configStreamLen;
++extern const dataArr st_twConfig[];
++extern const unsigned short zl_configBlockSize;
++#endif
+diff --git a/sound/soc/codecs/zl380tw_firmware.c b/sound/soc/codecs/zl380tw_firmware.c
+new file mode 100644
+index 00000000..17702e81
+--- /dev/null
++++ b/sound/soc/codecs/zl380tw_firmware.c
+@@ -0,0 +1,4715 @@
++/*Source file Microsemi_ZLS38051_P2.0.2_firmware.s3, modified: Thu Dec 08 16:32:27 2016
++ */ 
++#include "zl380tw_firmware.h"
++
++const twFwr st_twFirmware[] ={
++	{{0x0000, 0x1c0f, 0x0010, 0x0016, 0x0001, 0x0000, 0x0000, 0x0000, 0x000d, 0x000e, 0x000e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080200, 1},
++	{{0x0000, 0x0000, 0x0002, 0x0005, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080220, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080240, 1},
++	{{0x8004, 0x01f2, 0xc0c0, 0x0000, 0x0100, 0x0101, 0x0004, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4040, 0x0000 }, 16, 0x00080260, 1},
++	{{0x0000, 0x0002, 0x0004, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080280, 1},
++	{{0xc000, 0xc000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000e, 0x0004, 0x000c, 0x0000, 0x815e, 0xfff1, 0x81e0, 0xfff1 }, 16, 0x000802a0, 1},
++	{{0x03ec, 0xfff6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000802c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000802e0, 1},
++	{{0xdc04, 0x5820, 0x0000, 0x0000, 0x0000, 0x0040, 0x0810, 0xa000, 0x0093, 0x7fff, 0x0000, 0x7fff, 0x0000, 0x0000, 0x7fff, 0x7fff }, 16, 0x00080300, 1},
++	{{0x7fff, 0x7fff, 0x0400, 0x001f, 0x3040, 0x0080, 0x0006, 0x0a1f, 0x08a1, 0x003f, 0x0020, 0x0400, 0x4801, 0x0096, 0x0002, 0x0004 }, 16, 0x00080320, 1},
++	{{0x0000, 0x0400, 0x0000, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1122, 0x3344, 0x0806, 0x0228, 0xa000, 0x0000 }, 16, 0x00080340, 1},
++	{{0x0026, 0x0f10, 0x0a00, 0x4000, 0x0026, 0x1a00, 0x0800, 0x0400, 0x0320, 0x0000, 0x0b0b, 0x0000, 0x0000, 0x0010, 0x00aa, 0x2008 }, 16, 0x00080360, 1},
++	{{0x0400, 0x0200, 0x7801, 0x0280, 0x0023, 0x003c, 0x2801, 0x08a1, 0x0000, 0xa000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080380, 1},
++	{{0x0000, 0x0080, 0x0002, 0x0064, 0x000f, 0x3333, 0x7fbe, 0x3333, 0x7eb8, 0x7fff, 0x0001, 0x7fdf, 0x0002, 0x7333, 0x7333, 0x0031 }, 16, 0x000803a0, 1},
++	{{0x0000, 0x6666, 0x0001, 0x6666, 0x7fff, 0x0100, 0x0002, 0x0000, 0x0000, 0x7213, 0x0002, 0x6000, 0x0ccc, 0x0000, 0x0000, 0x0000 }, 16, 0x000803c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0002, 0x01f0, 0x0078, 0x0032, 0x0004, 0x01f0, 0x0078, 0x0032, 0x087a, 0x0000, 0x0000, 0x0004, 0x000e }, 16, 0x000803e0, 1},
++	{{0x0714, 0x0320, 0x0033, 0x0000, 0x0b27, 0x1358, 0x0c52, 0x1560, 0x0da2, 0x17a2, 0x0f0e, 0x1a21, 0x123d, 0x170a, 0x0000, 0x0000 }, 16, 0x00080400, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0190, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x0001, 0x0000 }, 16, 0x00080420, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000 }, 16, 0x00080440, 1},
++	{{0x3fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080460, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080480, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000804a0, 1},
++	{{0x0002, 0x003c, 0x005a, 0x0014, 0x0000, 0x0000, 0x0000, 0x7333, 0x0129, 0x0004, 0x000c, 0x000a, 0x0011, 0x2666, 0x0a5a, 0x0030 }, 16, 0x000804c0, 1},
++	{{0x0005, 0x0000, 0x0002, 0x1000, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000804e0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8 }, 16, 0x00080500, 1},
++	{{0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8 }, 16, 0x00080520, 1},
++	{{0x0200, 0x0000, 0x0003, 0x0000, 0x0002, 0x00c8, 0x00c0, 0x0000, 0x0002, 0x00c8, 0x00c0, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000 }, 16, 0x00080540, 1},
++	{{0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000 }, 16, 0x00080560, 1},
++	{{0x0009, 0x03e8, 0x0200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080580, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000805a0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000805c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000805e0, 1},
++	{{0x3e80, 0x0000, 0x0400, 0x0000, 0xf700, 0x0100, 0x0002, 0x0200, 0xd300, 0x0080, 0x0066, 0x0133, 0xfe00, 0x0600, 0x0002, 0x0200 }, 16, 0x00080600, 1},
++	{{0x3e80, 0x0010, 0x0000, 0x0000, 0xf700, 0x0100, 0x0002, 0x0200, 0xd300, 0x0080, 0x0066, 0x0133, 0xfe00, 0x0600, 0x0002, 0x0200 }, 16, 0x00080620, 1},
++	{{0x3e80, 0x0002, 0x0600, 0x0000, 0xf700, 0x0100, 0x0002, 0x0200, 0xd300, 0x0080, 0x0066, 0x0133, 0xfe00, 0x0500, 0x0001, 0x0200 }, 16, 0x00080640, 1},
++	{{0x0000, 0xee80, 0x0000, 0x0000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xee80, 0x0000, 0x0000, 0x8000, 0x8000, 0x0000, 0x0000 }, 16, 0x00080660, 1},
++	{{0x0000, 0xee80, 0x0000, 0x0000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0001, 0xffe2, 0x01f4, 0x0003, 0x0006, 0x00c8, 0x0000, 0x0000 }, 16, 0x00080680, 1},
++	{{0x07ff, 0x0c10, 0x0f08, 0x100a, 0x0508, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000806a0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000806c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000806e0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080700, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080720, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080740, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080760, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080780, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000807a0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000807c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000807e0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080800, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080820, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080840, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080860, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080880, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000808a0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000808c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000808e0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080900, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080920, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080940, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080960, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080980, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000809a0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000809c0, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000809e0, 1},
++	{{0x0008, 0x5014, 0x0008, 0x50ec, 0x0008, 0x501c, 0x0000, 0x0018, 0x0000, 0x0000, 0x0008, 0xd090, 0x0008, 0x5104, 0x0000, 0x0010 }, 16, 0x00084000, 1},
++	{{0x0000, 0x0000, 0x0008, 0xd0d0, 0x0008, 0x5114, 0x0000, 0x0010, 0x0000, 0x0000, 0x0008, 0xd0f0, 0x0008, 0x5124, 0x0000, 0x0000 }, 16, 0x00084020, 1},
++	{{0x0000, 0x000c, 0x0008, 0xd10c, 0x0008, 0x5130, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xd114, 0x0008, 0x5134, 0x0000, 0x0000 }, 16, 0x00084040, 1},
++	{{0x0000, 0x0004, 0x0008, 0xd8ac, 0x0008, 0x5138, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0xd8ae, 0x0008, 0x513a, 0x0000, 0x0002 }, 16, 0x00084060, 1},
++	{{0x0000, 0x0000, 0x0008, 0xd8b4, 0x0008, 0x513c, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0xd8b8, 0x0008, 0x513e, 0x0000, 0x0000 }, 16, 0x00084080, 1},
++	{{0x0000, 0x0001, 0x0008, 0xd8bb, 0x0008, 0x513f, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xd8d0, 0x0008, 0x5180, 0x0000, 0x0004 }, 16, 0x000840a0, 1},
++	{{0x0000, 0x0000, 0x0008, 0xd8d4, 0x0008, 0x5184, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xd8d5, 0x0008, 0x5185, 0x0000, 0x0000 }, 16, 0x000840c0, 1},
++	{{0x0000, 0x0001, 0x0008, 0xf038, 0x0008, 0x51b0, 0x0000, 0x000c, 0x0000, 0x0000, 0x0008, 0xf044, 0x0008, 0x51bc, 0x0000, 0x000c }, 16, 0x000840e0, 1},
++	{{0x0000, 0x0000, 0x0008, 0xf050, 0x0008, 0x51c8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf054, 0x0008, 0x51cc, 0x0000, 0x0000 }, 16, 0x00084100, 1},
++	{{0x0000, 0x0004, 0x0008, 0xf058, 0x0008, 0x51d0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf05c, 0x0008, 0x51d4, 0x0000, 0x0000 }, 16, 0x00084120, 1},
++	{{0x0000, 0x0004, 0x0008, 0xf060, 0x0008, 0x51d8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf064, 0x0008, 0x51dc, 0x0000, 0x0000 }, 16, 0x00084140, 1},
++	{{0x0000, 0x0004, 0x0008, 0xf068, 0x0008, 0x51e0, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0xf06a, 0x0008, 0x51e2, 0x0000, 0x0002 }, 16, 0x00084160, 1},
++	{{0x0000, 0x0000, 0x0008, 0xf06c, 0x0008, 0x51e4, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xf570, 0x0008, 0x55e8, 0x0000, 0x0018 }, 16, 0x00084180, 1},
++	{{0x0000, 0x0000, 0x0008, 0xf5b0, 0x0008, 0x5600, 0x0000, 0x000c, 0x0000, 0x0000, 0x0008, 0xf5bc, 0x0008, 0x560c, 0x0000, 0x0004 }, 16, 0x000841a0, 1},
++	{{0x0000, 0x0000, 0x0008, 0xf5c0, 0x0008, 0x5610, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf5c4, 0x0008, 0x5614, 0x0000, 0x0004 }, 16, 0x000841c0, 1},
++	{{0x0000, 0x0000, 0x0008, 0xf5c8, 0x0008, 0x5618, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf7cc, 0x0008, 0x561c, 0x0000, 0x0002 }, 16, 0x000841e0, 1},
++	{{0x0000, 0x0000, 0x0008, 0xf7ce, 0x0008, 0x561e, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xf7cf, 0x0008, 0x561f, 0x0000, 0x0000 }, 16, 0x00084200, 1},
++	{{0x0000, 0x0001, 0x0008, 0xf7d0, 0x0008, 0x5620, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x24e8, 0x0008, 0x5624, 0x0000, 0x0020 }, 16, 0x00084220, 1},
++	{{0x0000, 0x0000, 0x0009, 0x2508, 0x0008, 0x5644, 0x0000, 0x0020, 0x0000, 0x0000, 0x0009, 0x2528, 0x0008, 0x5664, 0x0000, 0x0010 }, 16, 0x00084240, 1},
++	{{0x0000, 0x0000, 0x0009, 0x2538, 0x0008, 0x5674, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x2548, 0x0008, 0x5684, 0x0000, 0x0010 }, 16, 0x00084260, 1},
++	{{0x0000, 0x0000, 0x0009, 0x2558, 0x0008, 0x5694, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x2778, 0x0008, 0x56a4, 0x0000, 0x00f0 }, 16, 0x00084280, 1},
++	{{0x0000, 0x0010, 0x0009, 0x2878, 0x0008, 0x57a4, 0x0000, 0x0018, 0x0000, 0x0000, 0x0009, 0x2890, 0x0008, 0x57bc, 0x0000, 0x0010 }, 16, 0x000842a0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x28a0, 0x0008, 0x57cc, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x28a8, 0x0008, 0x57d0, 0x0000, 0x0004 }, 16, 0x000842c0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x28ac, 0x0008, 0x57d4, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x28b0, 0x0008, 0x57d8, 0x0000, 0x0004 }, 16, 0x000842e0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x28b4, 0x0008, 0x57dc, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x28b8, 0x0008, 0x57e0, 0x0000, 0x0004 }, 16, 0x00084300, 1},
++	{{0x0000, 0x0000, 0x0009, 0x28c0, 0x0008, 0x57e4, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x28c4, 0x0008, 0x57e8, 0x0000, 0x0000 }, 16, 0x00084320, 1},
++	{{0x0000, 0x0004, 0x0009, 0x2cd6, 0x0008, 0x57ec, 0x0000, 0x003d, 0x0000, 0x0001, 0x0009, 0x2d14, 0x0008, 0x582a, 0x0000, 0x0037 }, 16, 0x00084340, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2d4c, 0x0008, 0x5862, 0x0000, 0x0037, 0x0000, 0x0001, 0x0009, 0x2d84, 0x0008, 0x589a, 0x0000, 0x0036 }, 16, 0x00084360, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2dbb, 0x0008, 0x58d1, 0x0000, 0x0032, 0x0000, 0x0001, 0x0009, 0x2dee, 0x0008, 0x5904, 0x0000, 0x0032 }, 16, 0x00084380, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2e21, 0x0008, 0x5937, 0x0000, 0x002f, 0x0000, 0x0001, 0x0009, 0x2e51, 0x0008, 0x5967, 0x0000, 0x002c }, 16, 0x000843a0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2e7e, 0x0008, 0x5994, 0x0000, 0x002b, 0x0000, 0x0001, 0x0009, 0x2eaa, 0x0008, 0x59c0, 0x0000, 0x002a }, 16, 0x000843c0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2ed5, 0x0008, 0x59eb, 0x0000, 0x0028, 0x0000, 0x0001, 0x0009, 0x2efe, 0x0008, 0x5a14, 0x0000, 0x0027 }, 16, 0x000843e0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2f26, 0x0008, 0x5a3c, 0x0000, 0x0026, 0x0000, 0x0001, 0x0009, 0x2f4d, 0x0008, 0x5a63, 0x0000, 0x0026 }, 16, 0x00084400, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2f74, 0x0008, 0x5a8a, 0x0000, 0x0024, 0x0000, 0x0001, 0x0009, 0x2f99, 0x0008, 0x5aaf, 0x0000, 0x0023 }, 16, 0x00084420, 1},
++	{{0x0000, 0x0001, 0x0009, 0x2fbd, 0x0008, 0x5ad3, 0x0000, 0x0021, 0x0000, 0x0001, 0x0009, 0x2fdf, 0x0008, 0x5af5, 0x0000, 0x0020 }, 16, 0x00084440, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3000, 0x0008, 0x5b16, 0x0000, 0x0020, 0x0000, 0x0001, 0x0009, 0x3021, 0x0008, 0x5b37, 0x0000, 0x0020 }, 16, 0x00084460, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3042, 0x0008, 0x5b58, 0x0000, 0x001e, 0x0000, 0x0001, 0x0009, 0x3061, 0x0008, 0x5b77, 0x0000, 0x001e }, 16, 0x00084480, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3080, 0x0008, 0x5b96, 0x0000, 0x001d, 0x0000, 0x0001, 0x0009, 0x309e, 0x0008, 0x5bb4, 0x0000, 0x001c }, 16, 0x000844a0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x30bb, 0x0008, 0x5bd1, 0x0000, 0x001b, 0x0000, 0x0001, 0x0009, 0x30d7, 0x0008, 0x5bed, 0x0000, 0x001b }, 16, 0x000844c0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x30f3, 0x0008, 0x5c09, 0x0000, 0x0019, 0x0000, 0x0001, 0x0009, 0x310d, 0x0008, 0x5c23, 0x0000, 0x0017 }, 16, 0x000844e0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3125, 0x0008, 0x5c3b, 0x0000, 0x0017, 0x0000, 0x0001, 0x0009, 0x313d, 0x0008, 0x5c53, 0x0000, 0x0016 }, 16, 0x00084500, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3154, 0x0008, 0x5c6a, 0x0000, 0x0016, 0x0000, 0x0001, 0x0009, 0x316b, 0x0008, 0x5c81, 0x0000, 0x0016 }, 16, 0x00084520, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3182, 0x0008, 0x5c98, 0x0000, 0x0016, 0x0000, 0x0001, 0x0009, 0x3199, 0x0008, 0x5caf, 0x0000, 0x0015 }, 16, 0x00084540, 1},
++	{{0x0000, 0x0001, 0x0009, 0x31af, 0x0008, 0x5cc5, 0x0000, 0x0015, 0x0000, 0x0001, 0x0009, 0x31c5, 0x0008, 0x5cdb, 0x0000, 0x0015 }, 16, 0x00084560, 1},
++	{{0x0000, 0x0001, 0x0009, 0x31db, 0x0008, 0x5cf1, 0x0000, 0x0015, 0x0000, 0x0001, 0x0009, 0x31f1, 0x0008, 0x5d07, 0x0000, 0x0014 }, 16, 0x00084580, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3206, 0x0008, 0x5d1c, 0x0000, 0x000f, 0x0000, 0x0001, 0x0009, 0x3216, 0x0008, 0x5d2c, 0x0000, 0x000d }, 16, 0x000845a0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3224, 0x0008, 0x5d3a, 0x0000, 0x000b, 0x0000, 0x0001, 0x0009, 0x3230, 0x0008, 0x5d46, 0x0000, 0x0008 }, 16, 0x000845c0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3239, 0x0008, 0x5d4f, 0x0000, 0x0007, 0x0000, 0x0001, 0x0009, 0x3241, 0x0008, 0x5d57, 0x0000, 0x0007 }, 16, 0x000845e0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3249, 0x0008, 0x5d5f, 0x0000, 0x0007, 0x0000, 0x0001, 0x0009, 0x3251, 0x0008, 0x5d67, 0x0000, 0x0006 }, 16, 0x00084600, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3258, 0x0008, 0x5d6e, 0x0000, 0x0006, 0x0000, 0x0001, 0x0009, 0x325f, 0x0008, 0x5d75, 0x0000, 0x0005 }, 16, 0x00084620, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3265, 0x0008, 0x5d7b, 0x0000, 0x0004, 0x0000, 0x0001, 0x0009, 0x326a, 0x0008, 0x5d80, 0x0000, 0x0004 }, 16, 0x00084640, 1},
++	{{0x0000, 0x0001, 0x0009, 0x326f, 0x0008, 0x5d85, 0x0000, 0x0004, 0x0000, 0x0001, 0x0009, 0x3274, 0x0008, 0x5d8a, 0x0000, 0x0004 }, 16, 0x00084660, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3279, 0x0008, 0x5d8f, 0x0000, 0x0003, 0x0000, 0x0001, 0x0009, 0x3281, 0x0008, 0x5d93, 0x0000, 0x0003 }, 16, 0x00084680, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3285, 0x0008, 0x5d97, 0x0000, 0x0003, 0x0000, 0x0001, 0x0009, 0x3289, 0x0008, 0x5d9b, 0x0000, 0x0003 }, 16, 0x000846a0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x328d, 0x0008, 0x5d9f, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x3290, 0x0008, 0x5da2, 0x0000, 0x0002 }, 16, 0x000846c0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3293, 0x0008, 0x5da5, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x3296, 0x0008, 0x5da8, 0x0000, 0x0002 }, 16, 0x000846e0, 1},
++	{{0x0000, 0x0001, 0x0009, 0x3299, 0x0008, 0x5dab, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x329c, 0x0008, 0x5dae, 0x0000, 0x0002 }, 16, 0x00084700, 1},
++	{{0x0000, 0x0001, 0x0009, 0x329f, 0x0008, 0x5db1, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x32a2, 0x0008, 0x5db4, 0x0000, 0x0002 }, 16, 0x00084720, 1},
++	{{0x0000, 0x0001, 0x0009, 0x32a5, 0x0008, 0x5db7, 0x0000, 0x0001, 0x0000, 0x0001, 0x0009, 0x32a7, 0x0008, 0x5db9, 0x0000, 0x0000 }, 16, 0x00084740, 1},
++	{{0x0000, 0x0001, 0x0009, 0x32a8, 0x0008, 0x5dba, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x32a9, 0x0008, 0x5dbb, 0x0000, 0x0000 }, 16, 0x00084760, 1},
++	{{0x0000, 0x0001, 0x0009, 0x32aa, 0x0008, 0x5dbc, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x32ab, 0x0008, 0x5dbd, 0x0000, 0x0000 }, 16, 0x00084780, 1},
++	{{0x0000, 0x0001, 0x0009, 0x32ac, 0x0008, 0x5dbe, 0x0000, 0x0001, 0x0000, 0x0000, 0x0009, 0x32fc, 0x0008, 0x6094, 0x0000, 0x000c }, 16, 0x000847a0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x3308, 0x0008, 0x60a0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3314, 0x0008, 0x60a4, 0x0000, 0x0000 }, 16, 0x000847c0, 1},
++	{{0x0000, 0x0004, 0x0009, 0x3320, 0x0008, 0x60a8, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x3334, 0x0008, 0x60ac, 0x0000, 0x0004 }, 16, 0x000847e0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x333c, 0x0008, 0x60b0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3340, 0x0008, 0x60b4, 0x0000, 0x0000 }, 16, 0x00084800, 1},
++	{{0x0000, 0x0004, 0x0009, 0x3344, 0x0008, 0x60b8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x334c, 0x0008, 0x60bc, 0x0000, 0x0000 }, 16, 0x00084820, 1},
++	{{0x0000, 0x0004, 0x0009, 0x3350, 0x0008, 0x60c0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3358, 0x0008, 0x60c4, 0x0000, 0x0000 }, 16, 0x00084840, 1},
++	{{0x0000, 0x0004, 0x0009, 0x335c, 0x0008, 0x60c8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3360, 0x0008, 0x60cc, 0x0000, 0x0000 }, 16, 0x00084860, 1},
++	{{0x0000, 0x0004, 0x0009, 0x3364, 0x0008, 0x60d0, 0x0000, 0x0002, 0x0000, 0x0000, 0x0009, 0x3366, 0x0008, 0x60d2, 0x0000, 0x0002 }, 16, 0x00084880, 1},
++	{{0x0000, 0x0000, 0x0009, 0x3369, 0x0008, 0x60d5, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x336a, 0x0008, 0x60d6, 0x0000, 0x0001 }, 16, 0x000848a0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x336c, 0x0008, 0x60d8, 0x0000, 0x0048, 0x0000, 0x0000, 0x0009, 0x33b4, 0x0008, 0x6120, 0x0000, 0x0000 }, 16, 0x000848c0, 1},
++	{{0x0000, 0x00c0, 0x0009, 0x3474, 0x0008, 0x61e0, 0x0000, 0x0000, 0x0000, 0x00c0, 0x0009, 0x3534, 0x0008, 0x69e8, 0x0000, 0x0000 }, 16, 0x000848e0, 1},
++	{{0x0000, 0x0004, 0x0009, 0x3538, 0x0008, 0x69ec, 0x0000, 0x0008, 0x0000, 0x0000, 0x0009, 0x3540, 0x0008, 0x69f4, 0x0000, 0x0002 }, 16, 0x00084900, 1},
++	{{0x0000, 0x0000, 0x0009, 0x3544, 0x0008, 0x69f8, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x3590, 0x0008, 0x6a08, 0x0000, 0x000c }, 16, 0x00084920, 1},
++	{{0x0000, 0x0000, 0x0009, 0x359c, 0x0008, 0x6a14, 0x0000, 0x000a, 0x0000, 0x0002, 0x0009, 0x35a8, 0x0008, 0x6a20, 0x0000, 0x0003 }, 16, 0x00084940, 1},
++	{{0x0000, 0x0000, 0x0009, 0x35ab, 0x0008, 0x6a23, 0x0000, 0x0003, 0x0000, 0x0000, 0x0009, 0x3690, 0x0008, 0x6a28, 0x0000, 0x0000 }, 16, 0x00084960, 1},
++	{{0x0000, 0x0004, 0x0009, 0x37c4, 0x0008, 0x6a2c, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x37d4, 0x0008, 0x6a50, 0x0000, 0x0058 }, 16, 0x00084980, 1},
++	{{0x0000, 0x0000, 0x0009, 0x382c, 0x0008, 0x6aa8, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x3c48, 0x0008, 0x6ac4, 0x0000, 0x0014 }, 16, 0x000849a0, 1},
++	{{0x0000, 0x0000, 0x0009, 0x3c5c, 0x0008, 0x6ad8, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0x3c68, 0x0008, 0x6ae4, 0x0000, 0x0000 }, 16, 0x000849c0, 1},
++	{{0x0000, 0x0004, 0x0009, 0x3c6c, 0x0008, 0x6ce8, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x3c70, 0x0008, 0x6cec, 0x0000, 0x0000 }, 16, 0x000849e0, 1},
++	{{0x0000, 0x0004, 0x0009, 0x4e74, 0x0008, 0x6cf0, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x4e80, 0x0008, 0x6cf4, 0x0000, 0x002c }, 16, 0x00084a00, 1},
++	{{0x0000, 0x0000, 0x0009, 0x4eac, 0x0008, 0x6d78, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0x82d0, 0x0008, 0x6d7c, 0x0000, 0x0004 }, 16, 0x00084a20, 1},
++	{{0x0000, 0x0000, 0x0009, 0x82d4, 0x0008, 0x6d80, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x82d8, 0x0008, 0x6d84, 0x0000, 0x0004 }, 16, 0x00084a40, 1},
++	{{0x0000, 0x0000, 0x0009, 0x82dc, 0x0008, 0x6d88, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x8ca0, 0x0008, 0x6d8c, 0x0000, 0x0000 }, 16, 0x00084a60, 1},
++	{{0x0000, 0x0002, 0x0009, 0x8ca2, 0x0008, 0x6d90, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0xb3b8, 0x0008, 0x6d94, 0x0000, 0x0000 }, 16, 0x00084a80, 1},
++	{{0x0000, 0x0004, 0x0009, 0xb3bc, 0x0008, 0x6d98, 0x0000, 0x0002, 0x0000, 0x0000, 0x0009, 0xb3be, 0x0008, 0x6d9a, 0x0000, 0x0002 }, 16, 0x00084aa0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xb3c0, 0x0008, 0x6d9c, 0x0000, 0x0002, 0x0000, 0x0000, 0x0009, 0xbbc8, 0x0008, 0x6da0, 0x0000, 0x0538 }, 16, 0x00084ac0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc100, 0x0008, 0x72d8, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xc2bc, 0x0008, 0x72fc, 0x0000, 0x0004 }, 16, 0x00084ae0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc2c0, 0x0008, 0x7300, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xc2c4, 0x0008, 0x7304, 0x0000, 0x0004 }, 16, 0x00084b00, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc2c8, 0x0008, 0x7308, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xc2cc, 0x0008, 0x730c, 0x0000, 0x0002 }, 16, 0x00084b20, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc30c, 0x0008, 0x7310, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0xc31c, 0x0008, 0x731c, 0x0000, 0x0000 }, 16, 0x00084b40, 1},
++	{{0x0000, 0x0001, 0x0009, 0xc31d, 0x0008, 0x731d, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0xc31e, 0x0008, 0x731e, 0x0000, 0x0000 }, 16, 0x00084b60, 1},
++	{{0x0000, 0x0001, 0x0009, 0xc360, 0x0008, 0x7320, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0xc364, 0x0008, 0x7324, 0x0000, 0x0000 }, 16, 0x00084b80, 1},
++	{{0x0000, 0x0004, 0x0009, 0xc368, 0x0008, 0x7328, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0xc36c, 0x0008, 0x732c, 0x0000, 0x0000 }, 16, 0x00084ba0, 1},
++	{{0x0000, 0x0004, 0x0009, 0xc372, 0x0008, 0x7330, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0xc390, 0x0008, 0x7334, 0x0000, 0x0030 }, 16, 0x00084bc0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc3c0, 0x0008, 0x7364, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0xc3d0, 0x0008, 0x7374, 0x0000, 0x02c2 }, 16, 0x00084be0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc692, 0x0008, 0x7636, 0x0000, 0x007e, 0x0000, 0x0002, 0x0009, 0xc712, 0x0008, 0x76b6, 0x0000, 0x0080 }, 16, 0x00084c00, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc792, 0x0008, 0x7736, 0x0000, 0x0080, 0x0000, 0x0000, 0x0009, 0xc812, 0x0008, 0x77b6, 0x0000, 0x0040 }, 16, 0x00084c20, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc852, 0x0008, 0x77f6, 0x0000, 0x0040, 0x0000, 0x0000, 0x0009, 0xc892, 0x0008, 0x7836, 0x0000, 0x003e }, 16, 0x00084c40, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc8d0, 0x0008, 0x7874, 0x0000, 0x003e, 0x0000, 0x0000, 0x0009, 0xc90e, 0x0008, 0x78b2, 0x0000, 0x0010 }, 16, 0x00084c60, 1},
++	{{0x0000, 0x0010, 0x0009, 0xc92e, 0x0008, 0x78d2, 0x0000, 0x001e, 0x0000, 0x0002, 0x0009, 0xc94e, 0x0008, 0x78f2, 0x0000, 0x0020 }, 16, 0x00084c80, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc96e, 0x0008, 0x7912, 0x0000, 0x001e, 0x0000, 0x0002, 0x0009, 0xc98e, 0x0008, 0x7932, 0x0000, 0x001e }, 16, 0x00084ca0, 1},
++	{{0x0000, 0x0002, 0x0009, 0xc9ae, 0x0008, 0x7952, 0x0000, 0x0010, 0x0000, 0x0010, 0x0009, 0xc9ce, 0x0008, 0x7972, 0x0000, 0x0010 }, 16, 0x00084cc0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc9de, 0x0008, 0x7982, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0xc9ee, 0x0008, 0x7992, 0x0000, 0x0010 }, 16, 0x00084ce0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xc9fe, 0x0008, 0x79a2, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0xca0a, 0x0008, 0x79ae, 0x0000, 0x0008 }, 16, 0x00084d00, 1},
++	{{0x0000, 0x0000, 0x0009, 0xca12, 0x0008, 0x79b6, 0x0000, 0x0004, 0x0000, 0x0004, 0x0009, 0xca1a, 0x0008, 0x79be, 0x0000, 0x0008 }, 16, 0x00084d20, 1},
++	{{0x0000, 0x0000, 0x0009, 0xca22, 0x0008, 0x79c6, 0x0000, 0x0006, 0x0000, 0x0000, 0x0009, 0xca28, 0x0008, 0x79cc, 0x0000, 0x0006 }, 16, 0x00084d40, 1},
++	{{0x0000, 0x0000, 0x0009, 0xca30, 0x0008, 0x79d4, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0xca3c, 0x0008, 0x79e0, 0x0000, 0x0000 }, 16, 0x00084d60, 1},
++	{{0x0000, 0x0004, 0x0009, 0xca40, 0x0008, 0x79e4, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0xca44, 0x0008, 0x79e8, 0x0000, 0x0044 }, 16, 0x00084d80, 1},
++	{{0x0000, 0x0000, 0x0009, 0xca88, 0x0008, 0x7a2c, 0x0000, 0x0030, 0x0000, 0x0000, 0x0009, 0xcabc, 0x0008, 0x7a5c, 0x0000, 0x0000 }, 16, 0x00084da0, 1},
++	{{0x0000, 0x0010, 0x0009, 0xcace, 0x0008, 0x7a6c, 0x0000, 0x0059, 0x0000, 0x0001, 0x0009, 0xcb28, 0x0008, 0x7ac6, 0x0000, 0x0059 }, 16, 0x00084dc0, 1},
++	{{0x0000, 0x0001, 0x0009, 0xcb82, 0x0008, 0x7b20, 0x0000, 0x0059, 0x0000, 0x0001, 0x0009, 0xcbdc, 0x0008, 0x7b7a, 0x0000, 0x0059 }, 16, 0x00084de0, 1},
++	{{0x0000, 0x0001, 0x0009, 0xcd38, 0x0008, 0x7bd4, 0x0000, 0x00f4, 0x0000, 0x0000, 0x0009, 0xce2c, 0x0008, 0x7cc8, 0x0000, 0x0028 }, 16, 0x00084e00, 1},
++	{{0x0000, 0x0000, 0x0009, 0xce54, 0x0008, 0x7cf0, 0x0000, 0x001c, 0x0000, 0x0000, 0x0009, 0xce70, 0x0008, 0x7d0c, 0x0000, 0x0014 }, 16, 0x00084e20, 1},
++	{{0x0000, 0x0008, 0x0009, 0xce8c, 0x0008, 0x7d28, 0x0000, 0x0010, 0x0000, 0x0004, 0x0009, 0xcea0, 0x0008, 0x7d3c, 0x0000, 0x0008 }, 16, 0x00084e40, 1},
++	{{0x0000, 0x0000, 0x0009, 0xceac, 0x0008, 0x7d44, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xceb0, 0x0008, 0x7d48, 0x0000, 0x0004 }, 16, 0x00084e60, 1},
++	{{0x0000, 0x0000, 0x0009, 0xceb4, 0x0008, 0x7d4c, 0x0000, 0x028c, 0x0000, 0x0004, 0x0009, 0xd144, 0x0008, 0x7fdc, 0x0000, 0x028c }, 16, 0x00084e80, 1},
++	{{0x0000, 0x0004, 0x0009, 0xd3d4, 0x0008, 0x826c, 0x0000, 0x0232, 0x0000, 0x0002, 0x0009, 0xd608, 0x0008, 0x84a0, 0x0000, 0x0010 }, 16, 0x00084ea0, 1},
++	{{0x0000, 0x0004, 0x0009, 0xd61c, 0x0008, 0x84b4, 0x0000, 0x0000, 0x0000, 0x000c, 0x0009, 0xd628, 0x0008, 0x84c0, 0x0000, 0x0000 }, 16, 0x00084ec0, 1},
++	{{0x0000, 0x0004, 0x0009, 0xd630, 0x0008, 0x84c4, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xd634, 0x0008, 0x84c8, 0x0000, 0x0004 }, 16, 0x00084ee0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xd638, 0x0008, 0x84cc, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xd63c, 0x0008, 0x84d0, 0x0000, 0x0004 }, 16, 0x00084f00, 1},
++	{{0x0000, 0x0000, 0x0009, 0xd640, 0x0008, 0x84d4, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xd644, 0x0008, 0x84d8, 0x0000, 0x0004 }, 16, 0x00084f20, 1},
++	{{0x0000, 0x0000, 0x0009, 0xd648, 0x0008, 0x84dc, 0x0000, 0x0000, 0x0000, 0x0004, 0x000b, 0xfa00, 0x0008, 0x84e0, 0x0000, 0x0000 }, 16, 0x00084f40, 1},
++	{{0x0000, 0x0c18, 0x000c, 0x20f4, 0x0008, 0x90f8, 0x0000, 0x0000, 0x0000, 0x0004, 0x000c, 0x20f8, 0x0008, 0x90fc, 0x0000, 0x0000 }, 16, 0x00084f60, 1},
++	{{0x0000, 0x0004, 0x000c, 0x20fc, 0x0008, 0x9100, 0x0000, 0x0000, 0x0000, 0x0004, 0x000c, 0x2100, 0x0008, 0x9104, 0x0000, 0x0000 }, 16, 0x00084f80, 1},
++	{{0x0000, 0x0004, 0x000c, 0x2660, 0x0008, 0x9108, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0xd664, 0x0008, 0x9308, 0x0000, 0x0000 }, 16, 0x00084fa0, 1},
++	{{0x0000, 0x0004, 0x0009, 0xd668, 0x0008, 0x930c, 0x0000, 0x0008, 0x0000, 0x0000, 0x0009, 0xd670, 0x0008, 0x9314, 0x0000, 0x0010 }, 16, 0x00084fc0, 1},
++	{{0x0000, 0x0000, 0x0009, 0xd680, 0x0008, 0x9324, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0xd684, 0x0008, 0x9328, 0x0000, 0x0000 }, 16, 0x00084fe0, 1},
++	{{0x0000, 0x0004, 0x0009, 0xd688, 0x0008, 0x932c, 0x0000, 0x0004, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, }, 14, 0x00085000, 1},
++	{{0x000c, 0x5600, 0x000c, 0x5500, 0x000c, 0xa000, 0x0000, 0x0100, 0x000c, 0xa000, 0x0000, 0x0000, }, 12, 0x0008501c, 1},
++	{{0x0008, 0x9800, 0x0001, 0x3ea0, 0x000b, 0xfa00, 0x0000, 0x35f4, 0x0000, 0x0002, }, 10, 0x00085034, 1},
++	{{0x6874, 0x7470, 0x3a2f, 0x2f61, 0x7573, 0x7376, 0x6e30, 0x312f, 0x7376, 0x6e2f, 0x7469, 0x6d62, 0x6572, 0x776f, 0x6c66, 0x2d73 }, 16, 0x00085048, 1},
++	{{0x772f, 0x6669, 0x726d, 0x7761, 0x7265, 0x2f7a, 0x6c73, 0x3338, 0x3035, 0x312f, 0x6272, 0x616e, 0x6368, 0x6573, 0x2f4d, 0x6169 }, 16, 0x00085068, 1},
++	{{0x6e74, 0x656e, 0x616e, 0x6365, 0x2f56, 0x6572, 0x5f32, 0x5f30, 0x5f31, 0x0038, 0x3231, 0x3600, 0x556e, 0x6d6f, 0x6469, 0x6669 }, 16, 0x00085088, 1},
++	{{0x6564, 0x0032, 0x3031, 0x362f, 0x3130, 0x2f32, 0x3620, 0x3132, 0x3a32, 0x393a, 0x3137, 0x0032, 0x3031, 0x362f, 0x3130, 0x2f32 }, 16, 0x000850a8, 1},
++	{{0x3620, 0x3132, 0x3a33, 0x333a, 0x3531, 0x0000, 0x0008, 0x5048, 0x0008, 0x509b, 0x0008, 0x50a0, 0x0008, 0x50ab, 0x0008, 0x50bf }, 16, 0x000850c8, 1},
++	{{0x2018, 0x0000, 0x000c, 0x5600, 0x000c, 0x5500, 0x000c, 0xa000, 0x0000, 0x0100, 0x000c, 0xa000, 0x0000, 0x0000, 0x0008, 0xd41c }, 16, 0x000850e8, 1},
++	{{0x0008, 0xd7dc, 0x0008, 0xd11c, 0x0008, 0xd1dc, 0x0008, 0xc1c0, 0x0008, 0xc040, 0x0008, 0xbe00, 0x0008, 0xbf80, 0x0000, 0x0000 }, 16, 0x00085108, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0001, 0x0000, 0x0008, 0x0008, 0x0010, 0x0018 }, 16, 0x00085128, 1},
++	{{0x0020, 0x002c, 0x0030, 0x0028, 0x1f40, 0x1f40, 0x3e80, 0x5dc0, 0x7d00, 0xac44, 0xbb80, 0x9c40, 0x0030, 0x0008, 0x0010, 0x0018 }, 16, 0x00085148, 1},
++	{{0x0030, 0x0030, 0x0030, 0x0030, 0x0001, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0005, 0x0008, 0x0200, 0x0000, 0x496e }, 16, 0x00085168, 1},
++	{{0x636f, 0x6d70, 0x6174, 0x6962, 0x6c65, 0x2041, 0x7070, 0x6c69, 0x6361, 0x7469, 0x6f6e, 0x0a00, 0x556e, 0x7472, 0x696d, 0x6d65 }, 16, 0x00085188, 1},
++	{{0x6420, 0x5061, 0x7274, 0x0a00, 0x000a, 0x224a, 0x000a, 0x22ca, 0x000a, 0x234a, 0x000a, 0x1f66, 0x000a, 0x1fde, 0x000a, 0x205a }, 16, 0x000851a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0030, 0x0000, 0x0000 }, 16, 0x000851c8, 1},
++	{{0x0000, 0x00c9, 0x0192, 0x025b, 0x0324, 0x03ed, 0x04b6, 0x057f, 0x0648, 0x0711, 0x07d9, 0x08a2, 0x096b, 0x0a33, 0x0afb, 0x0bc4 }, 16, 0x000851e8, 1},
++	{{0x0c8c, 0x0d54, 0x0e1c, 0x0ee4, 0x0fab, 0x1073, 0x113a, 0x1201, 0x12c8, 0x138f, 0x1455, 0x151c, 0x15e2, 0x16a8, 0x176e, 0x1833 }, 16, 0x00085208, 1},
++	{{0x18f9, 0x19be, 0x1a83, 0x1b47, 0x1c0c, 0x1cd0, 0x1d93, 0x1e57, 0x1f1a, 0x1fdd, 0x209f, 0x2162, 0x2224, 0x22e5, 0x23a7, 0x2467 }, 16, 0x00085228, 1},
++	{{0x2528, 0x25e8, 0x26a8, 0x2768, 0x2827, 0x28e5, 0x29a4, 0x2a62, 0x2b1f, 0x2bdc, 0x2c99, 0x2d55, 0x2e11, 0x2ecc, 0x2f87, 0x3042 }, 16, 0x00085248, 1},
++	{{0x30fc, 0x31b5, 0x326e, 0x3327, 0x33df, 0x3497, 0x354e, 0x3604, 0x36ba, 0x3770, 0x3825, 0x38d9, 0x398d, 0x3a40, 0x3af3, 0x3ba5 }, 16, 0x00085268, 1},
++	{{0x3c57, 0x3d08, 0x3db8, 0x3e68, 0x3f17, 0x3fc6, 0x4074, 0x4121, 0x41ce, 0x427a, 0x4326, 0x43d1, 0x447b, 0x4524, 0x45cd, 0x4675 }, 16, 0x00085288, 1},
++	{{0x471d, 0x47c4, 0x486a, 0x490f, 0x49b4, 0x4a58, 0x4afb, 0x4b9e, 0x4c40, 0x4ce1, 0x4d81, 0x4e21, 0x4ec0, 0x4f5e, 0x4ffb, 0x5098 }, 16, 0x000852a8, 1},
++	{{0x5134, 0x51cf, 0x5269, 0x5303, 0x539b, 0x5433, 0x54ca, 0x5560, 0x55f6, 0x568a, 0x571e, 0x57b1, 0x5843, 0x58d4, 0x5964, 0x59f4 }, 16, 0x000852c8, 1},
++	{{0x5a82, 0x5b10, 0x5b9d, 0x5c29, 0x5cb4, 0x5d3e, 0x5dc8, 0x5e50, 0x5ed7, 0x5f5e, 0x5fe4, 0x6068, 0x60ec, 0x616f, 0x61f1, 0x6272 }, 16, 0x000852e8, 1},
++	{{0x62f2, 0x6371, 0x63ef, 0x646c, 0x64e9, 0x6564, 0x65de, 0x6657, 0x66d0, 0x6747, 0x67bd, 0x6832, 0x68a7, 0x691a, 0x698c, 0x69fd }, 16, 0x00085308, 1},
++	{{0x6a6e, 0x6add, 0x6b4b, 0x6bb8, 0x6c24, 0x6c8f, 0x6cf9, 0x6d62, 0x6dca, 0x6e31, 0x6e97, 0x6efb, 0x6f5f, 0x6fc2, 0x7023, 0x7083 }, 16, 0x00085328, 1},
++	{{0x70e3, 0x7141, 0x719e, 0x71fa, 0x7255, 0x72af, 0x7308, 0x735f, 0x73b6, 0x740b, 0x7460, 0x74b3, 0x7505, 0x7556, 0x75a6, 0x75f4 }, 16, 0x00085348, 1},
++	{{0x7642, 0x768e, 0x76d9, 0x7723, 0x776c, 0x77b4, 0x77fb, 0x7840, 0x7885, 0x78c8, 0x790a, 0x794a, 0x798a, 0x79c9, 0x7a06, 0x7a42 }, 16, 0x00085368, 1},
++	{{0x7a7d, 0x7ab7, 0x7aef, 0x7b27, 0x7b5d, 0x7b92, 0x7bc6, 0x7bf9, 0x7c2a, 0x7c5a, 0x7c89, 0x7cb7, 0x7ce4, 0x7d0f, 0x7d3a, 0x7d63 }, 16, 0x00085388, 1},
++	{{0x7d8a, 0x7db1, 0x7dd6, 0x7dfb, 0x7e1e, 0x7e3f, 0x7e60, 0x7e7f, 0x7e9d, 0x7eba, 0x7ed6, 0x7ef0, 0x7f0a, 0x7f22, 0x7f38, 0x7f4e }, 16, 0x000853a8, 1},
++	{{0x7f62, 0x7f75, 0x7f87, 0x7f98, 0x7fa7, 0x7fb5, 0x7fc2, 0x7fce, 0x7fd9, 0x7fe2, 0x7fea, 0x7ff1, 0x7ff6, 0x7ffa, 0x7ffe, 0x7fff }, 16, 0x000853c8, 1},
++	{{0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c8, 0x00c9, 0x00c9, 0x00c8, 0x00c8, 0x00c9, 0x00c8 }, 16, 0x000853e8, 1},
++	{{0x00c8, 0x00c8, 0x00c8, 0x00c7, 0x00c8, 0x00c7, 0x00c7, 0x00c7, 0x00c7, 0x00c6, 0x00c7, 0x00c6, 0x00c6, 0x00c6, 0x00c5, 0x00c6 }, 16, 0x00085408, 1},
++	{{0x00c5, 0x00c5, 0x00c4, 0x00c5, 0x00c4, 0x00c3, 0x00c4, 0x00c3, 0x00c3, 0x00c2, 0x00c3, 0x00c2, 0x00c1, 0x00c2, 0x00c0, 0x00c1 }, 16, 0x00085428, 1},
++	{{0x00c0, 0x00c0, 0x00c0, 0x00bf, 0x00be, 0x00bf, 0x00be, 0x00bd, 0x00bd, 0x00bd, 0x00bc, 0x00bc, 0x00bb, 0x00bb, 0x00bb, 0x00ba }, 16, 0x00085448, 1},
++	{{0x00b9, 0x00b9, 0x00b9, 0x00b8, 0x00b8, 0x00b7, 0x00b6, 0x00b6, 0x00b6, 0x00b5, 0x00b4, 0x00b4, 0x00b3, 0x00b3, 0x00b2, 0x00b2 }, 16, 0x00085468, 1},
++	{{0x00b1, 0x00b0, 0x00b0, 0x00af, 0x00af, 0x00ae, 0x00ad, 0x00ad, 0x00ac, 0x00ac, 0x00ab, 0x00aa, 0x00a9, 0x00a9, 0x00a8, 0x00a8 }, 16, 0x00085488, 1},
++	{{0x00a7, 0x00a6, 0x00a5, 0x00a5, 0x00a4, 0x00a3, 0x00a3, 0x00a2, 0x00a1, 0x00a0, 0x00a0, 0x009f, 0x009e, 0x009d, 0x009d, 0x009c }, 16, 0x000854a8, 1},
++	{{0x009b, 0x009a, 0x009a, 0x0098, 0x0098, 0x0097, 0x0096, 0x0096, 0x0094, 0x0094, 0x0093, 0x0092, 0x0091, 0x0090, 0x0090, 0x008e }, 16, 0x000854c8, 1},
++	{{0x008e, 0x008d, 0x008c, 0x008b, 0x008a, 0x008a, 0x0088, 0x0087, 0x0087, 0x0086, 0x0084, 0x0084, 0x0083, 0x0082, 0x0081, 0x0080 }, 16, 0x000854e8, 1},
++	{{0x007f, 0x007e, 0x007d, 0x007d, 0x007b, 0x007a, 0x0079, 0x0079, 0x0077, 0x0076, 0x0075, 0x0075, 0x0073, 0x0072, 0x0071, 0x0071 }, 16, 0x00085508, 1},
++	{{0x006f, 0x006e, 0x006d, 0x006c, 0x006b, 0x006a, 0x0069, 0x0068, 0x0067, 0x0066, 0x0064, 0x0064, 0x0063, 0x0061, 0x0060, 0x0060 }, 16, 0x00085528, 1},
++	{{0x005e, 0x005d, 0x005c, 0x005b, 0x005a, 0x0059, 0x0057, 0x0057, 0x0055, 0x0055, 0x0053, 0x0052, 0x0051, 0x0050, 0x004e, 0x004e }, 16, 0x00085548, 1},
++	{{0x004c, 0x004b, 0x004a, 0x0049, 0x0048, 0x0047, 0x0045, 0x0045, 0x0043, 0x0042, 0x0040, 0x0040, 0x003f, 0x003d, 0x003c, 0x003b }, 16, 0x00085568, 1},
++	{{0x003a, 0x0038, 0x0038, 0x0036, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, 0x002e, 0x002d, 0x002b, 0x002b, 0x0029, 0x0027 }, 16, 0x00085588, 1},
++	{{0x0027, 0x0025, 0x0025, 0x0023, 0x0021, 0x0021, 0x001f, 0x001e, 0x001d, 0x001c, 0x001a, 0x001a, 0x0018, 0x0016, 0x0016, 0x0014 }, 16, 0x000855a8, 1},
++	{{0x0013, 0x0012, 0x0011, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x0009, 0x0008, 0x0007, 0x0005, 0x0004, 0x0004, 0x0001, 0x0001 }, 16, 0x000855c8, 1},
++	{{0x000a, 0x349a, 0x000a, 0x32e4, 0x000a, 0x335e, 0x000a, 0x33ac, 0x000a, 0x343a, 0x000a, 0x349a, 0x000a, 0x27fe, 0x000a, 0x27ee }, 16, 0x000855e8, 1},
++	{{0x000a, 0x27f4, 0x0008, 0xf59c, 0x0000, 0x0000, 0x0008, 0xf588, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000, 0x0009, 0x1140 }, 16, 0x00085608, 1},
++	{{0x0009, 0x0f80, 0x0009, 0x1040, 0x0009, 0x1180, 0x0009, 0x10c0, 0x0009, 0x0fc0, 0x0009, 0x1000, 0x0009, 0x1100, 0x0009, 0x0000 }, 16, 0x00085628, 1},
++	{{0x0008, 0xfc00, 0x0009, 0x0400, 0x0009, 0x0a00, 0x0009, 0x0c00, 0x0008, 0xf800, 0x0009, 0x0800, 0x0009, 0x0200, 0x0009, 0x12dc }, 16, 0x00085648, 1},
++	{{0x0009, 0x19bc, 0x0009, 0x18e0, 0x0009, 0x1ee4, 0x0009, 0x1a98, 0x0009, 0x13b8, 0x0009, 0x1e08, 0x0009, 0x2254, 0x0009, 0x1fc0 }, 16, 0x00085668, 1},
++	{{0x0009, 0x1c50, 0x0009, 0x240c, 0x0009, 0x209c, 0x0009, 0x1728, 0x0009, 0x164c, 0x0009, 0x1570, 0x0009, 0x2330, 0x0009, 0x32a5 }, 16, 0x00085688, 1},
++	{{0x0009, 0x3224, 0x0008, 0x5eb7, 0x000a, 0x5300, 0x0009, 0x329f, 0x0009, 0x31af, 0x0009, 0x2e7e, 0x0001, 0xfba6, 0x0009, 0x3296 }, 16, 0x000856a8, 1},
++	{{0x0009, 0x3000, 0x0009, 0x2e51, 0x0001, 0xfbac, 0x0009, 0x3289, 0x0009, 0x3216, 0x0009, 0x2cd6, 0x0001, 0xf858, 0x0009, 0x32a2 }, 16, 0x000856c8, 1},
++	{{0x0009, 0x3199, 0x0009, 0x2dbb, 0x0001, 0xf828, 0x0009, 0x3299, 0x0009, 0x31db, 0x0009, 0x2dee, 0x0001, 0xf82e, 0x0009, 0x3285 }, 16, 0x000856e8, 1},
++	{{0x0009, 0x3154, 0x0009, 0x2d14, 0x0001, 0xf834, 0x0009, 0x3290, 0x0009, 0x2fdf, 0x0009, 0x2eaa, 0x0001, 0xf840, 0x0009, 0x329c }, 16, 0x00085708, 1},
++	{{0x0009, 0x3021, 0x0009, 0x2e51, 0x0001, 0xf846, 0x0009, 0x3279, 0x0009, 0x2f99, 0x0009, 0x2e21, 0x0001, 0xf84c, 0x0009, 0x3265 }, 16, 0x00085728, 1},
++	{{0x0009, 0x3042, 0x0009, 0x2efe, 0x0001, 0xf852, 0x0009, 0x3251, 0x0009, 0x3251, 0x0009, 0x3125, 0x0001, 0xf864, 0x0009, 0x3241 }, 16, 0x00085748, 1},
++	{{0x0009, 0x3241, 0x0009, 0x3080, 0x0001, 0xf85e, 0x0009, 0x3274, 0x0009, 0x3274, 0x0009, 0x309e, 0x000a, 0x53f0, 0x0009, 0x3249 }, 16, 0x00085768, 1},
++	{{0x0009, 0x3249, 0x0009, 0x2f74, 0x000a, 0x5560, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, 0x469c }, 16, 0x00085788, 1},
++	{{0x000a, 0x4708, 0x000a, 0x4b02, 0x000a, 0x4764, 0x000a, 0x4856, 0x000a, 0x481c, 0x000a, 0x43c2, 0x000a, 0x4434, 0x000a, 0x4606 }, 16, 0x000857a8, 1},
++	{{0x000a, 0x44de, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0008, 0x5dc0, 0x0009, 0x28ce, 0x0009, 0x28ce, 0x0000, 0x0000 }, 16, 0x000857c8, 1},
++	{{0x0000, 0x0000, 0x4578, 0x6563, 0x7574, 0x6573, 0x2061, 0x204a, 0x5352, 0x2069, 0x6e73, 0x7472, 0x7563, 0x7469, 0x6f6e, 0x2028 }, 16, 0x000857e8, 1},
++	{{0x6a75, 0x6d70, 0x2074, 0x6f20, 0x7375, 0x6272, 0x6f75, 0x7469, 0x6e65, 0x2061, 0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e29 }, 16, 0x00085808, 1},
++	{{0x2e00, 0x5265, 0x6164, 0x7320, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x206c, 0x6f6e, 0x6720, 0x776f, 0x7264, 0x7320, 0x6f66, 0x2064 }, 16, 0x00085828, 1},
++	{{0x6174, 0x6120, 0x7374, 0x6172, 0x7469, 0x6e67, 0x2061, 0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x7075, 0x7473, 0x2070 }, 16, 0x00085848, 1},
++	{{0x726f, 0x6365, 0x7373, 0x6f72, 0x2074, 0x6f20, 0x736c, 0x6565, 0x702c, 0x2077, 0x7269, 0x7465, 0x2030, 0x7846, 0x4438, 0x3020 }, 16, 0x00085868, 1},
++	{{0x746f, 0x2048, 0x4249, 0x2074, 0x6f20, 0x7761, 0x6b65, 0x2075, 0x7000, 0x5772, 0x6974, 0x6573, 0x2075, 0x7020, 0x746f, 0x2031 }, 16, 0x00085888, 1},
++	{{0x3030, 0x2077, 0x6f72, 0x6428, 0x7329, 0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e, 0x6720, 0x6174, 0x203c }, 16, 0x000858a8, 1},
++	{{0x6164, 0x6472, 0x6573, 0x733e, 0x0052, 0x6561, 0x6473, 0x205b, 0x6c65, 0x6e67, 0x7468, 0x5d20, 0x6279, 0x7465, 0x7320, 0x6f66 }, 16, 0x000858c8, 1},
++	{{0x2064, 0x6174, 0x6120, 0x7374, 0x6172, 0x7469, 0x6e67, 0x2061, 0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x5265, 0x6164 }, 16, 0x000858e8, 1},
++	{{0x7320, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x2077, 0x6f72, 0x6473, 0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e }, 16, 0x00085908, 1},
++	{{0x6720, 0x6174, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x0057, 0x7269, 0x7465, 0x7320, 0x6120, 0x6c77, 0x6f72, 0x6428, 0x7329 }, 16, 0x00085928, 1},
++	{{0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e, 0x6720, 0x6174, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x0057 }, 16, 0x00085948, 1},
++	{{0x7269, 0x7465, 0x7320, 0x776f, 0x7264, 0x2873, 0x2920, 0x6f66, 0x2064, 0x6174, 0x6120, 0x7374, 0x6172, 0x7469, 0x6e67, 0x2061 }, 16, 0x00085968, 1},
++	{{0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x5265, 0x6164, 0x7320, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x2077, 0x6f72, 0x6473 }, 16, 0x00085988, 1},
++	{{0x206f, 0x6620, 0x6461, 0x7461, 0x2066, 0x726f, 0x6d20, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x5772, 0x6974, 0x6573, 0x2062 }, 16, 0x000859a8, 1},
++	{{0x7974, 0x6573, 0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e, 0x6720, 0x6174, 0x203c, 0x6164, 0x6472, 0x6573 }, 16, 0x000859c8, 1},
++	{{0x733e, 0x0077, 0x7220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x3c77, 0x6f72, 0x6430, 0x3e20, 0x5b77, 0x6f72, 0x6431, 0x5d20 }, 16, 0x000859e8, 1},
++	{{0x2e2e, 0x2e5b, 0x776f, 0x7264, 0x3939, 0x5d00, 0x4669, 0x6c6c, 0x7320, 0x6d65, 0x6d6f, 0x7279, 0x2077, 0x6974, 0x6820, 0x6120 }, 16, 0x00085a08, 1},
++	{{0x3332, 0x2d62, 0x6974, 0x2068, 0x6578, 0x2070, 0x6174, 0x7465, 0x726e, 0x2e00, 0x576f, 0x7273, 0x7420, 0x3530, 0x6d73, 0x2069 }, 16, 0x00085a28, 1},
++	{{0x6e74, 0x6572, 0x7661, 0x6c20, 0x2020, 0x2020, 0x3a20, 0x2533, 0x642e, 0x2531, 0x6425, 0x2525, 0x250a, 0x0043, 0x7572, 0x7265 }, 16, 0x00085a48, 1},
++	{{0x6e74, 0x2043, 0x5055, 0x2075, 0x7469, 0x6c69, 0x7a61, 0x7469, 0x6f6e, 0x203a, 0x2025, 0x3364, 0x2e25, 0x3164, 0x2525, 0x2525 }, 16, 0x00085a68, 1},
++	{{0x0a00, 0x4469, 0x7370, 0x6c61, 0x7920, 0x7468, 0x6520, 0x4761, 0x6c69, 0x6c65, 0x6f20, 0x5072, 0x6f66, 0x696c, 0x6572, 0x2043 }, 16, 0x00085a88, 1},
++	{{0x6f75, 0x6e74, 0x732e, 0x0077, 0x6c77, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x203c, 0x6c77, 0x6f72, 0x6430, 0x3e20, 0x5b6c }, 16, 0x00085aa8, 1},
++	{{0x776f, 0x7264, 0x315d, 0x202e, 0x2e2e, 0x0049, 0x646c, 0x6520, 0x6675, 0x6e63, 0x2063, 0x616c, 0x6c20, 0x636f, 0x756e, 0x7420 }, 16, 0x00085ac8, 1},
++	{{0x3a20, 0x2535, 0x642c, 0x2530, 0x2e33, 0x640a, 0x0077, 0x6220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x3c62, 0x7974, 0x6530 }, 16, 0x00085ae8, 1},
++	{{0x3e20, 0x5b62, 0x7974, 0x6531, 0x5d20, 0x2e2e, 0x2e00, 0x7772, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x203c, 0x776f, 0x7264 }, 16, 0x00085b08, 1},
++	{{0x303e, 0x205b, 0x776f, 0x7264, 0x315d, 0x202e, 0x2e2e, 0x0077, 0x7720, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x3c77, 0x6f72 }, 16, 0x00085b28, 1},
++	{{0x6430, 0x3e20, 0x5b77, 0x6f72, 0x6431, 0x5d20, 0x2e2e, 0x2e00, 0x6669, 0x6c6c, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x203c }, 16, 0x00085b48, 1},
++	{{0x6c65, 0x6e3e, 0x203c, 0x7061, 0x7474, 0x6572, 0x6e3e, 0x0052, 0x6561, 0x6420, 0x5379, 0x7374, 0x656d, 0x2049, 0x6e74, 0x6572 }, 16, 0x00085b68, 1},
++	{{0x7275, 0x7074, 0x2052, 0x6567, 0x6973, 0x7465, 0x7200, 0x466f, 0x7263, 0x6520, 0x616e, 0x2069, 0x6c6c, 0x6567, 0x616c, 0x2069 }, 16, 0x00085b88, 1},
++	{{0x6e73, 0x7472, 0x7563, 0x7469, 0x6f6e, 0x2e00, 0x4469, 0x7370, 0x6c61, 0x7920, 0x7468, 0x6520, 0x6370, 0x7520, 0x7574, 0x696c }, 16, 0x00085ba8, 1},
++	{{0x697a, 0x6174, 0x696f, 0x6e2e, 0x0049, 0x646c, 0x6520, 0x7469, 0x636b, 0x7320, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x3a20 }, 16, 0x00085bc8, 1},
++	{{0x2539, 0x640a, 0x0042, 0x7573, 0x7920, 0x7469, 0x636b, 0x7320, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x3a20, 0x2539, 0x640a }, 16, 0x00085be8, 1},
++	{{0x002a, 0x2a2a, 0x2a2a, 0x2049, 0x6e20, 0x3420, 0x7365, 0x636f, 0x6e64, 0x7320, 0x2a2a, 0x2a2a, 0x2a0a, 0x0054, 0x7572, 0x6e20 }, 16, 0x00085c08, 1},
++	{{0x6368, 0x6172, 0x6163, 0x7465, 0x7220, 0x6563, 0x686f, 0x206f, 0x6666, 0x0043, 0x6175, 0x7365, 0x2061, 0x2068, 0x6172, 0x6477 }, 16, 0x00085c28, 1},
++	{{0x6172, 0x6520, 0x7265, 0x626f, 0x6f74, 0x0044, 0x6973, 0x706c, 0x6179, 0x2061, 0x7070, 0x2073, 0x766e, 0x206e, 0x756d, 0x6265 }, 16, 0x00085c48, 1},
++	{{0x7200, 0x726c, 0x7720, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0066, 0x6c43, 0x7220, 0x3c61 }, 16, 0x00085c68, 1},
++	{{0x7070, 0x4e75, 0x6d20, 0x6f70, 0x7469, 0x6f6e, 0x616c, 0x3e00, 0x5475, 0x726e, 0x2063, 0x6861, 0x7261, 0x6374, 0x6572, 0x2065 }, 16, 0x00085c88, 1},
++	{{0x6368, 0x6f20, 0x6f6e, 0x0072, 0x6220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0072, 0x6420 }, 16, 0x00085ca8, 1},
++	{{0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0052, 0x6570, 0x726f, 0x6772, 0x616d, 0x2043, 0x5220 }, 16, 0x00085cc8, 1},
++	{{0x696e, 0x2066, 0x6c61, 0x7368, 0x0072, 0x7720, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0045 }, 16, 0x00085ce8, 1},
++	{{0x7374, 0x2043, 0x5055, 0x2063, 0x6c6f, 0x636b, 0x203a, 0x2025, 0x3964, 0x0a00, 0x5375, 0x7065, 0x7255, 0x7365, 0x7220, 0x4d6f }, 16, 0x00085d08, 1},
++	{{0x6465, 0x0a00, 0x6a73, 0x7220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x3f20, 0x5b63, 0x6f6d, 0x6d61, 0x6e64, 0x5d00, 0x2d2d }, 16, 0x00085d28, 1},
++	{{0x2d2d, 0x2d2d, 0x2d0a, 0x0045, 0x6368, 0x6f4f, 0x6666, 0x0069, 0x6c6c, 0x6567, 0x616c, 0x0067, 0x616c, 0x7072, 0x6f66, 0x0072 }, 16, 0x00085d48, 1},
++	{{0x6562, 0x6f6f, 0x7400, 0x4563, 0x686f, 0x4f6e, 0x0073, 0x6c65, 0x6570, 0x0066, 0x696c, 0x6c00, 0x666c, 0x4372, 0x0072, 0x6453 }, 16, 0x00085d68, 1},
++	{{0x6900, 0x7368, 0x6f77, 0x0077, 0x6c77, 0x0076, 0x6572, 0x0072, 0x6c77, 0x006a, 0x7372, 0x0054, 0x5700, 0x7762, 0x0073, 0x7500 }, 16, 0x00085d88, 1},
++	{{0x7772, 0x0072, 0x7700, 0x7777, 0x0072, 0x6400, 0x7262, 0x003f, 0x0000, 0x0000, 0x0000, 0x0100, 0x0009, 0x32a5, 0x0009, 0x3224 }, 16, 0x00085da8, 1},
++	{{0x0008, 0x5f82, 0x000a, 0x5210, 0x0009, 0x329f, 0x0009, 0x31af, 0x0009, 0x2e7e, 0x0001, 0xfba6, 0x0009, 0x3296, 0x0009, 0x2ed5 }, 16, 0x00085dc8, 1},
++	{{0x0009, 0x2d84, 0x0001, 0xfbac, 0x0009, 0x3281, 0x0009, 0x3281, 0x0009, 0x313d, 0x000a, 0x5090, 0x0009, 0x326a, 0x0009, 0x316b }, 16, 0x00085de8, 1},
++	{{0x0009, 0x31c5, 0x000a, 0x5110, 0x0009, 0x326f, 0x0009, 0x326f, 0x0009, 0x3061, 0x000a, 0x51c0, 0x0009, 0x3239, 0x0009, 0x3239 }, 16, 0x00085e08, 1},
++	{{0x0009, 0x310d, 0x000a, 0x51b0, 0x0009, 0x3258, 0x0009, 0x3258, 0x0009, 0x3182, 0x000a, 0x51a0, 0x0009, 0x325f, 0x0009, 0x325f }, 16, 0x00085e28, 1},
++	{{0x0009, 0x2d4c, 0x000a, 0x5590, 0x0009, 0x3293, 0x0009, 0x32aa, 0x0009, 0x32aa, 0x000a, 0x5580, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00085e48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0a21, 0x2020, 0x5356, 0x4e20, 0x494e, 0x464f, 0x3a0a, 0x2109, 0x5265, 0x7669, 0x7369, 0x6f6e }, 16, 0x00085e68, 1},
++	{{0x3a20, 0x2573, 0x202d, 0x2d20, 0x2573, 0x0a21, 0x0943, 0x6f6d, 0x6d69, 0x7420, 0x5469, 0x6d65, 0x3a20, 0x2573, 0x0a21, 0x0942 }, 16, 0x00085e88, 1},
++	{{0x7569, 0x6c64, 0x2054, 0x696d, 0x653a, 0x2025, 0x730a, 0x0044, 0x6973, 0x706c, 0x6179, 0x7320, 0x636f, 0x6d6d, 0x616e, 0x6420 }, 16, 0x00085ea8, 1},
++	{{0x6c69, 0x7374, 0x2c20, 0x6f72, 0x2069, 0x6e66, 0x6f72, 0x6d61, 0x7469, 0x6f6e, 0x206f, 0x6e20, 0x5b63, 0x6f6d, 0x6d61, 0x6e64 }, 16, 0x00085ec8, 1},
++	{{0x5d00, 0x0a53, 0x7973, 0x7465, 0x6d20, 0x496e, 0x7465, 0x7272, 0x7570, 0x7420, 0x496e, 0x6469, 0x6361, 0x7469, 0x6f6e, 0x2052 }, 16, 0x00085ee8, 1},
++	{{0x6567, 0x6973, 0x7465, 0x723a, 0x000a, 0x5072, 0x6573, 0x7320, 0x4573, 0x6320, 0x746f, 0x2052, 0x6574, 0x7572, 0x6e20, 0x746f }, 16, 0x00085f08, 1},
++	{{0x204e, 0x6f72, 0x6d61, 0x6c20, 0x4d6f, 0x6465, 0x3a0a, 0x0041, 0x7070, 0x6c69, 0x6361, 0x7469, 0x6f6e, 0x2043, 0x6f6d, 0x6d61 }, 16, 0x00085f28, 1},
++	{{0x6e64, 0x2043, 0x6f6e, 0x7465, 0x7874, 0x0a00, 0x4572, 0x726f, 0x723a, 0x2055, 0x6e6b, 0x6e6f, 0x776e, 0x2063, 0x6f6d, 0x6d61 }, 16, 0x00085f48, 1},
++	{{0x6e64, 0x2000, 0x4164, 0x6472, 0x6573, 0x7320, 0x6d75, 0x7374, 0x2062, 0x6520, 0x6865, 0x782e, 0x0a00, 0x4469, 0x7370, 0x6c61 }, 16, 0x00085f68, 1},
++	{{0x7973, 0x2063, 0x6f6d, 0x6d61, 0x6e64, 0x206c, 0x6973, 0x7400, 0x0a20, 0x7377, 0x5265, 0x6741, 0x7070, 0x5265, 0x7643, 0x6f64 }, 16, 0x00085f88, 1},
++	{{0x6520, 0x3d20, 0x004e, 0x6f20, 0x666c, 0x6173, 0x6820, 0x7072, 0x6573, 0x656e, 0x742e, 0x0a00, 0x4261, 0x6420, 0x496d, 0x6167 }, 16, 0x00085fa8, 1},
++	{{0x6520, 0x4e75, 0x6d62, 0x6572, 0x2e0a, 0x000a, 0x2050, 0x726f, 0x6475, 0x6374, 0x2049, 0x4420, 0x3d20, 0x5a4c, 0x5300, 0x4e6f }, 16, 0x00085fc8, 1},
++	{{0x7420, 0x706f, 0x7373, 0x6962, 0x6c65, 0x2025, 0x640a, 0x2000, 0x4e6f, 0x7420, 0x706f, 0x7373, 0x6962, 0x6c65, 0x2025, 0x640a }, 16, 0x00085fe8, 1},
++	{{0x2000, 0x5573, 0x6167, 0x653a, 0x0a20, 0x2573, 0x0a0a, 0x2573, 0x0a0a, 0x0045, 0x6e74, 0x7279, 0x2054, 0x6f6f, 0x204c, 0x6f6e }, 16, 0x00086008, 1},
++	{{0x670a, 0x2000, 0x5573, 0x6167, 0x653a, 0x0a20, 0x2573, 0x0a0a, 0x2573, 0x0a0a, 0x000a, 0x436f, 0x6d6d, 0x616e, 0x6473, 0x3a0a }, 16, 0x00086028, 1},
++	{{0x000a, 0x436f, 0x6d6d, 0x616e, 0x6473, 0x3a0a, 0x004c, 0x454e, 0x2025, 0x3478, 0x0a20, 0x0020, 0x2534, 0x7820, 0x2534, 0x780a }, 16, 0x00086048, 1},
++	{{0x0045, 0x6368, 0x6f4f, 0x6666, 0x0a00, 0x2225, 0x7322, 0x200a, 0x0020, 0x2573, 0x0a00, 0x2025, 0x730a, 0x0025, 0x733e, 0x2000 }, 16, 0x00086068, 1},
++	{{0x0820, 0x080a, 0x2000, 0x200a, 0x0000, 0x0000, 0x000a, 0x5c7c, 0x000a, 0x5c8e, 0x000a, 0x5ce2, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086088, 1},
++	{{0x7fff, 0xffff, 0x7fff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000860a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0600, 0x0009, 0x3474, 0x0008, 0xe118, 0x0008, 0xe058, 0x0008, 0xded8 }, 16, 0x000860c8, 1},
++	{{0x0008, 0xdf98, 0x0008, 0xc1c0, 0x0008, 0xc040, 0x0008, 0xbe00, 0x0008, 0xbf80, 0x0008, 0xd41c, 0x0008, 0xd7dc, 0x0008, 0xd11c }, 16, 0x000860e8, 1},
++	{{0x0008, 0xd1dc, 0x0009, 0x8b20, 0x0009, 0x89a0, 0x0009, 0xc124, 0x0009, 0xc1fc, 0x0009, 0x33b4, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086108, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086128, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086148, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086168, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086188, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000861a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000861c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000861e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086208, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086228, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086248, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086268, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0076, 0xfefb, 0x003b, 0x0160 }, 16, 0x00086288, 1},
++	{{0x006e, 0x0350, 0xfa43, 0x023a, 0xf8ba, 0x0736, 0x0998, 0xf256, 0x068e, 0xd4e8, 0x1eba, 0x086a, 0x3fd2, 0xd002, 0xdc63, 0x1929 }, 16, 0x000862a8, 1},
++	{{0x3fd3, 0x2ff3, 0xdda3, 0xe4d4, 0x068d, 0x2b2b, 0x1e60, 0xfafa, 0xf8ba, 0xf8c3, 0x093d, 0x0c53, 0x006e, 0xfcad, 0xfaa6, 0xfd68 }, 16, 0x000862c8, 1},
++	{{0x0076, 0x010f, 0x0054, 0xffd8, 0x0003, 0xfff1, 0x00b5, 0xfee7, 0xfe50, 0x00a6, 0x00ba, 0xff81, 0x04e4, 0xffab, 0xf301, 0x0320 }, 16, 0x000862e8, 1},
++	{{0x0553, 0xfbdb, 0x0d96, 0x0000, 0xf09c, 0x0425, 0x02a1, 0xfce0, 0x033d, 0x0055, 0xfe3d, 0x007f, 0x018c, 0xff5a, 0x0001, 0x0000 }, 16, 0x00086308, 1},
++	{{0xffff, 0xfff8, 0xfff4, 0xfff0, 0xffee, 0xfff0, 0xfff7, 0x0005, 0x0018, 0x002e, 0x0043, 0x0051, 0x0054, 0x0049, 0x002f, 0x000a }, 16, 0x00086328, 1},
++	{{0xffde, 0xffb6, 0xff9b, 0xff96, 0xffaa, 0xffd8, 0x0017, 0x005c, 0x0095, 0x00b4, 0x00ac, 0x0079, 0x0023, 0xffb7, 0xff4f, 0xff03 }, 16, 0x00086348, 1},
++	{{0xfeea, 0xff11, 0xff78, 0x000d, 0x00b2, 0x0141, 0x0194, 0x018f, 0x0129, 0x006e, 0xff83, 0xfe9a, 0xfded, 0xfdad, 0xfdf6, 0xfec6 }, 16, 0x00086368, 1},
++	{{0xfff9, 0x0151, 0x027d, 0x0330, 0x0330, 0x026a, 0x00f8, 0xff22, 0xfd4f, 0xfbf1, 0xfb6a, 0xfbf1, 0xfd85, 0xffde, 0x0282, 0x04d3 }, 16, 0x00086388, 1},
++	{{0x0639, 0x0642, 0x04c5, 0x01f2, 0xfe53, 0xfaaf, 0xf7ea, 0xf6ca, 0xf7ca, 0xfaf0, 0xffbf, 0x0545, 0x0a44, 0x0d72, 0x0dc2, 0x0ab0 }, 16, 0x000863a8, 1},
++	{{0x046a, 0xfbe7, 0xf2c8, 0xeb22, 0xe71a, 0xe880, 0xf06c, 0xfef5, 0x1316, 0x2ac2, 0x4329, 0x5928, 0x69c8, 0x72b9, 0x72b9, 0x69c8 }, 16, 0x000863c8, 1},
++	{{0x5928, 0x4329, 0x2ac2, 0x1316, 0xfef5, 0xf06c, 0xe880, 0xe71a, 0xeb22, 0xf2c8, 0xfbe7, 0x046a, 0x0ab0, 0x0dc2, 0x0d72, 0x0a44 }, 16, 0x000863e8, 1},
++	{{0x0545, 0xffbf, 0xfaf0, 0xf7ca, 0xf6ca, 0xf7ea, 0xfaaf, 0xfe53, 0x01f2, 0x04c5, 0x0642, 0x0639, 0x04d3, 0x0282, 0xffde, 0xfd85 }, 16, 0x00086408, 1},
++	{{0xfbf1, 0xfb6a, 0xfbf1, 0xfd4f, 0xff22, 0x00f8, 0x026a, 0x0330, 0x0330, 0x027d, 0x0151, 0xfff9, 0xfec6, 0xfdf6, 0xfdad, 0xfded }, 16, 0x00086428, 1},
++	{{0xfe9a, 0xff83, 0x006e, 0x0129, 0x018f, 0x0194, 0x0141, 0x00b2, 0x000d, 0xff78, 0xff11, 0xfeea, 0xff03, 0xff4f, 0xffb7, 0x0023 }, 16, 0x00086448, 1},
++	{{0x0079, 0x00ac, 0x00b4, 0x0095, 0x005c, 0x0017, 0xffd8, 0xffaa, 0xff96, 0xff9b, 0xffb6, 0xffde, 0x000a, 0x002f, 0x0049, 0x0054 }, 16, 0x00086468, 1},
++	{{0x0051, 0x0043, 0x002e, 0x0018, 0x0005, 0xfff7, 0xfff0, 0xffee, 0xfff0, 0xfff4, 0xfff8, 0xffff, 0x0000, 0x0001, 0xffed, 0xffe1 }, 16, 0x00086488, 1},
++	{{0xffce, 0xffb9, 0xffa5, 0xff96, 0xff92, 0xff9a, 0xffb2, 0xffd7, 0x0005, 0x0035, 0x005e, 0x0078, 0x007c, 0x0068, 0x003e, 0x0005 }, 16, 0x000864a8, 1},
++	{{0xffca, 0xff98, 0xff7e, 0xff84, 0xffaa, 0xffed, 0x003f, 0x008e, 0x00c6, 0x00d9, 0x00be, 0x0075, 0x000d, 0xff9a, 0xff36, 0xfefd }, 16, 0x000864c8, 1},
++	{{0xfefe, 0xff40, 0xffb9, 0x0052, 0x00e9, 0x015a, 0x0185, 0x015a, 0x00db, 0x001e, 0xff4b, 0xfe93, 0xfe24, 0xfe20, 0xfe92, 0xff68 }, 16, 0x000864e8, 1},
++	{{0x0079, 0x0189, 0x0254, 0x02a6, 0x025e, 0x0180, 0x0033, 0xfebf, 0xfd78, 0xfcb2, 0xfca8, 0xfd6f, 0xfeea, 0x00ce, 0x02b1, 0x041e }, 16, 0x00086508, 1},
++	{{0x04b1, 0x0432, 0x02a3, 0x0048, 0xfd9f, 0xfb43, 0xf9cf, 0xf9b7, 0xfb29, 0xfdfb, 0x01a8, 0x0569, 0x0858, 0x09a1, 0x08b7, 0x057c }, 16, 0x00086528, 1},
++	{{0x0057, 0xfa31, 0xf456, 0xf03e, 0xef49, 0xf279, 0xfa35, 0x062b, 0x1549, 0x25e1, 0x35e5, 0x4339, 0x4c0c, 0x4f21, 0x4c0c, 0x4339 }, 16, 0x00086548, 1},
++	{{0x35e5, 0x25e1, 0x1549, 0x062b, 0xfa35, 0xf279, 0xef49, 0xf03e, 0xf456, 0xfa31, 0x0057, 0x057c, 0x08b7, 0x09a1, 0x0858, 0x0569 }, 16, 0x00086568, 1},
++	{{0x01a8, 0xfdfb, 0xfb29, 0xf9b7, 0xf9cf, 0xfb43, 0xfd9f, 0x0048, 0x02a3, 0x0432, 0x04b1, 0x041e, 0x02b1, 0x00ce, 0xfeea, 0xfd6f }, 16, 0x00086588, 1},
++	{{0xfca8, 0xfcb2, 0xfd78, 0xfebf, 0x0033, 0x0180, 0x025e, 0x02a6, 0x0254, 0x0189, 0x0079, 0xff68, 0xfe92, 0xfe20, 0xfe24, 0xfe93 }, 16, 0x000865a8, 1},
++	{{0xff4b, 0x001e, 0x00db, 0x015a, 0x0185, 0x015a, 0x00e9, 0x0052, 0xffb9, 0xff40, 0xfefe, 0xfefd, 0xff36, 0xff9a, 0x000d, 0x0075 }, 16, 0x000865c8, 1},
++	{{0x00be, 0x00d9, 0x00c6, 0x008e, 0x003f, 0xffed, 0xffaa, 0xff84, 0xff7e, 0xff98, 0xffca, 0x0005, 0x003e, 0x0068, 0x007c, 0x0078 }, 16, 0x000865e8, 1},
++	{{0x005e, 0x0035, 0x0005, 0xffd7, 0xffb2, 0xff9a, 0xff92, 0xff96, 0xffa5, 0xffb9, 0xffce, 0xffe1, 0xffed, 0x0000, 0xff64, 0xe39e }, 16, 0x00086608, 1},
++	{{0xcadd, 0xb4ce, 0xa124, 0x8f9e, 0x8000, 0x7214, 0x65ac, 0x5a9d, 0x50c3, 0x47fa, 0x4026, 0x392c, 0x32f5, 0x2d6a, 0x287a, 0x2413 }, 16, 0x00086628, 1},
++	{{0x2026, 0x1ca7, 0x198a, 0x16c3, 0x1449, 0x1214, 0x101d, 0x0e5c, 0x0ccc, 0x0b68, 0x0a2a, 0x090f, 0x0813, 0x0732, 0x066a, 0x05b7 }, 16, 0x00086648, 1},
++	{{0x0518, 0x048a, 0x040c, 0x039b, 0x0337, 0x02dd, 0x028d, 0x0246, 0x0207, 0x01ce, 0x019c, 0x016f, 0x0147, 0x0124, 0x0104, 0x00e7 }, 16, 0x00086668, 1},
++	{{0x00ce, 0x00b8, 0x00a4, 0x0092, 0x0082, 0x0074, 0x0067, 0x005c, 0x0052, 0x0049, 0x0041, 0x003a, 0x0033, 0x002e, 0x0029, 0x0024 }, 16, 0x00086688, 1},
++	{{0x0020, 0x001d, 0x001a, 0x0017, 0x0014, 0x0012, 0x0010, 0x000e, 0x000d, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007, 0x0006, 0x0005 }, 16, 0x000866a8, 1},
++	{{0x0005, 0x0004, 0x0004, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0xffef }, 16, 0x000866c8, 1},
++	{{0xffc8, 0xff9d, 0xff85, 0xffa3, 0xfff4, 0x004d, 0x006c, 0x002e, 0xffba, 0xff6f, 0xff9b, 0x0031, 0x00b9, 0x00b1, 0x0000, 0xff29 }, 16, 0x000866e8, 1},
++	{{0xfef1, 0xffad, 0x00de, 0x017a, 0x00d0, 0xff40, 0xfe19, 0xfe86, 0x006e, 0x024a, 0x0254, 0x002a, 0xfd6e, 0xfc9e, 0xfee0, 0x02a8 }, 16, 0x00086708, 1},
++	{{0x04a9, 0x029a, 0xfd96, 0xf9c6, 0xfb20, 0x019f, 0x084f, 0x08af, 0x004f, 0xf44e, 0xef41, 0xfa2c, 0x1540, 0x35dd, 0x4c04, 0x4c04 }, 16, 0x00086728, 1},
++	{{0x35dd, 0x1540, 0xfa2c, 0xef41, 0xf44e, 0x004f, 0x08af, 0x084f, 0x019f, 0xfb20, 0xf9c6, 0xfd96, 0x029a, 0x04a9, 0x02a8, 0xfee0 }, 16, 0x00086748, 1},
++	{{0xfc9e, 0xfd6e, 0x002a, 0x0254, 0x024a, 0x006e, 0xfe86, 0xfe19, 0xff40, 0x00d0, 0x017a, 0x00de, 0xffad, 0xfef1, 0xff29, 0x0000 }, 16, 0x00086768, 1},
++	{{0x00b1, 0x00b9, 0x0031, 0xff9b, 0xff6f, 0xffba, 0x002e, 0x006c, 0x004d, 0xfff4, 0xffa3, 0xff85, 0xff9d, 0xffc8, 0xffef, 0xffef }, 16, 0x00086788, 1},
++	{{0xffbe, 0xff84, 0xff5d, 0xff7c, 0xffe4, 0x0060, 0x0096, 0x004c, 0xffad, 0xff39, 0xff66, 0x0030, 0x00fb, 0x0106, 0x001a, 0xfee2 }, 16, 0x000867a8, 1},
++	{{0xfe76, 0xff6b, 0x0120, 0x021d, 0x0149, 0xff12, 0xfd4c, 0xfdc1, 0x0071, 0x033a, 0x0377, 0x0071, 0xfc69, 0xfb08, 0xfe25, 0x03ac }, 16, 0x000867c8, 1},
++	{{0x06cb, 0x0402, 0xfcb7, 0xf6f4, 0xf8b0, 0x0219, 0x0c0a, 0x0cdb, 0x00be, 0xef0b, 0xe75e, 0xf72d, 0x1eec, 0x4efc, 0x6fb0, 0x6fb0 }, 16, 0x000867e8, 1},
++	{{0x4efc, 0x1eec, 0xf72d, 0xe75e, 0xef0b, 0x00be, 0x0cdb, 0x0c0a, 0x0219, 0xf8b0, 0xf6f4, 0xfcb7, 0x0402, 0x06cb, 0x03ac, 0xfe25 }, 16, 0x00086808, 1},
++	{{0xfb08, 0xfc69, 0x0071, 0x0377, 0x033a, 0x0071, 0xfdc1, 0xfd4c, 0xff12, 0x0149, 0x021d, 0x0120, 0xff6b, 0xfe76, 0xfee2, 0x001a }, 16, 0x00086828, 1},
++	{{0x0106, 0x00fb, 0x0030, 0xff66, 0xff39, 0xffad, 0x004c, 0x0096, 0x0060, 0xffe4, 0xff7c, 0xff5d, 0xff84, 0xffbe, 0xffef, 0xffda }, 16, 0x00086848, 1},
++	{{0xff78, 0xff4b, 0xffcc, 0x008c, 0x0067, 0xff6f, 0xff46, 0x0087, 0x0126, 0xffa8, 0xfe5c, 0xfff4, 0x0225, 0x00b1, 0xfd66, 0xfe5c }, 16, 0x00086868, 1},
++	{{0x02e9, 0x02f0, 0xfd08, 0xfb5d, 0x029d, 0x06d2, 0xfe5f, 0xf64e, 0xff95, 0x0dcd, 0x049b, 0xeaeb, 0xf09d, 0x2c3c, 0x6c63, 0x6c63 }, 16, 0x00086888, 1},
++	{{0x2c3c, 0xf09d, 0xeaeb, 0x049b, 0x0dcd, 0xff95, 0xf64e, 0xfe5f, 0x06d2, 0x029d, 0xfb5d, 0xfd08, 0x02f0, 0x02e9, 0xfe5c, 0xfd66 }, 16, 0x000868a8, 1},
++	{{0x00b1, 0x0225, 0xfff4, 0xfe5c, 0xffa8, 0x0126, 0x0087, 0xff46, 0xff6f, 0x0067, 0x008c, 0xffcc, 0xff4b, 0xff78, 0xffda, 0x0080 }, 16, 0x000868c8, 1},
++	{{0xfe65, 0xff40, 0x00b3, 0x0135, 0x00f4, 0x0024, 0xff43, 0xfeb5, 0xfed5, 0xff9f, 0x00be, 0x019f, 0x01b8, 0x00d8, 0xff53, 0xfde8 }, 16, 0x000868e8, 1},
++	{{0xfd6e, 0xfe5a, 0x006e, 0x02b8, 0x03f2, 0x0326, 0x0042, 0xfc5b, 0xf95e, 0xf957, 0xfd82, 0x0599, 0x0fc2, 0x1911, 0x1e9f, 0x1e9f }, 16, 0x00086908, 1},
++	{{0x1911, 0x0fc2, 0x0599, 0xfd82, 0xf957, 0xf95e, 0xfc5b, 0x0042, 0x0326, 0x03f2, 0x02b8, 0x006e, 0xfe5a, 0xfd6e, 0xfde8, 0xff53 }, 16, 0x00086928, 1},
++	{{0x00d8, 0x01b8, 0x019f, 0x00be, 0xff9f, 0xfed5, 0xfeb5, 0xff43, 0x0024, 0x00f4, 0x0135, 0x00b3, 0xff40, 0xfe65, 0x0080, 0xfffe }, 16, 0x00086948, 1},
++	{{0x0019, 0xffea, 0xffe3, 0x001b, 0x0037, 0xffde, 0xffa0, 0x001f, 0x009a, 0xfff8, 0xff1c, 0xffd3, 0x013a, 0x0090, 0xfe71, 0xfed0 }, 16, 0x00086968, 1},
++	{{0x01d2, 0x021a, 0xfe1a, 0xfca4, 0x01a4, 0x0507, 0xff31, 0xf8cd, 0xfef9, 0x0a1d, 0x04f4, 0xf19e, 0xf0fe, 0x152b, 0x3e82, 0x3e82 }, 16, 0x00086988, 1},
++	{{0x152b, 0xf0fe, 0xf19e, 0x04f4, 0x0a1d, 0xfef9, 0xf8cd, 0xff31, 0x0507, 0x01a4, 0xfca4, 0xfe1a, 0x021a, 0x01d2, 0xfed0, 0xfe71 }, 16, 0x000869a8, 1},
++	{{0x0090, 0x013a, 0xffd3, 0xff1c, 0xfff8, 0x009a, 0x001f, 0xffa0, 0xffde, 0x0037, 0x001b, 0xffe3, 0xffea, 0x0019, 0xfffe, 0x0000 }, 16, 0x000869c8, 1},
++	{{0x0000, 0x0000, 0x0400, 0x04c1, 0x05a6, 0x06b7, 0x0008, 0x0000, 0x0400, 0x042d, 0x045c, 0x048d, 0x04c1, 0x04f7, 0x0531, 0x0569 }, 16, 0x000869e8, 1},
++	{{0x7fff, 0xa000, 0x7fff, 0xa100, 0x7fff, 0xa200, 0x0200, 0x0000, 0x0400, 0x0000, 0x0800, 0x0000, 0x1c1d, 0x1e34, 0x3638, 0x0000 }, 16, 0x00086a08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4000, 0x2aab, 0x2000, 0x199a, 0x1555, 0x1249, 0x1000, 0x0e39, 0x0ccd, 0x0ba3, 0x0aab }, 16, 0x00086a28, 1},
++	{{0x09d9, 0x0925, 0x0889, 0x0800, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002 }, 16, 0x00086a48, 1},
++	{{0x0000, 0x0002, 0x0000, 0x0003, 0x0000, 0x0003, 0x0000, 0x0003, 0x0000, 0x0004, 0x0000, 0x0004, 0x0000, 0x0005, 0x0000, 0x0006 }, 16, 0x00086a68, 1},
++	{{0x0000, 0x0007, 0x0000, 0x0007, 0x0000, 0x0008, 0x0000, 0x0009, 0x0000, 0x000b, 0x0000, 0x000c, 0x0000, 0x000f, 0x0000, 0x0012 }, 16, 0x00086a88, 1},
++	{{0x0022, 0x1140, 0x7fff, 0x2bcc, 0x061d, 0x00ac, 0x0011, 0x0001, 0x0ccd, 0x3333, 0x7fff, 0x3333, 0x0ccd, 0x0000, 0x000a, 0xa8ae }, 16, 0x00086aa8, 1},
++	{{0x000a, 0xa8ae, 0x000a, 0x8d42, 0x000a, 0xa67c, 0x000a, 0xa68c, 0x000a, 0x99ba, 0x000a, 0x9922, 0x000a, 0x98e6, 0x0000, 0x0000 }, 16, 0x00086ac8, 1},
++	{{0x0005, 0x0014, 0x002c, 0x004f, 0x007b, 0x00b1, 0x00f1, 0x013b, 0x018e, 0x01eb, 0x0251, 0x02c1, 0x033b, 0x03be, 0x044a, 0x04df }, 16, 0x00086ae8, 1},
++	{{0x057e, 0x0625, 0x06d5, 0x078f, 0x0850, 0x091b, 0x09ee, 0x0ac9, 0x0bad, 0x0c98, 0x0d8c, 0x0e87, 0x0f8a, 0x1094, 0x11a6, 0x12bf }, 16, 0x00086b08, 1},
++	{{0x13de, 0x1505, 0x1632, 0x1766, 0x18a0, 0x19e0, 0x1b26, 0x1c71, 0x1dc2, 0x1f19, 0x2074, 0x21d5, 0x2339, 0x24a3, 0x2610, 0x2782 }, 16, 0x00086b28, 1},
++	{{0x28f7, 0x2a70, 0x2bec, 0x2d6c, 0x2eee, 0x3073, 0x31fa, 0x3383, 0x350f, 0x369c, 0x382a, 0x39ba, 0x3b4a, 0x3cdc, 0x3e6e, 0x4000 }, 16, 0x00086b48, 1},
++	{{0x4192, 0x4324, 0x44b5, 0x4646, 0x47d5, 0x4964, 0x4af1, 0x4c7c, 0x4e05, 0x4f8d, 0x5112, 0x5294, 0x5413, 0x558f, 0x5708, 0x587e }, 16, 0x00086b68, 1},
++	{{0x59ef, 0x5b5d, 0x5cc6, 0x5e2b, 0x5f8b, 0x60e7, 0x623d, 0x638e, 0x64da, 0x6620, 0x6760, 0x6899, 0x69cd, 0x6afa, 0x6c21, 0x6d41 }, 16, 0x00086b88, 1},
++	{{0x6e5a, 0x6f6b, 0x7076, 0x7179, 0x7274, 0x7367, 0x7453, 0x7536, 0x7612, 0x76e5, 0x77af, 0x7871, 0x792a, 0x79da, 0x7a82, 0x7b20 }, 16, 0x00086ba8, 1},
++	{{0x7bb6, 0x7c42, 0x7cc5, 0x7d3e, 0x7dae, 0x7e14, 0x7e71, 0x7ec5, 0x7f0e, 0x7f4e, 0x7f84, 0x7fb1, 0x7fd3, 0x7fec, 0x7ffb, 0x7fff }, 16, 0x00086bc8, 1},
++	{{0x7ffb, 0x7fec, 0x7fd3, 0x7fb1, 0x7f84, 0x7f4e, 0x7f0e, 0x7ec5, 0x7e71, 0x7e14, 0x7dae, 0x7d3e, 0x7cc5, 0x7c42, 0x7bb6, 0x7b20 }, 16, 0x00086be8, 1},
++	{{0x7a82, 0x79da, 0x792a, 0x7871, 0x77af, 0x76e5, 0x7612, 0x7536, 0x7453, 0x7367, 0x7274, 0x7179, 0x7076, 0x6f6b, 0x6e5a, 0x6d41 }, 16, 0x00086c08, 1},
++	{{0x6c21, 0x6afa, 0x69cd, 0x6899, 0x6760, 0x6620, 0x64da, 0x638e, 0x623d, 0x60e7, 0x5f8b, 0x5e2b, 0x5cc6, 0x5b5d, 0x59ef, 0x587e }, 16, 0x00086c28, 1},
++	{{0x5708, 0x558f, 0x5413, 0x5294, 0x5112, 0x4f8d, 0x4e05, 0x4c7c, 0x4af1, 0x4964, 0x47d5, 0x4646, 0x44b5, 0x4324, 0x4192, 0x4000 }, 16, 0x00086c48, 1},
++	{{0x3e6e, 0x3cdc, 0x3b4a, 0x39ba, 0x382a, 0x369c, 0x350f, 0x3383, 0x31fa, 0x3073, 0x2eee, 0x2d6c, 0x2bec, 0x2a70, 0x28f7, 0x2782 }, 16, 0x00086c68, 1},
++	{{0x2610, 0x24a3, 0x2339, 0x21d5, 0x2074, 0x1f19, 0x1dc2, 0x1c71, 0x1b26, 0x19e0, 0x18a0, 0x1766, 0x1632, 0x1505, 0x13de, 0x12bf }, 16, 0x00086c88, 1},
++	{{0x11a6, 0x1094, 0x0f8a, 0x0e87, 0x0d8c, 0x0c98, 0x0bad, 0x0ac9, 0x09ee, 0x091b, 0x0850, 0x078f, 0x06d5, 0x0625, 0x057e, 0x04df }, 16, 0x00086ca8, 1},
++	{{0x044a, 0x03be, 0x033b, 0x02c1, 0x0251, 0x01eb, 0x018e, 0x013b, 0x00f1, 0x00b1, 0x007b, 0x004f, 0x002c, 0x0014, 0x0005, 0x0000 }, 16, 0x00086cc8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x4474, 0x7fff, 0x042a, 0x015b, 0x00b1, 0x006b, 0x0046, 0x0030, 0x0021, 0x0017, 0x0010 }, 16, 0x00086ce8, 1},
++	{{0x000d, 0x000b, 0x0008, 0x0005, 0x0004, 0x0004, 0x0006, 0x000c, 0x0029, 0x0047, 0x0058, 0x0077, 0x60a9, 0x44e1, 0x38ac, 0x3175 }, 16, 0x00086d08, 1},
++	{{0x2c92, 0x28fe, 0x263c, 0x2408, 0x2238, 0x20b3, 0x1f67, 0x1e48, 0x1d4d, 0x1c6f, 0x1baa, 0x1af8, 0x1a59, 0x19c8, 0x1943, 0x18ca }, 16, 0x00086d28, 1},
++	{{0x185b, 0x17f4, 0x1795, 0x173c, 0x16ea, 0x169e, 0x1656, 0x1613, 0x15d4, 0x1598, 0x1560, 0x152b, 0x152b, 0x12f8, 0x11db, 0x1137 }, 16, 0x00086d48, 1},
++	{{0x10d2, 0x1091, 0x1066, 0x1048, 0x1033, 0x1025, 0x101b, 0x0000, 0x0000, 0x0000, 0x0009, 0x82ac, 0x0009, 0x82c4, 0x0009, 0x82a0 }, 16, 0x00086d68, 1},
++	{{0x0009, 0x82b8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0020, 0x0010, 0x0000, 0x0013, 0x4000, 0x0a00, 0x4001 }, 16, 0x00086d88, 1},
++	{{0x0320, 0x0000, 0x0000, 0x0000, 0x0026, 0x1a00, 0x0800, 0x0400, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0280, 0x2008 }, 16, 0x00086da8, 1},
++	{{0x0002, 0x01f0, 0x0078, 0x0032, 0x0004, 0x01f0, 0x0078, 0x0032, 0x000f, 0x5004, 0x0004, 0x0000, 0x01aa, 0x0000, 0x7800, 0x000f }, 16, 0x00086dc8, 1},
++	{{0x003c, 0x4801, 0x08a1, 0x0040, 0x8230, 0x001f, 0x7801, 0x000f, 0x003c, 0x2801, 0x08a1, 0x0040, 0xa000, 0x001f, 0x0080, 0x0002 }, 16, 0x00086de8, 1},
++	{{0x0064, 0x000f, 0x3333, 0x7fbe, 0x3333, 0x7eb8, 0x7fff, 0x0001, 0x7fdf, 0x0002, 0x7333, 0x7333, 0x0019, 0x0001, 0x6666, 0x0001 }, 16, 0x00086e08, 1},
++	{{0x6666, 0x0400, 0x4026, 0x7213, 0x0080, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6000, 0x0000, 0x4000, 0x0000, 0x0000 }, 16, 0x00086e28, 1},
++	{{0x880c, 0xa008, 0x0109, 0x7593, 0x7f00, 0x0000, 0x7fff, 0x0000, 0x0000, 0x087a, 0x0006, 0x0096, 0x0002, 0x0a1f, 0x3040, 0x0000 }, 16, 0x00086e48, 1},
++	{{0x7800, 0x0ccc, 0x0000, 0x0000, 0x0340, 0x0000, 0x0000, 0x1410, 0x0000, 0x0010, 0x0000, 0x0600, 0x3344, 0x1122, 0x0000, 0x0000 }, 16, 0x00086e68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0005, 0x0000, 0x0600, 0x0200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086e88, 1},
++	{{0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086ea8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086ec8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086ee8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086fa8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086fc8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086fe8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087008, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087028, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087048, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087068, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087088, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000870a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000870c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000870e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087108, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087128, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087148, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087168, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087188, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000871a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000871c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000871e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087208, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087228, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087248, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087268, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087288, 1},
++	{{0x0000, 0x0000, 0x0400, 0x0320, 0x0033, 0x0000, 0x0b27, 0x1358, 0x0c52, 0x1560, 0x0da2, 0x17a2, 0x0f0e, 0x1a21, 0x123d, 0x170a }, 16, 0x000872a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0190, 0x0190, 0x0009, 0xbbc8, 0x8000, 0x5a82, 0x49e7, 0x4000, 0x393e, 0x3441 }, 16, 0x000872c8, 1},
++	{{0x3061, 0x2d41, 0x2aab, 0x287a, 0x2698, 0x24f3, 0x2380, 0x2236, 0x210d, 0x2000, 0x7fff, 0xffff, 0x2311, 0x8963, 0x0000, 0x0001 }, 16, 0x000872e8, 1},
++	{{0x9678, 0x5429, 0x0010, 0x0000, 0x7fff, 0x4000, 0x2aab, 0x2000, 0x199a, 0x1555, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087308, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0xffea, 0xffea, 0x006a, 0x0018, 0xfec8, 0x0040, 0x02d4, 0xfe5c, 0xf9b6 }, 16, 0x00087328, 1},
++	{{0x076e, 0x1e48, 0x1e48, 0x076e, 0xf9b6, 0xfe5c, 0x02d4, 0x0040, 0xfec8, 0x0018, 0x006a, 0xffea, 0xffea, 0x0006, 0x000b, 0x0630 }, 16, 0x00087348, 1},
++	{{0x000b, 0x0630, 0x000b, 0x0668, 0x000b, 0x06b4, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 }, 16, 0x00087368, 1},
++	{{0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 }, 16, 0x00087388, 1},
++	{{0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003 }, 16, 0x000873a8, 1},
++	{{0x0003, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005 }, 16, 0x000873c8, 1},
++	{{0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0008, 0x0008, 0x0008, 0x0008 }, 16, 0x000873e8, 1},
++	{{0x0008, 0x0009, 0x0009, 0x0009, 0x0009, 0x000a, 0x000a, 0x000a, 0x000a, 0x000b, 0x000b, 0x000b, 0x000b, 0x000c, 0x000c, 0x000c }, 16, 0x00087408, 1},
++	{{0x000d, 0x000d, 0x000d, 0x000d, 0x000e, 0x000e, 0x000f, 0x000f, 0x000f, 0x0010, 0x0010, 0x0010, 0x0011, 0x0011, 0x0012, 0x0012 }, 16, 0x00087428, 1},
++	{{0x0012, 0x0013, 0x0013, 0x0014, 0x0014, 0x0015, 0x0015, 0x0016, 0x0016, 0x0017, 0x0017, 0x0018, 0x0018, 0x0019, 0x0019, 0x001a }, 16, 0x00087448, 1},
++	{{0x001b, 0x001b, 0x001c, 0x001c, 0x001d, 0x001e, 0x001f, 0x001f, 0x0020, 0x0021, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0025 }, 16, 0x00087468, 1},
++	{{0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0036 }, 16, 0x00087488, 1},
++	{{0x0037, 0x0038, 0x0039, 0x003a, 0x003c, 0x003d, 0x003f, 0x0040, 0x0041, 0x0043, 0x0044, 0x0046, 0x0047, 0x0049, 0x004b, 0x004c }, 16, 0x000874a8, 1},
++	{{0x004e, 0x0050, 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005d, 0x005f, 0x0061, 0x0063, 0x0066, 0x0068, 0x006a, 0x006d }, 16, 0x000874c8, 1},
++	{{0x006f, 0x0071, 0x0074, 0x0076, 0x0079, 0x007c, 0x007f, 0x0081, 0x0084, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, 0x0097, 0x009a }, 16, 0x000874e8, 1},
++	{{0x009d, 0x00a1, 0x00a5, 0x00a8, 0x00ac, 0x00b0, 0x00b4, 0x00b8, 0x00bc, 0x00c0, 0x00c4, 0x00c8, 0x00cd, 0x00d1, 0x00d6, 0x00db }, 16, 0x00087508, 1},
++	{{0x00df, 0x00e4, 0x00e9, 0x00ee, 0x00f4, 0x00f9, 0x00ff, 0x0104, 0x010a, 0x0110, 0x0116, 0x011c, 0x0122, 0x0128, 0x012f, 0x0136 }, 16, 0x00087528, 1},
++	{{0x013c, 0x0143, 0x014b, 0x0152, 0x0159, 0x0161, 0x0169, 0x0171, 0x0179, 0x0181, 0x0189, 0x0192, 0x019b, 0x01a4, 0x01ad, 0x01b7 }, 16, 0x00087548, 1},
++	{{0x01c0, 0x01ca, 0x01d4, 0x01de, 0x01e9, 0x01f4, 0x01ff, 0x020a, 0x0215, 0x0221, 0x022d, 0x0239, 0x0246, 0x0252, 0x025f, 0x026d }, 16, 0x00087568, 1},
++	{{0x027a, 0x0288, 0x0297, 0x02a5, 0x02b4, 0x02c3, 0x02d3, 0x02e3, 0x02f3, 0x0303, 0x0314, 0x0326, 0x0337, 0x0349, 0x035c, 0x036f }, 16, 0x00087588, 1},
++	{{0x0382, 0x0396, 0x03aa, 0x03be, 0x03d3, 0x03e9, 0x03ff, 0x0415, 0x042c, 0x0444, 0x045b, 0x0474, 0x048d, 0x04a6, 0x04c0, 0x04db }, 16, 0x000875a8, 1},
++	{{0x04f6, 0x0512, 0x052f, 0x054c, 0x056a, 0x0588, 0x05a7, 0x05c7, 0x05e7, 0x0608, 0x062a, 0x064d, 0x0670, 0x0694, 0x06b9, 0x06df }, 16, 0x000875c8, 1},
++	{{0x0705, 0x072d, 0x0755, 0x077e, 0x07a8, 0x07d3, 0x07ff, 0x082c, 0x085a, 0x0889, 0x08b8, 0x08e9, 0x091b, 0x094e, 0x0982, 0x09b8 }, 16, 0x000875e8, 1},
++	{{0x09ee, 0x0a26, 0x0a5f, 0x0a99, 0x0ad5, 0x0b11, 0x0b4f, 0x0b8f, 0x0bd0, 0x0c12, 0x0c55, 0x0c9b, 0x0ce1, 0x0d2a, 0x0d73, 0x0dbf }, 16, 0x00087608, 1},
++	{{0x0e0c, 0x0e5b, 0x0eab, 0x0efd, 0x0f51, 0x0fa7, 0x0fff, 0x0000, 0x003f, 0x003e, 0x001f, 0x001e, 0x001d, 0x001c, 0x001b, 0x001a }, 16, 0x00087628, 1},
++	{{0x0019, 0x0018, 0x0017, 0x0016, 0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a }, 16, 0x00087648, 1},
++	{{0x0009, 0x0008, 0x0007, 0x0006, 0x0005, 0x0004, 0x0000, 0x0000, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039, 0x0038, 0x0037, 0x0036 }, 16, 0x00087668, 1},
++	{{0x0035, 0x0034, 0x0033, 0x0032, 0x0031, 0x0030, 0x002f, 0x002e, 0x002d, 0x002c, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026 }, 16, 0x00087688, 1},
++	{{0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x001e, 0x001d, 0x001c, 0x001b, 0x001a }, 16, 0x000876a8, 1},
++	{{0x0019, 0x0018, 0x0017, 0x0016, 0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a }, 16, 0x000876c8, 1},
++	{{0x0009, 0x0008, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x001e, 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0016 }, 16, 0x000876e8, 1},
++	{{0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007, 0x0006 }, 16, 0x00087708, 1},
++	{{0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0002, 0x0001, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }, 16, 0x00087728, 1},
++	{{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }, 16, 0x00087748, 1},
++	{{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087768, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087788, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }, 16, 0x000877a8, 1},
++	{{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000877c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0001, 0x0001, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009 }, 16, 0x000877e8, 1},
++	{{0x0008, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007 }, 16, 0x00087808, 1},
++	{{0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0001, 0x0000, 0x0011, 0x0036, 0x005b, 0x0082, 0x00aa, 0x00d3, 0x00fe, 0x012c }, 16, 0x00087828, 1},
++	{{0x015b, 0x018c, 0x01bf, 0x01f5, 0x022e, 0x026a, 0x02aa, 0x02ee, 0x0336, 0x0383, 0x03d6, 0x0430, 0x0492, 0x04ff, 0x0577, 0x05ff }, 16, 0x00087848, 1},
++	{{0x0699, 0x0751, 0x0828, 0x0948, 0x0ab2, 0x0c1d, 0x0000, 0x0023, 0x0048, 0x006e, 0x0096, 0x00be, 0x00e9, 0x0114, 0x0143, 0x0172 }, 16, 0x00087868, 1},
++	{{0x01a6, 0x01d9, 0x0212, 0x024b, 0x028a, 0x02ca, 0x0312, 0x035a, 0x03ac, 0x03ff, 0x0461, 0x04c3, 0x053b, 0x05b2, 0x064c, 0x06e5 }, 16, 0x00087888, 1},
++	{{0x07bc, 0x0893, 0x09fd, 0x0b67, 0x0c80, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000 }, 16, 0x000878a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0007, 0x0006, 0x0005 }, 16, 0x000878c8, 1},
++	{{0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x0000, 0x0023, 0x006e, 0x00be, 0x0114, 0x0172, 0x01d9, 0x024b, 0x02ca, 0x035a, 0x03ff }, 16, 0x000878e8, 1},
++	{{0x04c3, 0x05b2, 0x06e5, 0x0893, 0x0b67, 0x0000, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0007, 0x0006, 0x0005 }, 16, 0x00087908, 1},
++	{{0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x0000, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0007, 0x0006, 0x0005 }, 16, 0x00087928, 1},
++	{{0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000 }, 16, 0x00087948, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffc4, 0xffe2, 0x003a, 0x00ac, 0x014e, 0x021a, 0x04ae, 0x0be2, 0x0000, 0x0096, 0x0143 }, 16, 0x00087968, 1},
++	{{0x0212, 0x0312, 0x0461, 0x064c, 0x09fd, 0x0000, 0x0096, 0x0143, 0x0212, 0x0312, 0x0461, 0x064c, 0x09fd, 0x0000, 0x0001, 0x0000 }, 16, 0x00087988, 1},
++	{{0x0000, 0x0003, 0x0002, 0x0002, 0x0001, 0x0002, 0x0001, 0xffff, 0xffff, 0x0000, 0x0000, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000 }, 16, 0x000879a8, 1},
++	{{0x00ca, 0x039e, 0x0000, 0xff2a, 0x031e, 0x0000, 0x000b, 0x11ee, 0x000b, 0x1216, 0x000b, 0x1236, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000879c8, 1},
++	{{0x000b, 0x1c1c, 0x000b, 0x1a84, 0x000b, 0x1aa2, 0x000b, 0x1ac2, 0x000b, 0x1ae2, 0x000b, 0x1b02, 0x000b, 0x1b02, 0x000b, 0x1b02 }, 16, 0x000879e8, 1},
++	{{0x000b, 0x1b02, 0x000b, 0x1b8e, 0x000b, 0x1b8e, 0x000b, 0x1b8e, 0x000b, 0x1b8e, 0x000b, 0x1c0c, 0x000b, 0x1c0c, 0x000b, 0x1c18 }, 16, 0x00087a08, 1},
++	{{0x000b, 0x1c18, 0x000b, 0x1974, 0x000b, 0x1974, 0x000b, 0x1992, 0x000b, 0x1992, 0x000b, 0x1992, 0x000b, 0x1992, 0x000b, 0x19f2 }, 16, 0x00087a28, 1},
++	{{0x000b, 0x19f2, 0x000b, 0x19f2, 0x000b, 0x19f2, 0x000b, 0x1a52, 0x000b, 0x1a52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087a48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0004, 0x0404, 0x0404, 0x0000, 0x0020, 0x2004, 0x0404, 0x0400, 0x0020, 0x0020, 0x0404, 0x0404, 0x0000 }, 16, 0x00087a68, 1},
++	{{0x2020, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404 }, 16, 0x00087a88, 1},
++	{{0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0000, 0x0004, 0x0404, 0x0404, 0x0000, 0x0000, 0x0404, 0x0404, 0x0400, 0x0000 }, 16, 0x00087aa8, 1},
++	{{0x0004, 0x0000, 0x1004, 0x0000, 0x0020, 0x2000, 0x0010, 0x0400, 0x0020, 0x0020, 0x0000, 0x1004, 0x0000, 0x2020, 0x0404, 0x0410 }, 16, 0x00087ac8, 1},
++	{{0x0404, 0x0000, 0x0004, 0x0020, 0x1020, 0x0000, 0x0000, 0x0420, 0x0010, 0x2000, 0x1010, 0x1010, 0x1010, 0x1010, 0x1000, 0x0000 }, 16, 0x00087ae8, 1},
++	{{0x0404, 0x0410, 0x2004, 0x0000, 0x0004, 0x0000, 0x1004, 0x0000, 0x0000, 0x0400, 0x0010, 0x0400, 0x0000, 0x0004, 0x0404, 0x0404 }, 16, 0x00087b08, 1},
++	{{0x0000, 0x0020, 0x2000, 0x0404, 0x0400, 0x0020, 0x0020, 0x0400, 0x0404, 0x0000, 0x2020, 0x0404, 0x0404, 0x0404, 0x0000, 0x0004 }, 16, 0x00087b28, 1},
++	{{0x0404, 0x0404, 0x0400, 0x0000, 0x0404, 0x0404, 0x0404, 0x0004, 0x0404, 0x0404, 0x0404, 0x0400, 0x0404, 0x0004, 0x0404, 0x0404 }, 16, 0x00087b48, 1},
++	{{0x0000, 0x0004, 0x0404, 0x0404, 0x0000, 0x0000, 0x0404, 0x0404, 0x0400, 0x0000, 0x0004, 0x0000, 0x1004, 0x0000, 0x0020, 0x2000 }, 16, 0x00087b68, 1},
++	{{0x0010, 0x0400, 0x0020, 0x0020, 0x0000, 0x1004, 0x0000, 0x2020, 0x0404, 0x0410, 0x0404, 0x0000, 0x0004, 0x0020, 0x1020, 0x0000 }, 16, 0x00087b88, 1},
++	{{0x0000, 0x0420, 0x0010, 0x2000, 0x1010, 0x1010, 0x1010, 0x1010, 0x1000, 0x0000, 0x0404, 0x0410, 0x0404, 0x0000, 0x0004, 0x0000 }, 16, 0x00087ba8, 1},
++	{{0x1004, 0x0000, 0x0000, 0x0400, 0x0010, 0x0400, 0x0000, 0x0207, 0x0000, 0x0246, 0x0000, 0x028d, 0x0000, 0x02dd, 0x0000, 0x0337 }, 16, 0x00087bc8, 1},
++	{{0x0000, 0x039b, 0x0000, 0x040c, 0x0000, 0x048a, 0x0000, 0x0518, 0x0000, 0x05b7, 0x0000, 0x066a, 0x0000, 0x0732, 0x0000, 0x0813 }, 16, 0x00087be8, 1},
++	{{0x0000, 0x090f, 0x0000, 0x0a2a, 0x0000, 0x0b68, 0x0000, 0x0ccc, 0x0000, 0x0e5c, 0x0000, 0x101d, 0x0000, 0x1214, 0x0000, 0x1449 }, 16, 0x00087c08, 1},
++	{{0x0000, 0x16c3, 0x0000, 0x198a, 0x0000, 0x1ca7, 0x0000, 0x2026, 0x0000, 0x2413, 0x0000, 0x287a, 0x0000, 0x2d6a, 0x0000, 0x32f5 }, 16, 0x00087c28, 1},
++	{{0x0000, 0x392c, 0x0000, 0x4026, 0x0000, 0x47fa, 0x0000, 0x50c3, 0x0000, 0x5a9d, 0x0000, 0x65ac, 0x0000, 0x7214, 0x0000, 0x8000 }, 16, 0x00087c48, 1},
++	{{0x0000, 0x8f9e, 0x0000, 0xa124, 0x0000, 0xb4ce, 0x0000, 0xcadd, 0x0000, 0xe39e, 0x0000, 0xff64, 0x0001, 0x1e8e, 0x0001, 0x4185 }, 16, 0x00087c68, 1},
++	{{0x0001, 0x68c0, 0x0001, 0x94c5, 0x0001, 0xc629, 0x0001, 0xfd93, 0x0002, 0x3bc1, 0x0002, 0x8185, 0x0002, 0xcfcc, 0x0003, 0x27a0 }, 16, 0x00087c88, 1},
++	{{0x0003, 0x8a2b, 0x0003, 0xf8bd, 0x0004, 0x74cd, 0x0005, 0x0000, 0x0005, 0x9c2f, 0x0006, 0x4b6c, 0x0007, 0x100c, 0x0007, 0xeca9 }, 16, 0x00087ca8, 1},
++	{{0x000b, 0x3e7a, 0x000b, 0x3ef0, 0x000b, 0x3f7a, 0x000b, 0x4010, 0x000b, 0x408e, 0x000b, 0x410a, 0x000b, 0x4220, 0x000b, 0x45f8 }, 16, 0x00087cc8, 1},
++	{{0x000b, 0x49dc, 0x000b, 0x4a3e, 0x00aa, 0xaaab, 0x0066, 0x6666, 0x0049, 0x2492, 0x0038, 0xe38a, 0x002e, 0x8cc9, 0x0027, 0x3413 }, 16, 0x00087ce8, 1},
++	{{0x0025, 0xe225, 0x0009, 0xcc38, 0x0009, 0xcc38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087d08, 1},
++	{{0x002a, 0xaaaa, 0xffff, 0x49f5, 0x0000, 0x0455, 0xffff, 0xffe5, 0x0000, 0x0000, 0x0001, 0xf2ba, 0x002a, 0x8240, 0x0000, 0x0418 }, 16, 0x00087d28, 1},
++	{{0x0006, 0x6666, 0x0000, 0x0000, 0xb000, 0x0028, 0x0003, 0x0000, 0xb000, 0x0028, 0x0003, 0x0000, 0xb100, 0x0028, 0x0004, 0x0000 }, 16, 0x00087d48, 1},
++	{{0xb200, 0x0027, 0x0004, 0x0000, 0xb300, 0x0027, 0x0005, 0x0000, 0xb400, 0x0026, 0x0005, 0x0000, 0xb500, 0x0026, 0x0006, 0x0000 }, 16, 0x00087d68, 1},
++	{{0xb600, 0x0025, 0x0007, 0x0000, 0xb700, 0x0025, 0x0008, 0x0000, 0xb800, 0x0024, 0x0009, 0x0000, 0xb900, 0x0024, 0x000a, 0x0000 }, 16, 0x00087d88, 1},
++	{{0xba00, 0x0023, 0x000b, 0x0000, 0xbb00, 0x0023, 0x000d, 0x0000, 0xbc00, 0x0022, 0x000e, 0x0000, 0xbd00, 0x0022, 0x0010, 0x0000 }, 16, 0x00087da8, 1},
++	{{0xbe00, 0x0021, 0x0012, 0x0000, 0xbf00, 0x0021, 0x0014, 0x0000, 0xc000, 0x0020, 0x0017, 0x0000, 0xc100, 0x0020, 0x001a, 0x0000 }, 16, 0x00087dc8, 1},
++	{{0xc200, 0x001f, 0x001d, 0x0000, 0xc300, 0x001f, 0x0020, 0x0000, 0xc400, 0x001e, 0x0024, 0x0000, 0xc500, 0x001e, 0x0029, 0x0000 }, 16, 0x00087de8, 1},
++	{{0xc600, 0x001d, 0x002e, 0x0000, 0xc700, 0x001d, 0x0033, 0x0000, 0xc800, 0x001c, 0x003a, 0x0000, 0xc900, 0x001c, 0x0041, 0x0000 }, 16, 0x00087e08, 1},
++	{{0xca00, 0x001b, 0x0049, 0x0000, 0xcb00, 0x001b, 0x0052, 0x0000, 0xcc00, 0x001a, 0x005c, 0x0000, 0xcd00, 0x001a, 0x0067, 0x0000 }, 16, 0x00087e28, 1},
++	{{0xce00, 0x0019, 0x0074, 0x0000, 0xcf00, 0x0019, 0x0082, 0x0000, 0xd000, 0x0018, 0x0092, 0x0000, 0xd100, 0x0018, 0x00a4, 0x0000 }, 16, 0x00087e48, 1},
++	{{0xd200, 0x0017, 0x00b8, 0x0000, 0xd300, 0x0017, 0x00ce, 0x0000, 0xd400, 0x0016, 0x00e7, 0x0000, 0xd500, 0x0016, 0x0104, 0x0000 }, 16, 0x00087e68, 1},
++	{{0xd600, 0x0015, 0x0124, 0x0000, 0xd700, 0x0015, 0x0147, 0x0000, 0xd800, 0x0014, 0x016f, 0x0000, 0xd900, 0x0014, 0x019c, 0x0000 }, 16, 0x00087e88, 1},
++	{{0xda00, 0x0013, 0x01ce, 0x0000, 0xdb00, 0x0013, 0x0207, 0x0000, 0xdc00, 0x0012, 0x0246, 0x0000, 0xdd00, 0x0012, 0x028d, 0x0000 }, 16, 0x00087ea8, 1},
++	{{0xde00, 0x0011, 0x02dd, 0x0000, 0xdf00, 0x0011, 0x0337, 0x0000, 0xe000, 0x0010, 0x039b, 0x0000, 0xe100, 0x0010, 0x040c, 0x0000 }, 16, 0x00087ec8, 1},
++	{{0xe200, 0x000f, 0x048a, 0x0000, 0xe300, 0x000f, 0x0518, 0x0000, 0xe400, 0x000e, 0x05b7, 0x0000, 0xe500, 0x000e, 0x066a, 0x0000 }, 16, 0x00087ee8, 1},
++	{{0xe600, 0x000d, 0x0732, 0x0000, 0xe700, 0x000d, 0x0813, 0x0000, 0xe800, 0x000c, 0x090f, 0x0000, 0xe900, 0x000c, 0x0a2a, 0x0000 }, 16, 0x00087f08, 1},
++	{{0xea00, 0x000b, 0x0b68, 0x0000, 0xeb00, 0x000b, 0x0ccc, 0x0000, 0xec00, 0x000a, 0x0e5c, 0x0000, 0xed00, 0x000a, 0x101d, 0x0000 }, 16, 0x00087f28, 1},
++	{{0xee00, 0x0009, 0x1214, 0x0000, 0xef00, 0x0009, 0x1449, 0x0000, 0xf000, 0x0008, 0x16c2, 0x0000, 0xf100, 0x0008, 0x1989, 0x0000 }, 16, 0x00087f48, 1},
++	{{0xf200, 0x0007, 0x1ca7, 0x0000, 0xf300, 0x0007, 0x2026, 0x0000, 0xf400, 0x0006, 0x2412, 0x0000, 0xf500, 0x0006, 0x2879, 0x0000 }, 16, 0x00087f68, 1},
++	{{0xf600, 0x0005, 0x2d6a, 0x0000, 0xf700, 0x0005, 0x32f4, 0x0000, 0xf800, 0x0004, 0x392c, 0x0000, 0xf900, 0x0004, 0x4026, 0x0000 }, 16, 0x00087f88, 1},
++	{{0xfa00, 0x0003, 0x47fa, 0x0000, 0xfb00, 0x0003, 0x50c2, 0x0000, 0xfc00, 0x0002, 0x5a9d, 0x0000, 0xfd00, 0x0002, 0x65ab, 0x0000 }, 16, 0x00087fa8, 1},
++	{{0xfe00, 0x0001, 0x7213, 0x0000, 0xff00, 0x0001, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb000, 0x0028, 0x0000, 0x002a }, 16, 0x00087fc8, 1},
++	{{0xb000, 0x0028, 0x0000, 0x0036, 0xb100, 0x0028, 0x0000, 0x0044, 0xb200, 0x0027, 0x0000, 0x0055, 0xb300, 0x0027, 0x0000, 0x006b }, 16, 0x00087fe8, 1},
++	{{0xb400, 0x0026, 0x0000, 0x0087, 0xb500, 0x0026, 0x0000, 0x00aa, 0xb600, 0x0025, 0x0000, 0x00d7, 0xb700, 0x0025, 0x0000, 0x010e }, 16, 0x00088008, 1},
++	{{0xb800, 0x0024, 0x0000, 0x0155, 0xb900, 0x0024, 0x0000, 0x01ad, 0xba00, 0x0023, 0x0000, 0x021c, 0xbb00, 0x0023, 0x0000, 0x02a8 }, 16, 0x00088028, 1},
++	{{0xbc00, 0x0022, 0x0000, 0x0358, 0xbd00, 0x0022, 0x0000, 0x0436, 0xbe00, 0x0021, 0x0000, 0x054e, 0xbf00, 0x0021, 0x0000, 0x06ad }, 16, 0x00088048, 1},
++	{{0xc000, 0x0020, 0x0000, 0x0868, 0xc100, 0x0020, 0x0000, 0x0a95, 0xc200, 0x001f, 0x0000, 0x0d53, 0xc300, 0x001f, 0x0000, 0x10c6 }, 16, 0x00088068, 1},
++	{{0xc400, 0x001e, 0x0000, 0x151f, 0xc500, 0x001e, 0x0000, 0x1a97, 0xc600, 0x001d, 0x0000, 0x2179, 0xc700, 0x001d, 0x0000, 0x2a24 }, 16, 0x00088088, 1},
++	{{0xc800, 0x001c, 0x0000, 0x350d, 0xc900, 0x001c, 0x0000, 0x42ca, 0xca00, 0x001b, 0x0000, 0x5415, 0xcb00, 0x001b, 0x0000, 0x69db }, 16, 0x000880a8, 1},
++	{{0xcc00, 0x001a, 0x0000, 0x8544, 0xcd00, 0x001a, 0x0000, 0xa7c5, 0xce00, 0x0019, 0x0000, 0xd336, 0xcf00, 0x0019, 0x0001, 0x09e6 }, 16, 0x000880c8, 1},
++	{{0xd000, 0x0018, 0x0001, 0x4ebf, 0xd100, 0x0018, 0x0001, 0xa56c, 0xd200, 0x0017, 0x0002, 0x128a, 0xd300, 0x0017, 0x0002, 0x9be9 }, 16, 0x000880e8, 1},
++	{{0xd400, 0x0016, 0x0003, 0x48da, 0xd500, 0x0016, 0x0004, 0x2292, 0xd600, 0x0015, 0x0005, 0x34a9, 0xd700, 0x0015, 0x0006, 0x8db8 }, 16, 0x00088108, 1},
++	{{0xd800, 0x0014, 0x0008, 0x4020, 0xd900, 0x0014, 0x000a, 0x6302, 0xda00, 0x0013, 0x000d, 0x137e, 0xdb00, 0x0013, 0x0010, 0x763f }, 16, 0x00088128, 1},
++	{{0xdc00, 0x0012, 0x0014, 0xb96b, 0xdd00, 0x0012, 0x001a, 0x1721, 0xde00, 0x0011, 0x0020, 0xd886, 0xdf00, 0x0011, 0x0029, 0x59b5 }, 16, 0x00088148, 1},
++	{{0xe000, 0x0010, 0x0034, 0x0e9d, 0xe100, 0x0010, 0x0041, 0x8937, 0xe200, 0x000f, 0x0052, 0x8143, 0xe300, 0x000f, 0x0067, 0xde18 }, 16, 0x00088168, 1},
++	{{0xe400, 0x000e, 0x0082, 0xc2f2, 0xe500, 0x000e, 0x00a4, 0x9e76, 0xe600, 0x000d, 0x00cf, 0x3e37, 0xe700, 0x000d, 0x0104, 0xe74c }, 16, 0x00088188, 1},
++	{{0xe800, 0x000c, 0x0148, 0x7543, 0xe900, 0x000c, 0x019d, 0x8113, 0xea00, 0x000b, 0x0208, 0x9229, 0xeb00, 0x000b, 0x028f, 0x5c28 }, 16, 0x000881a8, 1},
++	{{0xec00, 0x000a, 0x0339, 0x0ca2, 0xed00, 0x000a, 0x040e, 0xacf4, 0xee00, 0x0009, 0x051b, 0x9d77, 0xef00, 0x0009, 0x066e, 0x309c }, 16, 0x000881c8, 1},
++	{{0xf000, 0x0008, 0x0818, 0x6e27, 0xf100, 0x0008, 0x0a31, 0x08ff, 0xf200, 0x0007, 0x0cd4, 0x94a5, 0xf300, 0x0007, 0x1027, 0x0ac3 }, 16, 0x000881e8, 1},
++	{{0xf400, 0x0006, 0x1455, 0xb5a2, 0xf500, 0x0006, 0x1999, 0x9999, 0xf600, 0x0005, 0x203a, 0x7e5b, 0xf700, 0x0005, 0x2892, 0xc18a }, 16, 0x00088208, 1},
++	{{0xf800, 0x0004, 0x3314, 0x26ae, 0xf900, 0x0004, 0x404d, 0xe61f, 0xfa00, 0x0003, 0x50f4, 0x4d88, 0xfb00, 0x0003, 0x65ea, 0x59fd }, 16, 0x00088228, 1},
++	{{0xfc00, 0x0002, 0x804d, 0xce79, 0xfd00, 0x0002, 0xa186, 0x6ba7, 0xfe00, 0x0001, 0xcb59, 0x185d, 0xff00, 0x0001, 0xffff, 0xffff }, 16, 0x00088248, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0007, 0x0000, 0x0007, 0x0000, 0x0008, 0x0000, 0x0009, 0x0000, 0x000a, 0x0000, 0x000c, 0x0000, 0x000d }, 16, 0x00088268, 1},
++	{{0x0000, 0x000f, 0x0000, 0x0010, 0x0000, 0x0012, 0x0000, 0x0015, 0x0000, 0x0017, 0x0000, 0x001a, 0x0000, 0x001d, 0x0000, 0x0021 }, 16, 0x00088288, 1},
++	{{0x0000, 0x0025, 0x0000, 0x0029, 0x0000, 0x002e, 0x0000, 0x0034, 0x0000, 0x003a, 0x0000, 0x0042, 0x0000, 0x004a, 0x0000, 0x0053 }, 16, 0x000882a8, 1},
++	{{0x0000, 0x005d, 0x0000, 0x0068, 0x0000, 0x0075, 0x0000, 0x0083, 0x0000, 0x0093, 0x0000, 0x00a5, 0x0000, 0x00b9, 0x0000, 0x00cf }, 16, 0x000882c8, 1},
++	{{0x0000, 0x00e9, 0x0000, 0x0105, 0x0000, 0x0125, 0x0000, 0x0148, 0x0000, 0x0171, 0x0000, 0x019e, 0x0000, 0x01d0, 0x0000, 0x0209 }, 16, 0x000882e8, 1},
++	{{0x0000, 0x0248, 0x0000, 0x028f, 0x0000, 0x02df, 0x0000, 0x0339, 0x0000, 0x039e, 0x0000, 0x040f, 0x0000, 0x048d, 0x0000, 0x051c }, 16, 0x00088308, 1},
++	{{0x0000, 0x05bb, 0x0000, 0x066e, 0x0000, 0x0737, 0x0000, 0x0818, 0x0000, 0x0915, 0x0000, 0x0a31, 0x0000, 0x0b6f, 0x0000, 0x0cd5 }, 16, 0x00088328, 1},
++	{{0x0000, 0x0e65, 0x0000, 0x1027, 0x0000, 0x1220, 0x0000, 0x1456, 0x0000, 0x16d1, 0x0000, 0x199a, 0x0000, 0x1cb9, 0x0000, 0x203a }, 16, 0x00088348, 1},
++	{{0x0000, 0x2429, 0x0000, 0x2893, 0x0000, 0x2d86, 0x0000, 0x3314, 0x0000, 0x3950, 0x0000, 0x404e, 0x0000, 0x4827, 0x0000, 0x50f4 }, 16, 0x00088368, 1},
++	{{0x0000, 0x5ad5, 0x0000, 0x65ea, 0x0000, 0x725a, 0x0000, 0x804e, 0x0000, 0x8ff6, 0x0000, 0xa186, 0x0000, 0xb53c, 0x0000, 0xcb59 }, 16, 0x00088388, 1},
++	{{0x0000, 0xe429, 0x0001, 0x0000, 0x0001, 0x1f3d, 0x0001, 0x4249, 0x0001, 0x699c, 0x0001, 0x95bc, 0x0001, 0xc73d, 0x0001, 0xfeca }, 16, 0x000883a8, 1},
++	{{0x0002, 0x3d1d, 0x0002, 0x830b, 0x0002, 0xd182, 0x0003, 0x298b, 0x0003, 0x8c53, 0x0003, 0xfb28, 0x0004, 0x7783, 0x0005, 0x030a }, 16, 0x000883c8, 1},
++	{{0x0005, 0x9f98, 0x0006, 0x4f40, 0x0007, 0x1457, 0x0007, 0xf17b, 0x0008, 0xe99a, 0x000a, 0x0000, 0x000b, 0x385e, 0x000c, 0x96d9 }, 16, 0x000883e8, 1},
++	{{0x000e, 0x2019, 0x000f, 0xd954, 0x0011, 0xc865, 0x0013, 0xf3df, 0x0016, 0x6320, 0x0019, 0x1e6e, 0x001c, 0x2f0f, 0x001f, 0x9f6e }, 16, 0x00088408, 1},
++	{{0x0023, 0x7b39, 0x0027, 0xcf8b, 0x002c, 0xab1a, 0x0032, 0x1e65, 0x0038, 0x3bf0, 0x003f, 0x1882, 0x0046, 0xcb69, 0x004f, 0x6ece }, 16, 0x00088428, 1},
++	{{0x0059, 0x2006, 0x0064, 0x0000, 0x0070, 0x33ac, 0x007d, 0xe47e, 0x008d, 0x40f6, 0x009e, 0x7d44, 0x00b1, 0xd3f4, 0x00c7, 0x86b7 }, 16, 0x00088448, 1},
++	{{0x00df, 0xdf43, 0x00fb, 0x304b, 0x0119, 0xd69a, 0x013c, 0x3a4f, 0x0162, 0xd03a, 0x018e, 0x1b70, 0x01be, 0xaf00, 0x01f5, 0x2fef }, 16, 0x00088468, 1},
++	{{0x0232, 0x5761, 0x0276, 0xf515, 0x02c3, 0xf21f, 0x031a, 0x5407, 0x037b, 0x403d, 0x03e8, 0x0000, 0x002a, 0xaaaa, 0xffff, 0x49f5 }, 16, 0x00088488, 1},
++	{{0x0000, 0x0455, 0xffff, 0xffe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0600, 0x0003 }, 16, 0x000884a8, 1},
++	{{0x1800, 0x000c, 0x1800, 0x000c, 0x0300, 0x0001, 0xb000, 0x0028, 0x3c00, 0x001e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000884c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000884e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088508, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088528, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088548, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088568, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088588, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000885a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000885c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000885e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088608, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088628, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088648, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088668, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088688, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000886a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000886c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000886e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088708, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088728, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088748, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088768, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088788, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000887a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000887c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000887e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088808, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088828, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088848, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088868, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088888, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000888a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000888c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000888e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088908, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088928, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088948, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088968, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088988, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000889a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000889c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000889e8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088aa8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ac8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ae8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ba8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088bc8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088be8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ca8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088cc8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ce8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088da8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088dc8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088de8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ea8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ec8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ee8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f08, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f28, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f48, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f68, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f88, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088fa8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088fc8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088fe8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089008, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089028, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089048, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089068, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089088, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000890a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000890c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000890e8, 1},
++	{{0x000b, 0x7c66, 0x000b, 0x7bf4, 0x000b, 0x7c0a, 0x000b, 0x7c50, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800 }, 16, 0x00089108, 1},
++	{{0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700, 0x1800 }, 16, 0x00089128, 1},
++	{{0x1900, 0x1a00, 0x1b00, 0x1c00, 0x1d00, 0x1e00, 0x1f00, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2800 }, 16, 0x00089148, 1},
++	{{0x2900, 0x2a00, 0x2b00, 0x2c00, 0x2d00, 0x2e00, 0x2f00, 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x3800 }, 16, 0x00089168, 1},
++	{{0x3900, 0x3a00, 0x3b00, 0x3c00, 0x3d00, 0x3e00, 0x3f00, 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800 }, 16, 0x00089188, 1},
++	{{0x4900, 0x4a00, 0x4b00, 0x4c00, 0x4d00, 0x4e00, 0x4f00, 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800 }, 16, 0x000891a8, 1},
++	{{0x5900, 0x5a00, 0x5b00, 0x5c00, 0x5d00, 0x5e00, 0x5f00, 0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700, 0x6800 }, 16, 0x000891c8, 1},
++	{{0x6900, 0x6a00, 0x6b00, 0x6c00, 0x6d00, 0x6e00, 0x6f00, 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, 0x7800 }, 16, 0x000891e8, 1},
++	{{0x7900, 0x7a00, 0x7b00, 0x7c00, 0x7d00, 0x7e00, 0x7f00, 0x7fff, 0x7fff, 0x7fff, 0x7214, 0x65ac, 0x5a9d, 0x50c3, 0x47fa, 0x4026 }, 16, 0x00089208, 1},
++	{{0x392c, 0x32f5, 0x2d6a, 0x287a, 0x2413, 0x2026, 0x1ca7, 0x198a, 0x16c3, 0x1449, 0x1214, 0x101d, 0x0e5c, 0x0ccc, 0x0b68, 0x0a2a }, 16, 0x00089228, 1},
++	{{0x090f, 0x0813, 0x0732, 0x066a, 0x05b7, 0x0518, 0x048a, 0x040c, 0x039b, 0x0337, 0x02dd, 0x028d, 0x0246, 0x0207, 0x01ce, 0x019c }, 16, 0x00089248, 1},
++	{{0x016f, 0x0147, 0x0124, 0x0104, 0x00e7, 0x00ce, 0x00b8, 0x00a4, 0x0092, 0x0082, 0x0074, 0x0067, 0x005c, 0x0052, 0x0049, 0x0041 }, 16, 0x00089268, 1},
++	{{0x003a, 0x0033, 0x002e, 0x0029, 0x0024, 0x0020, 0x0000, 0x7fff, 0x7f82, 0x7e0d, 0x7ba2, 0x7847, 0x7401, 0x6ed9, 0x68d9, 0x620d }, 16, 0x00089288, 1},
++	{{0x5a82, 0x5246, 0x496a, 0x3fff, 0x3618, 0x2bc7, 0x2121, 0x163a, 0x0b28, 0x0000, 0xf4d8, 0xe9c6, 0xdedf, 0xd439, 0xc9e8, 0xc001 }, 16, 0x000892a8, 1},
++	{{0xb696, 0xadba, 0xa57e, 0x9df3, 0x9727, 0x9127, 0x8bff, 0x87b9, 0x845e, 0x81f3, 0x807e, 0x8001, 0x0005, 0x0a0f, 0x1419, 0x1e23 }, 16, 0x000892c8, 1},
++	{{0x282d, 0x3237, 0x3c41, 0x464b, 0x5055, 0x5a5f, 0x6469, 0x6e73, 0x787d, 0x8287, 0x8c91, 0x969b, 0xa0a5, 0xaaaf, 0xb400, 0x0000 }, 16, 0x000892e8, 1},
++	{{0x0000, 0x0000, 0x7fff, 0x4000, 0x2aab, 0x2000, 0x000b, 0xab6e, 0x000b, 0xaba2, 0x000b, 0xac72, 0x000b, 0xaddc, 0x0000, 0x0000 }, 16, 0x00089308, 1},
++	{{0x0000, 0x0000, 0xffff, 0xffff, 0x0001, 0x0304, 0x0607, 0x090a, 0x0b0d, 0x0e10, 0x1112, 0x1415, 0x1618, 0x191a, 0x1c1d, 0x1e20 }, 16, 0x00089328, 1},
++	{{0x2122, 0x2425, 0x2628, 0x292a, 0x2c2d, 0x2e2f, 0x3132, 0x3334, 0x3637, 0x3839, 0x3b3c, 0x3d3e, 0x3f41, 0x4243, 0x4445, 0x4748 }, 16, 0x00089348, 1},
++	{{0x494a, 0x4b4d, 0x4e4f, 0x5051, 0x5254, 0x5556, 0x5758, 0x595a, 0x5c5d, 0x5e5f, 0x6061, 0x6263, 0x6466, 0x6768, 0x696a, 0x6b6c }, 16, 0x00089368, 1},
++	{{0x6d6e, 0x6f70, 0x7172, 0x7475, 0x7677, 0x7879, 0x7a7b, 0x7c7d, 0x7e7f, 0x8081, 0x8283, 0x8485, 0x8687, 0x8889, 0x8a8b, 0x8c8d }, 16, 0x00089388, 1},
++	{{0x8e8f, 0x9091, 0x9293, 0x9495, 0x9697, 0x9899, 0x9a9b, 0x9b9c, 0x9d9e, 0x9fa0, 0xa1a2, 0xa3a4, 0xa5a6, 0xa7a8, 0xa9a9, 0xaaab }, 16, 0x000893a8, 1},
++	{{0xacad, 0xaeaf, 0xb0b1, 0xb2b2, 0xb3b4, 0xb5b6, 0xb7b8, 0xb9b9, 0xbabb, 0xbcbd, 0xbebf, 0xc0c0, 0xc1c2, 0xc3c4, 0xc5c6, 0xc6c7 }, 16, 0x000893c8, 1},
++	{{0xc8c9, 0xcacb, 0xcbcc, 0xcdce, 0xcfd0, 0xd0d1, 0xd2d3, 0xd4d4, 0xd5d6, 0xd7d8, 0xd8d9, 0xdadb, 0xdcdc, 0xddde, 0xdfe0, 0xe0e1 }, 16, 0x000893e8, 1},
++	{{0xe2e3, 0xe4e4, 0xe5e6, 0xe7e7, 0xe8e9, 0xeaea, 0xebec, 0xedee, 0xeeef, 0xf0f1, 0xf1f2, 0xf3f4, 0xf4f5, 0xf6f7, 0xf7f8, 0xf9f9 }, 16, 0x00089408, 1},
++	{{0xfafb, 0xfcfc, 0xfdfe, 0xffff, }, 4, 0x00089428, 1},
++	{{0x0000, 0x2018, }, 2, 0x00089430, 1},
++	{{0x31e4, 0x21cc, 0x8009, 0x3503, 0x200c, 0x80e4, 0x0846, 0x30ec, 0x8008, 0x3103, 0x3000, 0x8000, 0x90c0, 0xe7e8, 0x90c0, 0x90c0 }, 16, 0x0009e100, 1},
++	{{0x944e, 0x3928, 0x2000, 0xbfff, 0x3000, 0x2000, 0x8000, 0x92c8, 0x4099, 0x9f7c, 0x3304, 0x3520, 0x800a, 0x31e4, 0x21c8, 0x8009 }, 16, 0x0009e120, 1},
++	{{0x3503, 0x200c, 0x80e4, 0x90c0, 0x90c0, 0x94c0, 0xc080, 0xc180, 0x9cc0, 0x7550, 0x7650, 0x75d1, 0x76d1, 0xc980, 0xca80, 0x3e00 }, 16, 0x0009e140, 1},
++	{{0xa00a, 0x7750, 0x7450, 0x77d1, 0x74d1, 0xcb80, 0xcc80, 0x3e00, 0xa00f, 0x7550, 0x7650, 0x75d1, 0x76d1, 0xede9, 0xeee9, 0x3a00 }, 16, 0x0009e160, 1},
++	{{0xa10c, 0x7750, 0x77d1, 0xefe9, 0xe8e9, 0x3680, 0xa100, 0xe9e9, 0xeae9, 0x3680, 0xa100, 0xebe9, 0xece9, 0x3680, 0xa100, 0xede9 }, 16, 0x0009e180, 1},
++	{{0xeee9, 0x3680, 0xa000, 0xefe9, 0xe0e9, 0x94c0, 0xe1e9, 0xe2e9, 0x94c0, 0xe3e9, 0xc760, 0x94c0, 0xcc50, 0xcd50, 0x94c0, 0xce50 }, 16, 0x0009e1a0, 1},
++	{{0xcf50, 0x31e4, 0x2100, 0x8009, 0x9f79, 0x9f71, 0x0146, 0x3044, 0x8008, 0x3a40, 0x3038, 0x8008, 0x24ea, 0x3d40, 0x3034, 0x8008 }, 16, 0x0009e1c0, 1},
++	{{0x8447, 0x96c0, 0x9b41, 0x2b03, 0x8008, 0x2c30, 0x1492, 0x5395, 0x266a, 0x34f8, 0x3fff, 0xbfff, 0x8427, 0x6cd3, 0x7261, 0x96c1 }, 16, 0x0009e1e0, 1},
++	{{0x6d30, 0x31e0, 0x9fff, 0x94c3, 0xcc40, 0xc843, 0x7841, 0x92c3, 0xec18, 0x92c3, 0x929c, 0x5292, 0x7170, 0x81e1, 0x90c0, 0x92d0 }, 16, 0x0009e200, 1},
++	{{0xed48, 0xea48, 0x90c0, 0x3840, 0x2004, 0x8008, 0x6c10, 0x5a98, 0x90c0, 0x2a0a, 0x8001, 0xeaf1, 0xea61, 0x35e4, 0x2106, 0x8009 }, 16, 0x0009e220, 1},
++	{{0x5998, 0x5b98, 0x5c98, 0x9f4b, 0x90c0, 0x2103, 0x800a, 0x92d0, 0x9de1, 0x9d82, 0x9f4c, 0x90c0, 0x21e3, 0x9fd7, 0x92c8, 0x9082 }, 16, 0x0009e240, 1},
++	{{0x8fcf, 0x9f71, 0x9f71, 0x9f71, 0x90c0, 0x90c0, 0x9f71, 0x3480, 0xa000, 0x9f63, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e260, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6469, 0x7750, 0x9620, 0xc08e, 0x8411, 0x33e4, 0x39ea }, 16, 0x0009e280, 1},
++	{{0x8001, 0xc484, 0x04c1, 0x38b9, 0x8008, 0x94c0, 0xd321, 0xc08f, 0x8411, 0x33e4, 0x39ea, 0x8001, 0xc384, 0x03c1, 0x38b7, 0x8008 }, 16, 0x0009e2a0, 1},
++	{{0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6469, 0x77d0, 0x9e20, 0x9720, 0x845b, 0x01c5, 0x38b9 }, 16, 0x0009e2c0, 1},
++	{{0x8008, 0x64e9, 0x8051, 0x9ac0, 0xd0a3, 0x3dc0, 0x30fc, 0x8008, 0xc0a6, 0x8043, 0x1495, 0x38e8, 0x2c00, 0xbfff, 0x3ae8, 0x2c04 }, 16, 0x0009e2e0, 1},
++	{{0xbfff, 0x0490, 0x39e0, 0x3f80, 0x8009, 0x33a1, 0x3800, 0x8008, 0x32e4, 0x3a5c, 0x8001, 0x4392, 0x32e4, 0x3a62, 0x8001, 0x94c0 }, 16, 0x0009e300, 1},
++	{{0xc184, 0xc0a6, 0x32e4, 0x39e4, 0x8001, 0xc08e, 0xc383, 0x03c1, 0x38b9, 0x8008, 0x98c0, 0xd3a1, 0x00c5, 0x38b7, 0x8008, 0x846f }, 16, 0x0009e320, 1},
++	{{0x6469, 0x806b, 0x98c0, 0xd023, 0x3cc0, 0x3100, 0x8008, 0x805f, 0x1394, 0x38e8, 0x2800, 0xbfff, 0x98c0, 0x3ee8, 0x2804, 0xbfff }, 16, 0x0009e340, 1},
++	{{0xc0a2, 0x0390, 0x3900, 0x2680, 0x800a, 0x37a1, 0x3c00, 0x8008, 0x4796, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0a, 0x8078, 0x52d2 }, 16, 0x0009e360, 1},
++	{{0x355c, 0x8000, 0x3454, 0x8000, 0x8015, 0x33e4, 0x3a5c, 0x8001, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc184, 0xc0a2, 0x32e4, 0x39e4 }, 16, 0x0009e380, 1},
++	{{0x8001, 0xc08f, 0xc483, 0x04c1, 0x38b7, 0x8008, 0x94c0, 0x9e21, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e3a0, 1},
++	{{0x96c0, 0x6f90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xe8f1, 0x270b, 0x8020, 0x2418, 0x83c8, 0x94c0, 0xe7eb, 0xc281 }, 16, 0x0009e3c0, 1},
++	{{0x98c0, 0x3de8, 0x3c14, 0xbfff, 0xf245, 0x98c0, 0x34f1, 0x3fff, 0xbfff, 0xf59d, 0x1395, 0x3be8, 0x3c04, 0xbfff, 0x98c0, 0xde03 }, 16, 0x0009e3e0, 1},
++	{{0x3fc8, 0x3c10, 0xbfff, 0x0495, 0x30e9, 0x3fff, 0xb000, 0x3441, 0x2e00, 0x9200, 0x0493, 0x3ec8, 0x3c10, 0xbfff, 0x1197, 0x3fc8 }, 16, 0x0009e400, 1},
++	{{0x3c10, 0xbfff, 0x98c0, 0xdc01, 0x3ac8, 0x3c00, 0xbfff, 0x4097, 0x5196, 0x0991, 0xa000, 0x98c0, 0x4196, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e420, 1},
++	{{0x3e00, 0xa008, 0x7bc1, 0x6c10, 0x5097, 0x3300, 0x2000, 0x8042, 0x96c0, 0x318e, 0x8000, 0xc112, 0x6769, 0x92c3, 0x6e10, 0x94c6 }, 16, 0x0009e440, 1},
++	{{0x72f7, 0xc481, 0x92c2, 0x6f10, 0x94c7, 0xd4c3, 0xc681, 0x1505, 0xa001, 0x90c0, 0x3e26, 0xb000, 0x90c0, 0xc312, 0x90c0, 0x64e0 }, 16, 0x0009e460, 1},
++	{{0xc081, 0xd440, 0x3a06, 0xa200, 0x90c0, 0xf143, 0xd440, 0x65e0, 0x2461, 0xf044, 0x7170, 0x802b, 0x7160, 0x840b, 0x70e3, 0x8023 }, 16, 0x0009e480, 1},
++	{{0x70fb, 0x841f, 0x90c0, 0x94c0, 0xc112, 0xf2c4, 0x3170, 0x24e0, 0xf3c3, 0x94c0, 0x65e0, 0x81f3, 0x7160, 0x8407, 0x71f9, 0x81e7 }, 16, 0x0009e4a0, 1},
++	{{0x6669, 0x96c0, 0xf2c5, 0x2718, 0x8690, 0x6769, 0x8175, 0xf2c5, 0x6560, 0x2669, 0x3700, 0x2000, 0x8200, 0x2518, 0x813e, 0x98c0 }, 16, 0x0009e4c0, 1},
++	{{0x3ee8, 0x3c38, 0xbfff, 0xf946, 0x94c0, 0xf847, 0xf245, 0x1396, 0xce44, 0x32e4, 0x39d2, 0x8001, 0x37ff, 0x9fff, 0x32e4, 0x3c4e }, 16, 0x0009e4e0, 1},
++	{{0x8001, 0x96c0, 0x74ff, 0xf2c5, 0xce4c, 0x2660, 0x2560, 0x3fc8, 0x3c10, 0xbfff, 0x33a1, 0x33b0, 0x8000, 0x307b, 0x1597, 0x3381 }, 16, 0x0009e500, 1},
++	{{0x2020, 0x8000, 0x96c0, 0x3b0f, 0x87ff, 0x8036, 0x94c6, 0xdb8f, 0xce86, 0x707b, 0x8026, 0x92c2, 0xce85, 0x3670, 0x8018, 0x801c }, 16, 0x0009e520, 1},
++	{{0x92c2, 0xce84, 0x3650, 0x8010, 0x8012, 0x92c2, 0xce83, 0x3630, 0x8008, 0x90c0, 0x94c1, 0xce81, 0xce82, 0x98c0, 0x3d40, 0x3170 }, 16, 0x0009e540, 1},
++	{{0x8008, 0xf245, 0x0ec1, 0x38b8, 0x8008, 0xeefc, 0xee1d, 0x1bd6, 0xce44, 0x98c0, 0xcb4e, 0x33e4, 0x39d2, 0x8001, 0x98c0, 0x05c5 }, 16, 0x0009e560, 1},
++	{{0x38b8, 0x8008, 0xf9c6, 0x9ac0, 0x75e5, 0x3a40, 0x3150, 0x8008, 0xf8c7, 0x96c0, 0x7dc1, 0xf2c5, 0xce4c, 0xcb43, 0x90c0, 0xea1b }, 16, 0x0009e580, 1},
++	{{0x5ad2, 0x98c0, 0xca49, 0x32e4, 0x3c4e, 0x8001, 0x64e0, 0x3fc4, 0x2660, 0x2560, 0x3a40, 0x3170, 0x8008, 0x3820, 0xa000, 0x02c5 }, 16, 0x0009e5a0, 1},
++	{{0x38b8, 0x8008, 0x3e00, 0xa808, 0x75e2, 0x3a01, 0x8006, 0xeb1a, 0x280d, 0x8006, 0x3e00, 0xb000, 0xdd9f, 0xd891, 0x57d3, 0x3ac8 }, 16, 0x0009e5c0, 1},
++	{{0x3c18, 0xbfff, 0x98c0, 0x3603, 0x8006, 0x7fdc, 0x4315, 0x98c0, 0xd5c1, 0x06c5, 0x38b8, 0x8008, 0x3f44, 0x0913, 0xa200, 0x98c0 }, 16, 0x0009e5e0, 1},
++	{{0xdf9b, 0x06c0, 0x38b0, 0x8008, 0x5192, 0x3318, 0x8003, 0x6469, 0x90c0, 0x94c2, 0x0997, 0xa000, 0x96c0, 0x6669, 0x280b, 0x8004 }, 16, 0x0009e600, 1},
++	{{0x96c0, 0x55d3, 0x2718, 0x8168, 0x3481, 0x2000, 0x8000, 0x9ac0, 0x3b9e, 0x8000, 0x767c, 0x2b0a, 0x8002, 0x3266, 0x3ec8, 0x3c10 }, 16, 0x0009e620, 1},
++	{{0xbfff, 0x98c7, 0x2718, 0x813e, 0x90c0, 0x6d10, 0x1696, 0x3ec8, 0x3c10, 0xbfff, 0x98c0, 0x30e9, 0x3fff, 0xb000, 0xf946, 0x9ac0 }, 16, 0x0009e640, 1},
++	{{0xdc06, 0x3cc8, 0x3c10, 0xbfff, 0xf847, 0x0096, 0xf245, 0x14d3, 0x5196, 0x397c, 0x9ff0, 0x7e64, 0x94c0, 0xd994, 0xcf44, 0xdd99 }, 16, 0x0009e660, 1},
++	{{0x4396, 0x1694, 0xeeea, 0x0916, 0xa800, 0x0694, 0xcb4e, 0x51d3, 0x3319, 0x8007, 0x32e4, 0x39d2, 0x8001, 0x01c1, 0x38b8, 0x8008 }, 16, 0x0009e680, 1},
++	{{0x94c0, 0xcb46, 0xcf4c, 0x9ac0, 0x7a41, 0x3d40, 0x3150, 0x8008, 0xf9c6, 0x11d3, 0xf8c7, 0x98c0, 0x331b, 0x8007, 0xf2c5, 0xeaee }, 16, 0x0009e6a0, 1},
++	{{0x7dc1, 0xcf43, 0x90c0, 0xef1d, 0x11d7, 0x32e4, 0x3c4e, 0x8001, 0x3681, 0x8001, 0x9cc0, 0x30cb, 0x87c1, 0x6560, 0x3a01, 0x8004 }, 16, 0x0009e6c0, 1},
++	{{0xcc40, 0x9ac0, 0xdb11, 0xc553, 0x3ee8, 0x3c24, 0xbfff, 0x98c0, 0xec61, 0x3de8, 0x3c20, 0xbfff, 0x3a00, 0xa100, 0x3601, 0x8004 }, 16, 0x0009e6e0, 1},
++	{{0xcc4d, 0xed61, 0x3c20, 0xa000, 0xd4c6, 0x3fe8, 0x3c14, 0xbfff, 0x4d96, 0x09b5, 0xa000, 0x0595, 0x3d40, 0x3170, 0x8008, 0x1097 }, 16, 0x0009e700, 1},
++	{{0x3c40, 0x3140, 0x8008, 0x0950, 0xa000, 0x4097, 0x03c5, 0x38b8, 0x8008, 0x7463, 0x96c0, 0x311c, 0x8007, 0xcf40, 0x7e41, 0x94c0 }, 16, 0x0009e720, 1},
++	{{0xce44, 0xeffc, 0xef1c, 0xee1d, 0x1dd7, 0x55d6, 0x3655, 0x7edc, 0x9ac0, 0x3623, 0x8004, 0xedfc, 0x3a21, 0x8004, 0x98c0, 0xd891 }, 16, 0x0009e740, 1},
++	{{0x0dc0, 0x38b0, 0x8008, 0x14d3, 0xd5c1, 0x96c0, 0x397c, 0x9ff0, 0xdf9b, 0x9ac0, 0xdc1c, 0xdf9d, 0x30e4, 0x2788, 0x8009, 0x4012 }, 16, 0x0009e760, 1},
++	{{0x02c1, 0x38b8, 0x8008, 0x4212, 0x98c0, 0x3a00, 0x20e0, 0x8008, 0xe846, 0x1cd0, 0x3be8, 0x3c04, 0xbfff, 0x4c12, 0x4793, 0x9ac0 }, 16, 0x0009e780, 1},
++	{{0x6e10, 0xe9f1, 0x3fe8, 0x3c14, 0xbfff, 0x96c0, 0xf79d, 0x2518, 0x8372, 0x1197, 0x33e9, 0x3fff, 0xbfff, 0x9ac0, 0xdd81, 0x3be8 }, 16, 0x0009e7a0, 1},
++	{{0x3c08, 0xbfff, 0xf245, 0x0397, 0x38c8, 0x3c10, 0xbfff, 0x3341, 0x2e00, 0x9000, 0x0393, 0x3179, 0x3000, 0xbfff, 0x1090, 0x3cc8 }, 16, 0x0009e7c0, 1},
++	{{0x3c10, 0xbfff, 0x98c0, 0xdc80, 0x3ac8, 0x3c00, 0xbfff, 0x4190, 0x5190, 0x0981, 0xa000, 0x98c0, 0x4190, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e7e0, 1},
++	{{0x3e00, 0xa008, 0x7a41, 0x6e10, 0x5594, 0x3300, 0x2000, 0x8042, 0x96c0, 0x3b9d, 0x8000, 0xc112, 0x66e9, 0x92c3, 0x6e90, 0x94c6 }, 16, 0x0009e800, 1},
++	{{0x73f4, 0xc581, 0x92c2, 0x6f10, 0x94c7, 0xd4c3, 0xc681, 0x1505, 0xa001, 0x90c0, 0x3e26, 0xb000, 0x90c0, 0xc312, 0x90c0, 0x64e0 }, 16, 0x0009e820, 1},
++	{{0xc481, 0xd444, 0x3a06, 0xa200, 0x90c0, 0xf143, 0xd444, 0x65e0, 0x2461, 0xf044, 0x7170, 0x802b, 0x7160, 0x840b, 0x70e3, 0x8023 }, 16, 0x0009e840, 1},
++	{{0x70fb, 0x841f, 0x90c0, 0x94c0, 0xc112, 0xf3c4, 0x31f0, 0x24e0, 0xf2c3, 0x94c0, 0x6560, 0x81f3, 0x71e0, 0x8407, 0x7179, 0x81e7 }, 16, 0x0009e860, 1},
++	{{0x66e9, 0x96c0, 0xf2c5, 0x2718, 0x82d8, 0x6769, 0x8175, 0x37d5, 0xf2c5, 0x6560, 0x27e9, 0x2f10, 0x3be8, 0x3c38, 0xbfff, 0x96c0 }, 16, 0x0009e880, 1},
++	{{0xf642, 0x2518, 0x8108, 0x1393, 0xf946, 0x96c0, 0x37ed, 0x9fff, 0xf245, 0x3acd, 0x8410, 0x3755, 0x33e4, 0x39d2, 0x8001, 0x32e4 }, 16, 0x0009e8a0, 1},
++	{{0x3c4e, 0x8001, 0x34fe, 0x27e0, 0xf2c5, 0x2560, 0x38c8, 0x3c10, 0xbfff, 0x33a1, 0x33b0, 0x8000, 0x307b, 0x1490, 0x3181, 0x2020 }, 16, 0x0009e8c0, 1},
++	{{0x8000, 0x96c0, 0x391e, 0x87ff, 0x8036, 0x92c2, 0xcd86, 0x7079, 0x8028, 0x92c2, 0xcd85, 0x3670, 0x8018, 0x801e, 0x92c2, 0xcd84 }, 16, 0x0009e8e0, 1},
++	{{0x3650, 0x8010, 0x8014, 0x92c2, 0xcd83, 0x3630, 0x8008, 0x90c0, 0x94c1, 0xcd81, 0xcd82, 0x90c0, 0x98c0, 0xeeed, 0x32e4, 0x39d2 }, 16, 0x0009e900, 1},
++	{{0x8001, 0x98c0, 0xf245, 0x0dc1, 0x38bb, 0x8008, 0x9ac0, 0x67e0, 0x04c5, 0x38bb, 0x8008, 0xf9c6, 0x9ac0, 0x7664, 0x3b40, 0x3150 }, 16, 0x0009e920, 1},
++	{{0x8008, 0xf2c5, 0x3e41, 0xce4b, 0xcd44, 0x90c0, 0xed1b, 0x5dd5, 0x98c0, 0xcd49, 0x32e4, 0x3c4e, 0x8001, 0x64e0, 0x3f44, 0x2560 }, 16, 0x0009e940, 1},
++	{{0x04c5, 0x38bb, 0x8008, 0x9ac0, 0x3a65, 0x8000, 0x74e4, 0x290d, 0x8006, 0x98c0, 0xdc9e, 0x04c5, 0x38bb, 0x8008, 0x9cc0, 0x3865 }, 16, 0x0009e960, 1},
++	{{0x8000, 0x7664, 0x3660, 0x8000, 0x4115, 0x9ac0, 0xd895, 0x7e5c, 0x06c5, 0x38bb, 0x8008, 0x3f44, 0xd4c0, 0x98c0, 0xde19, 0x06c0 }, 16, 0x0009e980, 1},
++	{{0x38b2, 0x8008, 0xf442, 0x96c0, 0x67e9, 0x290e, 0x8004, 0x96c0, 0x55d6, 0x2718, 0x8156, 0x3081, 0x2000, 0x8000, 0x9ac0, 0x3b9f }, 16, 0x0009e9a0, 1},
++	{{0x8000, 0x74f8, 0x2e0f, 0x8002, 0x30e7, 0x3bc8, 0x3c10, 0xbfff, 0x98c7, 0x2718, 0x812c, 0x90c0, 0x6d10, 0x1093, 0x3779, 0x3000 }, 16, 0x0009e9c0, 1},
++	{{0xbfff, 0x9ac0, 0xdf80, 0x38c8, 0x3c10, 0xbfff, 0xf946, 0x0793, 0x3ac8, 0x3c10, 0xbfff, 0x14d6, 0x5390, 0x96c0, 0x397f, 0x9ff0 }, 16, 0x0009e9e0, 1},
++	{{0xf245, 0x7fe4, 0xdd9f, 0x4390, 0x5592, 0x0905, 0xa800, 0x4592, 0x53d6, 0x371e, 0x8007, 0x32e4, 0x39d2, 0x8001, 0x06c1, 0x38bb }, 16, 0x0009ea00, 1},
++	{{0x8008, 0x9ac0, 0x7bc1, 0x06c5, 0x38bb, 0x8008, 0xf9c6, 0x9ac0, 0x7666, 0x3840, 0x3150, 0x8008, 0xf2c5, 0x7e41, 0xca44, 0x90c0 }, 16, 0x0009ea20, 1},
++	{{0xea18, 0x13d2, 0x32e4, 0x3c4e, 0x8001, 0x36e1, 0x8003, 0x9ec0, 0x30cb, 0x87c1, 0x6560, 0x3a01, 0x8007, 0xc840, 0xf5c2, 0x9ac0 }, 16, 0x0009ea40, 1},
++	{{0xda11, 0xcd43, 0x3ce8, 0x3c24, 0xbfff, 0x98c0, 0xe861, 0x3be8, 0x3c20, 0xbfff, 0x98c0, 0x3603, 0x8007, 0xc84e, 0xed61, 0x9ac0 }, 16, 0x0009ea60, 1},
++	{{0xd5c4, 0x3ae8, 0x3c14, 0xbfff, 0x4d94, 0x09b6, 0xa000, 0x0693, 0x3840, 0x3170, 0x8008, 0x1192, 0x3c40, 0x3140, 0x8008, 0x0991 }, 16, 0x0009ea80, 1},
++	{{0xa000, 0x4192, 0x01c5, 0x38bb, 0x8008, 0x7761, 0x96c0, 0x3d1c, 0x8007, 0xcd46, 0x7e41, 0x94c0, 0xca44, 0xedfc, 0xed1c, 0x1bd5 }, 16, 0x0009eaa0, 1},
++	{{0xea18, 0x51d2, 0x3651, 0x3cdc, 0xebfc, 0x9ac0, 0x3660, 0x8004, 0x90c0, 0x3a64, 0x8004, 0x98c0, 0xda14, 0x0bc0, 0x38b2, 0x8008 }, 16, 0x0009eac0, 1},
++	{{0x13d6, 0xd444, 0x96c0, 0xde98, 0x3778, 0x9ff0, 0x9ac0, 0xdf18, 0xde99, 0x30e4, 0x2b04, 0x8009, 0x0617, 0xf542, 0x02c1, 0x38bb }, 16, 0x0009eae0, 1},
++	{{0x8008, 0x4217, 0x98c0, 0x3800, 0x20e2, 0x8008, 0xe946, 0x1bd1, 0x3ce8, 0x3c08, 0xbfff, 0x4b10, 0xf0c2, 0x4094, 0x2704, 0x8e64 }, 16, 0x0009eb00, 1},
++	{{0x90c0, 0x90c0, 0x90c8, 0x2560, 0x3ac8, 0x3c10, 0xbfff, 0x96c0, 0x746a, 0x27eb, 0x9fe0, 0x98c0, 0x3dc8, 0x3c10, 0xbfff, 0xe7eb }, 16, 0x0009eb20, 1},
++	{{0x94c0, 0x9e21, 0x9f21, 0x5192, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4195, 0x2560, 0x31e4, 0x24d2, 0x8009, 0x2560, 0x37d5, 0x31e4 }, 16, 0x0009eb40, 1},
++	{{0x2894, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6469, 0xc841, 0xe748, 0x96c0, 0xf389, 0x27e9, 0x9ff8 }, 16, 0x0009eb60, 1},
++	{{0x98c6, 0xe8fe, 0x3ba0, 0x3800, 0x8008, 0x98c7, 0xd1a1, 0x3ba0, 0x3c00, 0x8008, 0x90c0, 0x96c6, 0xeb18, 0x12fc, 0x9fec, 0x96c7 }, 16, 0x0009eb80, 1},
++	{{0x5193, 0x14fc, 0x9fec, 0x98c6, 0xf142, 0x34e9, 0x810a, 0xf38b, 0x9cc1, 0x38e9, 0x811a, 0xf28b, 0x36e9, 0x8280, 0xf142, 0x96c7 }, 16, 0x0009eba0, 1},
++	{{0xf142, 0x34e9, 0x8290, 0x94c7, 0x6469, 0xf142, 0x5291, 0x98c6, 0xe768, 0x3da0, 0x3800, 0x8008, 0x96c3, 0x39a0, 0x3c00, 0x8008 }, 16, 0x0009ebc0, 1},
++	{{0x92c2, 0xe81d, 0x94c7, 0x9f70, 0xe819, 0x4290, 0x90c0, 0x90c0, 0x98c0, 0x3118, 0x8700, 0x9620, 0x9f20, 0x6469, 0x809d, 0x96c0 }, 16, 0x0009ebe0, 1},
++	{{0x3410, 0x8500, 0xc68b, 0x8089, 0x98c0, 0x3410, 0x8400, 0xc481, 0xc689, 0x806d, 0x96c0, 0x3410, 0x8300, 0xc68f, 0x8059, 0x96c0 }, 16, 0x0009ec00, 1},
++	{{0x3410, 0x8200, 0xc68e, 0x8045, 0x96c0, 0x3410, 0x8700, 0xc68d, 0x8031, 0x98c0, 0x3410, 0x8600, 0xc281, 0xc68a, 0x8015, 0x98c0 }, 16, 0x0009ec20, 1},
++	{{0x3410, 0x8100, 0xc082, 0xc68a, 0x8451, 0x31e4, 0x2c9c, 0x8009, 0x30e4, 0x2c9c, 0x8009, 0x98c0, 0xc082, 0x02c1, 0x38bc, 0x8008 }, 16, 0x0009ec40, 1},
++	{{0x98c0, 0xc085, 0x31e4, 0x2c9c, 0x8009, 0x98c0, 0xc086, 0x31e4, 0x2c9c, 0x8009, 0x98c0, 0xc087, 0x31e4, 0x2c9c, 0x8009, 0x30e4 }, 16, 0x0009ec60, 1},
++	{{0x2c9c, 0x8009, 0x98c0, 0xc081, 0x04c1, 0x38bc, 0x8008, 0x98c0, 0xc083, 0x31e4, 0x2c9c, 0x8009, 0x2c10, 0x6f10, 0xd0a1, 0xd358 }, 16, 0x0009ec80, 1},
++	{{0x96c0, 0x747e, 0x9621, 0x9f21, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x64e9, 0xcd50, 0xc59c, 0x94c0, 0x9620, 0x9720, 0x94c0 }, 16, 0x0009eca0, 1},
++	{{0xcd5e, 0xcc51, 0x96c0, 0x7b61, 0x9e20, 0x9f20, 0x9cc0, 0x36c2, 0x8005, 0xcd56, 0x34c5, 0x8005, 0xe748, 0x98c0, 0xda15, 0x03c6 }, 16, 0x0009ecc0, 1},
++	{{0x30fc, 0x8008, 0x98c0, 0xd642, 0x36cd, 0x8041, 0x843b, 0x9ac0, 0x66e9, 0x39c8, 0x3c10, 0xbfff, 0xce44, 0x3fc0, 0x2280, 0x8008 }, 16, 0x0009ece0, 1},
++	{{0x94c7, 0x5291, 0xc881, 0x90c0, 0x98c6, 0x350a, 0x87ff, 0xee1f, 0xe838, 0x9ac0, 0xda0a, 0xc84a, 0x31e4, 0x2d4e, 0x8009, 0x98c0 }, 16, 0x0009ed00, 1},
++	{{0x02c6, 0x3100, 0x8008, 0xce44, 0x34cd, 0x8041, 0x26e9, 0x3bc8, 0x3c10, 0xbfff, 0x3cc0, 0x22f0, 0x8008, 0x94c7, 0x5293, 0xc881 }, 16, 0x0009ed20, 1},
++	{{0x90c0, 0x98c6, 0x351c, 0x87ff, 0xee1c, 0xe838, 0xc84a, 0x94c0, 0xee42, 0xc781, 0x96c0, 0xd7c4, 0x50d6, 0xee4a, 0x98c0, 0x3ece }, 16, 0x0009ed40, 1},
++	{{0x8743, 0xce50, 0x5316, 0x98c0, 0x34f3, 0x9fff, 0xf191, 0xf792, 0x3a00, 0xa001, 0x2e08, 0x8002, 0x7651, 0xcf56, 0x1410, 0x4116 }, 16, 0x0009ed60, 1},
++	{{0x94c0, 0x4710, 0x8081, 0x3e00, 0xa003, 0x70e3, 0x74d3, 0x7452, 0x74d4, 0xcc58, 0xcd5e, 0x96c0, 0x7f42, 0xc581, 0x806b, 0x3b42 }, 16, 0x0009ed80, 1},
++	{{0xf501, 0x9ac0, 0x6e90, 0xf603, 0x32e4, 0x2b70, 0x8009, 0x36d3, 0xf502, 0x3c00, 0xaa00, 0x7550, 0x75d5, 0x7651, 0xce58, 0xc181 }, 16, 0x0009eda0, 1},
++	{{0x756a, 0x3600, 0xa008, 0x6569, 0x7452, 0x8437, 0x33e4, 0x2bf0, 0x8009, 0x94c0, 0xd02a, 0xcc58, 0x92c2, 0x79c1, 0x3a22, 0xa004 }, 16, 0x0009edc0, 1},
++	{{0x6e90, 0x74f3, 0xc681, 0xf603, 0x96c2, 0x32e4, 0x2b70, 0x8009, 0x3662, 0xa000, 0xf601, 0xf502, 0x3600, 0xb800, 0x7550, 0x7651 }, 16, 0x0009ede0, 1},
++	{{0x34f4, 0x9fff, 0x8077, 0x3e00, 0xa003, 0x73e4, 0x74d4, 0x7452, 0x74d4, 0xcc58, 0xcd5e, 0x96c0, 0x7f42, 0xc582, 0x8065, 0x96c0 }, 16, 0x0009ee00, 1},
++	{{0x6e90, 0xf501, 0xf603, 0x32e4, 0x2b70, 0x8009, 0xf502, 0x3800, 0xa800, 0x7550, 0xce58, 0xc182, 0x756a, 0x3600, 0xa008, 0x6569 }, 16, 0x0009ee20, 1},
++	{{0x7452, 0x8439, 0x33e4, 0x2bf0, 0x8009, 0x3800, 0xb000, 0xd022, 0x7651, 0xcc58, 0x92c2, 0x7a41, 0x3a22, 0xa000, 0x6d90, 0x74f4 }, 16, 0x0009ee40, 1},
++	{{0xc782, 0xf603, 0x96c2, 0x32e4, 0x2b70, 0x8009, 0x3642, 0xa000, 0xf302, 0xf701, 0x3400, 0xa800, 0x7550, 0x32e4, 0x2bf0, 0x8009 }, 16, 0x0009ee60, 1},
++	{{0x3800, 0xa004, 0x7452, 0xce58, 0xc181, 0x3a00, 0xb000, 0x76d0, 0x74d4, 0xcd5e, 0xcc5b, 0x3a00, 0xa004, 0x76d6, 0x7453, 0xc681 }, 16, 0x0009ee80, 1},
++	{{0xf502, 0x3600, 0xa800, 0x75d5, 0xf601, 0x7dc2, 0x3c00, 0xa004, 0x76d3, 0x79c2, 0x32e4, 0x2b70, 0x8009, 0x3800, 0xa004, 0x74d3 }, 16, 0x0009eea0, 1},
++	{{0x7753, 0xf303, 0x3a00, 0xb200, 0x75d6, 0x7768, 0x74d4, 0xcc58, 0x6769, 0x848f, 0xd2aa, 0x3602, 0xa004, 0x3303, 0x8001, 0x3822 }, 16, 0x0009eec0, 1},
++	{{0xa800, 0x74f3, 0xc281, 0xc088, 0x94c2, 0xf201, 0xf303, 0x96c2, 0x32e4, 0x2b70, 0x8009, 0x3422, 0xa000, 0xf002, 0x3800, 0xa804 }, 16, 0x0009eee0, 1},
++	{{0x75f1, 0xce58, 0xcf5b, 0x3e40, 0xa402, 0x311a, 0x8700, 0xcc58, 0x3701, 0x8004, 0xc281, 0x96c0, 0x3412, 0x8600, 0x7573, 0x94c0 }, 16, 0x0009ef00, 1},
++	{{0x7542, 0x8443, 0x3820, 0xa804, 0x6dc8, 0xf502, 0xf201, 0x32e4, 0x2b70, 0x8009, 0x3640, 0xa800, 0x74f3, 0xf103, 0x3860, 0xa800 }, 16, 0x0009ef20, 1},
++	{{0x7673, 0xc488, 0xc281, 0x3820, 0xa000, 0x7a41, 0xcc58, 0xf103, 0x32e4, 0x2b70, 0x8009, 0x3860, 0xa000, 0x74f4, 0xf201, 0xf402 }, 16, 0x0009ef40, 1},
++	{{0x32e4, 0x2bf0, 0x8009, 0x94c0, 0xce58, 0xc182, 0x3c20, 0xa004, 0x77d0, 0x74d7, 0x6760, 0xcc5c, 0xc482, 0x3860, 0xa000, 0x7454 }, 16, 0x0009ef60, 1},
++	{{0xf503, 0xf401, 0x32e4, 0x2b70, 0x8009, 0x3420, 0xa000, 0xf702, 0x3800, 0xb000, 0x6769, 0x75d5, 0xcc58, 0x8499, 0x3400, 0xa004 }, 16, 0x0009ef80, 1},
++	{{0xd3a2, 0x94c2, 0x3f06, 0x8001, 0x3842, 0xa000, 0x74f6, 0xc388, 0xc582, 0x94c2, 0xf303, 0xf501, 0x96c2, 0x32e4, 0x2b70, 0x8009 }, 16, 0x0009efa0, 1},
++	{{0x3422, 0xa000, 0xf302, 0x94c0, 0xce58, 0xcf5b, 0x3c20, 0xa001, 0x311e, 0x8700, 0x7773, 0xcc58, 0xc582, 0x3a00, 0xa201, 0x3416 }, 16, 0x0009efc0, 1},
++	{{0x8600, 0x7746, 0xcd5e, 0x3800, 0xa004, 0x3d04, 0x8004, 0x844d, 0x3860, 0xa040, 0x6f5f, 0xf702, 0xf501, 0x3c00, 0xa004, 0x7e42 }, 16, 0x0009efe0, 1},
++	{{0x74f6, 0x32e4, 0x2b70, 0x8009, 0x3420, 0xa000, 0xf403, 0x3840, 0xa004, 0x74f6, 0xc088, 0xc682, 0x3820, 0xa004, 0x78c1, 0xcc58 }, 16, 0x0009f000, 1},
++	{{0xf403, 0x32e4, 0x2b70, 0x8009, 0x3820, 0xa800, 0x74f1, 0xf601, 0xf002, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x0009f020, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x6469, 0x9620, 0x06c5, 0x38b9, 0x8008, 0x94c0, 0x9e20 }, 16, 0x0009f040, 1},
++	{{0x846f, 0x98c0, 0xd323, 0x05c6, 0x3104, 0x8008, 0x96c0, 0x845f, 0x0905, 0xa300, 0x06c4, 0x38b0, 0x8008, 0x98c0, 0xdf1d, 0x3ee8 }, 16, 0x0009f060, 1},
++	{{0x2c08, 0xbfff, 0x06c2, 0x3108, 0x8008, 0x4696, 0x06c5, 0x38b6, 0x8008, 0x6769, 0x92c3, 0x6c90, 0x98c2, 0xc681, 0x34a1, 0x2800 }, 16, 0x0009f080, 1},
++	{{0x8008, 0x96c3, 0x33a1, 0x3000, 0x8008, 0x96c2, 0x04c2, 0x3104, 0x8008, 0x96c2, 0x06c1, 0x38b6, 0x8008, 0x96c3, 0x03c2, 0x3104 }, 16, 0x0009f0a0, 1},
++	{{0x8008, 0x96c3, 0x01c1, 0x38b6, 0x8008, 0x98c0, 0xd021, 0x06c5, 0x38b7, 0x8008, 0x846b, 0x98c0, 0xd323, 0x04c6, 0x3118, 0x8008 }, 16, 0x0009f0c0, 1},
++	{{0x96c0, 0x845f, 0x0904, 0xa300, 0x00c4, 0x38b2, 0x8008, 0x98c0, 0xdc1c, 0x3ae8, 0x2808, 0xbfff, 0x00c2, 0x3110, 0x8008, 0x4092 }, 16, 0x0009f0e0, 1},
++	{{0x00c5, 0x38ba, 0x8008, 0x6469, 0x92c3, 0x6c90, 0x98c2, 0xc081, 0x34a1, 0x2000, 0x8008, 0x96c3, 0x3681, 0x3800, 0x8008, 0x96c2 }, 16, 0x0009f100, 1},
++	{{0x04c2, 0x3118, 0x8008, 0x96c2, 0x00c1, 0x38ba, 0x8008, 0x96c3, 0x06c2, 0x3118, 0x8008, 0x96c3, 0x01c1, 0x38ba, 0x8008, 0x9e21 }, 16, 0x0009f120, 1},
++	{{0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6e90, 0x9620, 0x9720, 0x96c0, 0x6c90, 0x9e20, 0x9f20 }, 16, 0x0009f140, 1},
++	{{0x98c0, 0x3bc0, 0x30ac, 0x8008, 0xeae9, 0x98c0, 0x3fc0, 0x308c, 0x8008, 0xece8, 0x0593, 0xe9eb, 0x0597, 0xeeef, 0x96c0, 0xee64 }, 16, 0x0009f160, 1},
++	{{0x270d, 0x8020, 0x0596, 0xe964, 0x0591, 0xe7ed, 0x96c0, 0xeb68, 0x2300, 0x8200, 0x0593, 0xef68, 0x0597, 0xf341, 0x98c0, 0xfa43 }, 16, 0x0009f180, 1},
++	{{0x38a0, 0x3800, 0x8008, 0x98c0, 0x05c2, 0x3080, 0x8008, 0xeeec, 0x05c1, 0x38b9, 0x8008, 0x32e4, 0x3c8a, 0x8001, 0x05c2, 0x30a0 }, 16, 0x0009f1a0, 1},
++	{{0x8008, 0x9ac0, 0x6f10, 0x38c0, 0x30bc, 0x8008, 0xc281, 0x2c90, 0x3dc0, 0x30cc, 0x8008, 0x0690, 0xefe8, 0x0695, 0xebed, 0x98c0 }, 16, 0x0009f1c0, 1},
++	{{0xe868, 0x07a6, 0x3800, 0x8008, 0x98c0, 0x3cef, 0x804f, 0xeb64, 0xed68, 0x96c0, 0xef64, 0x2400, 0x8200, 0x0690, 0x4693, 0x0695 }, 16, 0x0009f1e0, 1},
++	{{0x4697, 0x98c0, 0xf441, 0x38a0, 0x3c00, 0x8008, 0x07a2, 0x3800, 0x8008, 0x02c1, 0x38b9, 0x8008, 0x06c1, 0x38b7, 0x8008, 0x06c2 }, 16, 0x0009f200, 1},
++	{{0x30c0, 0x8008, 0x32e4, 0x3c8a, 0x8001, 0x06c2, 0x30b0, 0x8008, 0x9cc0, 0x6d10, 0x6c90, 0x06a6, 0x3c00, 0x8008, 0xc581, 0x9ac0 }, 16, 0x0009f220, 1},
++	{{0x6c10, 0x3d00, 0x20e0, 0x8008, 0xeef1, 0x96c0, 0x34ee, 0x804f, 0xfac3, 0x3800, 0x20e2, 0x8008, 0x05c1, 0x38b7, 0x8008, 0x06a2 }, 16, 0x0009f240, 1},
++	{{0x3c00, 0x8008, 0x4215, 0x4210, 0x02c1, 0x38b8, 0x8008, 0x01c1, 0x38bb, 0x8008, 0x2418, 0x8666, 0x01c1, 0x38bc, 0x8008, 0x33e4 }, 16, 0x0009f260, 1},
++	{{0x2290, 0x8009, 0x9ac0, 0x6c10, 0x03c5, 0x38b9, 0x8008, 0xecee, 0x65e9, 0x90c0, 0x98c7, 0x32e4, 0x22d0, 0x8009, 0x5394, 0x96c3 }, 16, 0x0009f280, 1},
++	{{0x03c2, 0x30fc, 0x8008, 0x94c0, 0xc185, 0xe939, 0x32e4, 0x23c0, 0x8009, 0x94c0, 0xf101, 0xe8ee, 0x9cc0, 0x6469, 0x6c10, 0xecee }, 16, 0x0009f2a0, 1},
++	{{0x03c6, 0x30fc, 0x8008, 0x98c0, 0x36cd, 0x8041, 0xec48, 0x841b, 0x33e4, 0x2290, 0x8009, 0x98c0, 0xfac3, 0x31e4, 0x38da, 0x8009 }, 16, 0x0009f2c0, 1},
++	{{0x9cc0, 0x66e9, 0x6f10, 0x3dc8, 0x3c10, 0xbfff, 0xc7ff, 0x96c0, 0xc283, 0x2000, 0x8080, 0x94c2, 0x5195, 0xc581, 0x96c1, 0xc482 }, 16, 0x0009f2e0, 1},
++	{{0x32c9, 0x82d0, 0x98c6, 0x31a2, 0x3800, 0x8008, 0xd6c1, 0x96c6, 0xc385, 0x3acc, 0x8743, 0x9ac0, 0x7674, 0x3111, 0x2000, 0x8000 }, 16, 0x0009f300, 1},
++	{{0xc587, 0x3c20, 0xa000, 0x6c7d, 0x3bc0, 0x2282, 0x8008, 0xc386, 0x3a40, 0xa000, 0x7a61, 0x05c4, 0x38b0, 0x8008, 0x3e00, 0xa700 }, 16, 0x0009f320, 1},
++	{{0x2b0e, 0x8002, 0x6929, 0x69ad, 0x7e42, 0xc255, 0x3a00, 0xb988, 0x6af6, 0x6a2d, 0xcf44, 0xc945, 0x3a80, 0xa000, 0xeafc, 0x0dc6 }, 16, 0x0009f340, 1},
++	{{0x38d0, 0x8008, 0x3620, 0xa000, 0xef19, 0xe9fe, 0x0197, 0x3122, 0x336c, 0x8009, 0x14dc, 0xed54, 0x3800, 0xa100, 0x4413, 0x2d08 }, 16, 0x0009f360, 1},
++	{{0x8028, 0x3820, 0xa000, 0x451e, 0x2800, 0x8052, 0x461e, 0x3420, 0xa000, 0x451e, 0x3420, 0xa000, 0x451e, 0x471e, 0x4716, 0x16dc }, 16, 0x0009f380, 1},
++	{{0xee50, 0x96c0, 0x4616, 0x2e0f, 0x8002, 0x421f, 0x3420, 0xa000, 0x4a1f, 0x3420, 0xa000, 0x451f, 0x3420, 0xa000, 0x451f, 0x471f }, 16, 0x0009f3a0, 1},
++	{{0x4717, 0x12dc, 0xef50, 0x3800, 0xa100, 0x4217, 0x2f0a, 0x8002, 0x3480, 0xa000, 0x431a, 0x3480, 0xa000, 0x491a, 0x34a0, 0xa000 }, 16, 0x0009f3c0, 1},
++	{{0x451a, 0x34a0, 0xa000, 0x451a, 0x3480, 0xa000, 0x471a, 0x3480, 0xa000, 0x4712, 0x3600, 0xa100, 0x53d4, 0xea50, 0x38c0, 0xa000 }, 16, 0x0009f3e0, 1},
++	{{0x4312, 0x2a09, 0x8002, 0x3640, 0xa000, 0x4519, 0xfa44, 0x3420, 0xa000, 0x4419, 0x3420, 0xa000, 0x4519, 0x3420, 0xa000, 0x4519 }, 16, 0x0009f400, 1},
++	{{0x4719, 0x3600, 0xa100, 0x4711, 0xeee9, 0x3600, 0xa100, 0x52d5, 0xee38, 0x96c0, 0x351a, 0x80ff, 0xf945, 0x7d42, 0xcd42, 0x90c0 }, 16, 0x0009f420, 1},
++	{{0x3420, 0xa000, 0xed19, 0x5695, 0x3480, 0xa000, 0x4696, 0x3480, 0xa000, 0x53d0, 0x371d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465 }, 16, 0x0009f440, 1},
++	{{0x96c0, 0xf9c5, 0x2402, 0x804a, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xc8b6, 0x3680, 0xa100, 0xebe9, 0xe9e9, 0x36a0, 0xa000, 0xeb3c }, 16, 0x0009f460, 1},
++	{{0xed56, 0x3680, 0xa100, 0x4013, 0xe938, 0x13d5, 0x3022, 0x336c, 0x8009, 0x9ac0, 0x2d08, 0x8028, 0x90c0, 0x371f, 0x80ff, 0x7fc2 }, 16, 0x0009f480, 1},
++	{{0xcd47, 0x90c0, 0x3420, 0xa000, 0xed18, 0x5295, 0x3480, 0xa000, 0x4291, 0x52d0, 0x351e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466 }, 16, 0x0009f4a0, 1},
++	{{0x94c0, 0xf9c5, 0xcdae, 0x3022, 0x336c, 0x8009, 0x3a20, 0xa000, 0x0fc6, 0x38d0, 0x8008, 0xe8e9, 0xe83d, 0x3600, 0xa100, 0x4010 }, 16, 0x0009f4c0, 1},
++	{{0xef58, 0x3680, 0xa000, 0x56d7, 0xede9, 0x3c40, 0xa000, 0x3d1f, 0x80ff, 0xed7a, 0x2f08, 0x8028, 0x7fc2, 0xc357, 0x90c0, 0x34a0 }, 16, 0x0009f4e0, 1},
++	{{0xa000, 0xeb18, 0x3480, 0xa000, 0x5293, 0x4295, 0x52d0, 0x351c, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7464, 0x98c0, 0xf9c5, 0x08c6 }, 16, 0x0009f500, 1},
++	{{0x38d0, 0x8008, 0x3d20, 0x336c, 0x8009, 0x3680, 0xa000, 0xefe9, 0xe85a, 0x3680, 0xa000, 0xef72, 0xe942, 0x3680, 0xa000, 0x4017 }, 16, 0x0009f520, 1},
++	{{0xf945, 0x96c0, 0x53d0, 0x2808, 0x8028, 0x371a, 0x80ff, 0x7d42, 0xc552, 0x90c0, 0x3480, 0xa000, 0xed1d, 0x3480, 0xa000, 0x5495 }, 16, 0x0009f540, 1},
++	{{0x4491, 0x52d0, 0x351e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x3a40, 0xa000, 0xf9c5, 0x0cc6, 0x38d0, 0x8008, 0x2602, 0x8058 }, 16, 0x0009f560, 1},
++	{{0x3600, 0xa100, 0xe948, 0xec54, 0x0011, 0xede9, 0x36c0, 0xa000, 0x56d4, 0xed3e, 0x9ac0, 0x7f68, 0x3820, 0x336c, 0x8009, 0xf945 }, 16, 0x0009f580, 1},
++	{{0x3840, 0xa100, 0x7f42, 0x2c0c, 0x8028, 0xc656, 0x90c0, 0x3480, 0xa000, 0xee18, 0x3480, 0xa000, 0x5196, 0x4195, 0x3480, 0xa000 }, 16, 0x0009f5a0, 1},
++	{{0x51d4, 0x3ce8, 0x3244, 0x3d90, 0x800a, 0x7461, 0x96c0, 0xf9c5, 0x2002, 0x8052, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xc8bc, 0x3680 }, 16, 0x0009f5c0, 1},
++	{{0xa100, 0xefe9, 0xebe9, 0x36a0, 0xa000, 0xef38, 0xed56, 0x3680, 0xa100, 0x4017, 0xeb38, 0x13d5, 0x3022, 0x336c, 0x8009, 0x96c0 }, 16, 0x0009f5e0, 1},
++	{{0x7de8, 0x2d08, 0x8028, 0x7dc2, 0xcd43, 0x90c0, 0x3420, 0xa000, 0xed18, 0x5695, 0x3480, 0xa000, 0x4693, 0x53d0, 0x3de8, 0x3244 }, 16, 0x0009f600, 1},
++	{{0x3d90, 0x800a, 0x7463, 0x94c0, 0xf9c5, 0xc8b6, 0x3820, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0x3a80, 0xa000, 0xece9, 0x3d20, 0x336c }, 16, 0x0009f620, 1},
++	{{0x8009, 0x3680, 0xa100, 0xec38, 0xee58, 0x36c0, 0xa000, 0x4014, 0xcca0, 0x3680, 0xa000, 0x55d6, 0xe8e9, 0x3ae0, 0xa000, 0x7ee8 }, 16, 0x0009f640, 1},
++	{{0xe83c, 0x2e0b, 0x8028, 0x7ec2, 0xc455, 0x90c0, 0x3480, 0xa000, 0xec1d, 0x3480, 0xa000, 0x5594, 0x4590, 0x3480, 0xa000, 0x52d3 }, 16, 0x0009f660, 1},
++	{{0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x3a40, 0xa000, 0xf9c5, 0x0cc6, 0x38d0, 0x8008, 0x3820, 0x336c, 0x8009, 0x3600, 0xa100 }, 16, 0x0009f680, 1},
++	{{0xede9, 0xec5a, 0x3840, 0xa100, 0xed7a, 0x2c0b, 0x8028, 0x4015, 0x3680, 0xa000, 0x52d4, 0xede9, 0x3d68, 0xed64, 0x7d42, 0xc052 }, 16, 0x0009f6a0, 1},
++	{{0x90c0, 0x3480, 0xa000, 0xe818, 0x3480, 0xa000, 0x5490, 0x4495, 0x3480, 0xa000, 0x57d3, 0x3fe8, 0x3244, 0x3d90, 0x800a, 0x7467 }, 16, 0x0009f6c0, 1},
++	{{0x98c0, 0xf9c5, 0x3bc0, 0x2282, 0x8008, 0x3a20, 0xa000, 0xfac4, 0x0dc6, 0x38d0, 0x8008, 0xe942, 0x4011, 0x15d3, 0x57d6, 0x9ac0 }, 16, 0x0009f6e0, 1},
++	{{0x3b19, 0x80ff, 0x90c0, 0x3f1d, 0x80ff, 0x96c0, 0x72e1, 0x2d09, 0x8002, 0x90c0, 0x94c2, 0x0907, 0xa0ff, 0x92c2, 0x4716, 0x16d7 }, 16, 0x0009f700, 1},
++	{{0x53d3, 0x9ac0, 0x3d1a, 0x80ff, 0x90c0, 0x371d, 0x80ff, 0x7165, 0x90c0, 0x94c2, 0x0906, 0xa0ff, 0x92c2, 0x4617, 0x3600, 0xa100 }, 16, 0x0009f720, 1},
++	{{0x54d3, 0x55d2, 0x9ac0, 0x391e, 0x80ff, 0x90c0, 0x3b1b, 0x80ff, 0x71e6, 0x90c0, 0x94c2, 0x0905, 0xa0ff, 0x3482, 0xa000, 0x4512 }, 16, 0x0009f740, 1},
++	{{0x12d7, 0x56d6, 0x9ac0, 0x351f, 0x80ff, 0x90c0, 0x3d1e, 0x80ff, 0x73e6, 0x90c0, 0x94c2, 0x0902, 0xa0ff, 0x92c2, 0x4217, 0x3680 }, 16, 0x0009f760, 1},
++	{{0xa000, 0x51d2, 0x53d6, 0x9ac0, 0x331c, 0x80ff, 0x90c0, 0x371a, 0x80ff, 0x7262, 0x90c0, 0x94c2, 0x0901, 0xa0ff, 0x3482, 0xa000 }, 16, 0x0009f780, 1},
++	{{0x4112, 0x3600, 0xa100, 0x54d7, 0x52d2, 0x9ac0, 0x391d, 0x80ff, 0x90c0, 0x3519, 0x80ff, 0x70e5, 0x90c0, 0x94c2, 0x0902, 0xa0ff }, 16, 0x0009f7a0, 1},
++	{{0x3482, 0xa000, 0x4212, 0x54d1, 0x391c, 0x8004, 0x6669, 0x92c3, 0x6c90, 0x94c3, 0x55d3, 0xc081, 0x94c3, 0x3b1e, 0x80ff, 0x96c3 }, 16, 0x0009f7c0, 1},
++	{{0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf601, 0xf602, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x8002, 0x55d0, 0x3b1e, 0x8008, 0x6769 }, 16, 0x0009f7e0, 1},
++	{{0x92c3, 0x6c90, 0x94c3, 0x55d6, 0xc082, 0x94c3, 0x3b1c, 0x80ff, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf402, 0xf401, 0x0dc6 }, 16, 0x0009f800, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2d08, 0x8002, 0x52d0, 0x351c, 0x8010, 0x6669, 0x92c3, 0x6c90, 0x94c3, 0x56d7, 0xc083, 0x94c3, 0x3d1f }, 16, 0x0009f820, 1},
++	{{0x80ff, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf702, 0xf701, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed42, 0x55d5, 0x3b1b, 0x8020 }, 16, 0x0009f840, 1},
++	{{0x65e9, 0x92c3, 0x6c90, 0x3683, 0xa000, 0x55d2, 0xc084, 0x94c3, 0x3b1d, 0x80ff, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf502 }, 16, 0x0009f860, 1},
++	{{0xf501, 0x98c0, 0x3fc0, 0x26a0, 0x8008, 0xc784, 0x3ec0, 0x2360, 0x8008, 0x3204, 0x2f80, 0x800b, 0xe8ef, 0x3204, 0x2e90, 0x800b }, 16, 0x0009f880, 1},
++	{{0xe8ee, 0x9ac0, 0x2f0f, 0x80d0, 0x7be1, 0x2e0e, 0x80d0, 0x67ea, 0x81e3, 0x9ac0, 0x6c10, 0xc381, 0x36a1, 0x2800, 0x8008, 0x03c1 }, 16, 0x0009f8a0, 1},
++	{{0x38b6, 0x8008, 0x32e4, 0x3050, 0x8009, 0x06c2, 0x3104, 0x8008, 0x32e4, 0x3050, 0x8009, 0x6c10, 0xfac3, 0x9ac0, 0x6f10, 0x07c5 }, 16, 0x0009f8c0, 1},
++	{{0x38b8, 0x8008, 0xc081, 0x3567, 0x3840, 0x3160, 0x8008, 0x3d41, 0x03c5, 0x38bc, 0x8008, 0x9ac0, 0x65e9, 0xcd42, 0x06c1, 0x38bc }, 16, 0x0009f8e0, 1},
++	{{0x8008, 0x90c0, 0xed18, 0x5d15, 0xcd4f, 0x92c3, 0xedfc, 0x94c7, 0xeaf1, 0xcd4f, 0x2418, 0x85ce, 0x07c0, 0x38ae, 0x8008, 0x33e4 }, 16, 0x0009f900, 1},
++	{{0x2290, 0x8009, 0x98c0, 0x06c5, 0x38b7, 0x8008, 0xfac3, 0x2769, 0xc081, 0x90c0, 0x98c7, 0x32e4, 0x22d0, 0x8009, 0x5192, 0x96c3 }, 16, 0x0009f920, 1},
++	{{0x01c2, 0x3100, 0x8008, 0x94c0, 0xfac3, 0xc685, 0x94c0, 0xf601, 0xe838, 0x32e4, 0x23c0, 0x8009, 0xe9ea, 0x98c0, 0x6469, 0x6f10 }, 16, 0x0009f940, 1},
++	{{0xfac3, 0xc081, 0x94c0, 0xc2ff, 0x8413, 0x33e4, 0x2290, 0x8009, 0x31e4, 0x3ee2, 0x8009, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xceb4 }, 16, 0x0009f960, 1},
++	{{0x98c0, 0x01c6, 0x3100, 0x8008, 0xea48, 0x3c20, 0xa004, 0x32cb, 0x8041, 0xc183, 0x2d0d, 0x8078, 0x15d5, 0x38c8, 0x3c10, 0xbfff }, 16, 0x0009f980, 1},
++	{{0x3c80, 0xa000, 0x3b5b, 0x8000, 0xeded, 0x2000, 0x8080, 0x9ac0, 0x3453, 0x8000, 0xed3e, 0x2602, 0x8052, 0x3a40, 0xa000, 0x39a0 }, 16, 0x0009f9a0, 1},
++	{{0x3c00, 0x8008, 0xc685, 0x3826, 0xa000, 0xc490, 0x2202, 0x805c, 0x3e66, 0xa008, 0x90c0, 0xc587, 0x04c0, 0x38b2, 0x8008, 0x65e9 }, 16, 0x0009f9c0, 1},
++	{{0x3a40, 0xa000, 0x3111, 0x2000, 0x8000, 0xc286, 0x94c2, 0x5590, 0xc481, 0x96c1, 0xc582, 0x3acb, 0x82c0, 0x98c6, 0x3bc0, 0x22f2 }, 16, 0x0009f9e0, 1},
++	{{0x8008, 0xd643, 0x3a46, 0xa100, 0x90c0, 0xed3a, 0x38cd, 0x8743, 0x3675, 0x03c4, 0x38b2, 0x8008, 0x3e00, 0xa826, 0x2b0f, 0x8002 }, 16, 0x0009fa00, 1},
++	{{0x6c7d, 0x68b9, 0x6bae, 0xc843, 0x3e00, 0xb000, 0x7a61, 0x6aad, 0x3022, 0x336c, 0x8009, 0xc453, 0x3800, 0xa088, 0x7e42, 0x683d }, 16, 0x0009fa20, 1},
++	{{0xe8fc, 0x3600, 0xa100, 0xce44, 0xecfe, 0x90c0, 0xee19, 0x4196, 0x54da, 0x4413, 0x431f, 0x461f, 0x431f, 0x431f, 0x421f, 0x4217 }, 16, 0x0009fa40, 1},
++	{{0x14da, 0xef50, 0x96c0, 0x4417, 0x2f0e, 0x8002, 0x3420, 0xa000, 0x411e, 0x481e, 0x431e, 0x431e, 0x421e, 0x4216, 0x11da, 0xee50 }, 16, 0x0009fa60, 1},
++	{{0x96c0, 0x4116, 0x2e08, 0x8002, 0x3420, 0xa000, 0x4718, 0x3420, 0xa000, 0x4c18, 0x4318, 0x4318, 0x4218, 0x4210, 0x11d2, 0xe850 }, 16, 0x0009fa80, 1},
++	{{0x96c0, 0x4110, 0x2809, 0x8002, 0x0519, 0xf846, 0x3420, 0xa000, 0x4019, 0x4319, 0x4319, 0x4219, 0x3600, 0xa100, 0x4211, 0xefe9 }, 16, 0x0009faa0, 1},
++	{{0x36c0, 0xa100, 0x56d5, 0xef3e, 0x96c0, 0x3d1a, 0x80ff, 0xf947, 0x7d42, 0xc352, 0x90c0, 0x34a0, 0xa000, 0xeb18, 0x3480, 0xa000 }, 16, 0x0009fac0, 1},
++	{{0x5193, 0x3480, 0xa000, 0x4197, 0x56d5, 0x3d19, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x96c0, 0xf9c7, 0x2202, 0x804a, 0x3a20 }, 16, 0x0009fae0, 1},
++	{{0xa000, 0x0ec6, 0x38d0, 0x8008, 0xcdb6, 0x3680, 0xa100, 0xebe9, 0xefe9, 0x36a0, 0xa100, 0xeb3a, 0xee5e, 0x3680, 0xa100, 0x4013 }, 16, 0x0009fb00, 1},
++	{{0xef3d, 0x3a80, 0xa000, 0x51d6, 0x3022, 0x336c, 0x8009, 0x3c20, 0xa000, 0x2e0d, 0x8028, 0x90c0, 0x331b, 0x80ff, 0x7dc2, 0xc653 }, 16, 0x0009fb20, 1},
++	{{0x90c0, 0x34a0, 0xa000, 0xee18, 0x3480, 0xa000, 0x5296, 0x3480, 0xa000, 0x4297, 0x55d5, 0x3b1a, 0x80ff, 0x3244, 0x3d90, 0x800a }, 16, 0x0009fb40, 1},
++	{{0x7462, 0x3640, 0xa000, 0xf9c7, 0xcaae, 0x3820, 0xa000, 0x0bc6, 0x38d0, 0x8008, 0x98c0, 0xede9, 0x3622, 0x336c, 0x8009, 0x3860 }, 16, 0x0009fb60, 1},
++	{{0xa100, 0xed3a, 0x2b0f, 0x8020, 0x3600, 0xa100, 0x4015, 0xe8e9, 0x3680, 0xa100, 0x53d7, 0xe87a, 0x3c20, 0xa000, 0x2f0d, 0x8028 }, 16, 0x0009fb80, 1},
++	{{0x90c0, 0x371b, 0x80ff, 0x7dc2, 0xc453, 0x90c0, 0x34a0, 0xa000, 0xec1e, 0x3480, 0xa000, 0x5494, 0x3480, 0xa000, 0x4490, 0x51d5 }, 16, 0x0009fba0, 1},
++	{{0x331c, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7464, 0x3a40, 0xa000, 0xf9c7, 0x0dc6, 0x38d0, 0x8008, 0x3d20, 0x336c, 0x8009, 0x38c0 }, 16, 0x0009fbc0, 1},
++	{{0xa100, 0xefe9, 0x2d0a, 0x8022, 0x38c0, 0xa100, 0xef72, 0x2a08, 0x8028, 0x3680, 0xa000, 0x4017, 0xe942, 0x3680, 0xa000, 0x54d2 }, 16, 0x0009fbe0, 1},
++	{{0xf947, 0x391c, 0x80ff, 0x7e42, 0xc254, 0x90c0, 0x3480, 0xa000, 0xea1d, 0x3480, 0xa000, 0x5692, 0x4691, 0x3480, 0xa000, 0x51d0 }, 16, 0x0009fc00, 1},
++	{{0x331e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x3a40, 0xa000, 0xf9c7, 0x09c6, 0x38d0, 0x8008, 0x3622, 0x336c, 0x8009, 0x3600 }, 16, 0x0009fc20, 1},
++	{{0xa100, 0xe948, 0xe95c, 0x96c0, 0x4011, 0x2002, 0x8058, 0x3680, 0xa000, 0x51d1, 0xede9, 0x3ae0, 0xa000, 0x7ce8, 0xed38, 0x2909 }, 16, 0x0009fc40, 1},
++	{{0x8028, 0x3cc2, 0xf947, 0xc451, 0x90c0, 0x34a0, 0xa000, 0xec1e, 0x3480, 0xa000, 0x5594, 0x4595, 0x3480, 0xa000, 0x56d1, 0x3f68 }, 16, 0x0009fc60, 1},
++	{{0x3244, 0x3d90, 0x800a, 0x7466, 0x96c0, 0xf9c7, 0x2102, 0x8052, 0x3a20, 0xa000, 0x08c6, 0x38d0, 0x8008, 0xcdbc, 0x3a80, 0xa000 }, 16, 0x0009fc80, 1},
++	{{0xede9, 0x3222, 0x336c, 0x8009, 0x36a0, 0xa100, 0xed39, 0xe85e, 0x3480, 0xa000, 0x4015, 0x3680, 0xa100, 0x52d0, 0xede9, 0x3600 }, 16, 0x0009fca0, 1},
++	{{0xa100, 0x7d68, 0xed3d, 0x3840, 0xa000, 0x7d42, 0x280d, 0x8028, 0xc352, 0x90c0, 0x34a0, 0xa000, 0xeb1a, 0x3480, 0xa000, 0x5493 }, 16, 0x0009fcc0, 1},
++	{{0x3480, 0xa000, 0x4495, 0x54d5, 0x3e68, 0x3244, 0x3d90, 0x800a, 0x7464, 0x3640, 0xa000, 0xf9c7, 0xcab6, 0x3a20, 0xa000, 0x0ec6 }, 16, 0x0009fce0, 1},
++	{{0x38d0, 0x8008, 0xcda0, 0x3a80, 0xa000, 0xebe9, 0x3122, 0x336c, 0x8009, 0x38e0, 0xa100, 0xeb3a, 0x2e0d, 0x8020, 0x3680, 0xa100 }, 16, 0x0009fd00, 1},
++	{{0x4013, 0xece9, 0x3680, 0xa100, 0x54d5, 0xec3d, 0x3840, 0xa000, 0x7e68, 0x2d0d, 0x8028, 0x7e42, 0xc754, 0x90c0, 0x34a0, 0xa000 }, 16, 0x0009fd20, 1},
++	{{0xef19, 0x3480, 0xa000, 0x5697, 0x3480, 0xa000, 0x4694, 0x52d5, 0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x3a40, 0xa000, 0xf9c7 }, 16, 0x0009fd40, 1},
++	{{0x0ec6, 0x38d0, 0x8008, 0x3322, 0x336c, 0x8009, 0x3840, 0xa100, 0xede9, 0x2e0a, 0x8022, 0x3840, 0xa100, 0xed7a, 0x2a0c, 0x8028 }, 16, 0x0009fd60, 1},
++	{{0x4015, 0x3680, 0xa000, 0x54d2, 0xede9, 0x3e68, 0xed64, 0x7e42, 0xc554, 0x90c0, 0x34a0, 0xa000, 0xed1b, 0x3480, 0xa000, 0x5595 }, 16, 0x0009fd80, 1},
++	{{0x4595, 0x3480, 0xa000, 0x51d4, 0x3ce8, 0x3244, 0x3d90, 0x800a, 0x7461, 0x98c0, 0xf9c7, 0x0dc6, 0x38d0, 0x8008, 0x3bc0, 0x22f2 }, 16, 0x0009fda0, 1},
++	{{0x8008, 0x96c0, 0xe942, 0x2d0d, 0x8002, 0x4011, 0x56d5, 0x3d1a, 0x8040, 0x6569, 0x90c0, 0x94c3, 0x56d3, 0xc181, 0x96c3, 0x3d1d }, 16, 0x0009fdc0, 1},
++	{{0x80ff, 0xc081, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf502, 0xf501, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8002, 0x55d5 }, 16, 0x0009fde0, 1},
++	{{0x3b1a, 0x8080, 0x6569, 0x90c0, 0x94c3, 0x56d7, 0xc181, 0x96c3, 0x3d1a, 0x80ff, 0xc082, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3 }, 16, 0x0009fe00, 1},
++	{{0xf202, 0xf201, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8002, 0x52d5, 0x351b, 0x8100, 0x65e9, 0x90c0, 0x94c3, 0x55d6, 0xc181 }, 16, 0x0009fe20, 1},
++	{{0x96c3, 0x3b1c, 0x80ff, 0xc083, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf402, 0xf401, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xf8c6 }, 16, 0x0009fe40, 1},
++	{{0x90c0, 0xed42, 0x56d5, 0x3d1c, 0x8200, 0x6669, 0x90c0, 0x94c3, 0x53d0, 0xc084, 0x96c3, 0x371d, 0x80ff, 0xc181, 0x96c3, 0x32e4 }, 16, 0x0009fe60, 1},
++	{{0x2cb0, 0x8009, 0x94c3, 0xf501, 0xf502, 0x98c0, 0x3ec0, 0x29e0, 0x8008, 0xc684, 0x3fc0, 0x2d20, 0x8008, 0x3204, 0x2f80, 0x800b }, 16, 0x0009fe80, 1},
++	{{0xe8ee, 0x3204, 0x2e90, 0x800b, 0xe8ef, 0x9ac0, 0x2e0e, 0x80d0, 0x7b61, 0x2f0f, 0x80d0, 0x676a, 0x81e3, 0x98c0, 0xc281, 0x34a1 }, 16, 0x0009fea0, 1},
++	{{0x2000, 0x8008, 0x98c0, 0xc081, 0x02c1, 0x38ba, 0x8008, 0x32e4, 0x3050, 0x8009, 0x04c2, 0x3118, 0x8008, 0x32e4, 0x3050, 0x8009 }, 16, 0x0009fec0, 1},
++	{{0xc081, 0x01c5, 0x38bb, 0x8008, 0x36e1, 0x3d40, 0x3160, 0x8008, 0x3ec1, 0x04c5, 0x38bc, 0x8008, 0x9ac0, 0x6669, 0xc845, 0x01c5 }, 16, 0x0009fee0, 1},
++	{{0x38b8, 0x8008, 0x3661, 0x01c5, 0x38bb, 0x8008, 0x3761, 0xe81d, 0x5d10, 0xcd4a, 0x98c7, 0x02c0, 0x38ac, 0x8008, 0xedfc, 0x92c3 }, 16, 0x0009ff00, 1},
++	{{0xcd4a, 0x98c7, 0x6669, 0x02c0, 0x38ac, 0x8008, 0x8407, 0x6769, 0xd3da, 0x98c0, 0x7777, 0x74f2, 0xc0b0, 0xc290, 0x7656, 0x2c7d }, 16, 0x0009ff20, 1},
++	{{0x00c4, 0x38ae, 0x8008, 0x7754, 0x2e7c, 0x3224, 0x3880, 0x800a, 0xf601, 0x96c0, 0x7456, 0x27e8, 0x9fe0, 0xe7e8, 0x94c0, 0x9e21 }, 16, 0x0009ff40, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009ff60, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xc0a6, 0x270d, 0x8038, 0x32e4, 0x3a68, 0x8001, 0xe7ed, 0x98c0, 0x3e00 }, 16, 0x0009ff80, 1},
++	{{0x20ec, 0x8008, 0xc784, 0x38a8, 0x3c20, 0xbfff, 0x0226, 0x3350, 0x8009, 0x0296, 0x3d00, 0x20ec, 0x8008, 0x1a90, 0x3c00, 0x20ec }, 16, 0x0009ffa0, 1},
++	{{0x8008, 0x0a22, 0x3350, 0x8009, 0x1b95, 0x3dc0, 0x2282, 0x8008, 0x3ec0, 0x21c0, 0x8008, 0x98c0, 0xea3b, 0x32c2, 0x30d0, 0x8008 }, 16, 0x0009ffc0, 1},
++	{{0x3600, 0xa100, 0x4a94, 0xe8ed, 0x13d5, 0x0424, 0x3364, 0x8009, 0x9ac0, 0x371a, 0x8700, 0x7a41, 0x2d0a, 0x8004, 0x96c0, 0x3412 }, 16, 0x0009ffe0, 1},
++	{{0x8600, 0x5f12, 0x2618, 0x8168, 0x98c0, 0x0420, 0x3364, 0x8009, 0xc490, 0x98c0, 0xea44, 0x09c6, 0x3104, 0x8008, 0x1612, 0xc948 }, 16, 0x000a0000, 1},
++	{{0x9ac0, 0x676a, 0x05c4, 0x38b0, 0x8008, 0xeffc, 0x96c0, 0x6815, 0xef19, 0x841d, 0x96c0, 0x9b46, 0x2b03, 0x800a, 0xc840, 0x521f }, 16, 0x000a0020, 1},
++	{{0x92d0, 0x421e, 0x5718, 0x471e, 0x9ac0, 0x2a08, 0x8014, 0x90c0, 0x2a0b, 0x8018, 0x14d0, 0xc194, 0x96c0, 0x391e, 0x8700, 0x5813 }, 16, 0x000a0040, 1},
++	{{0x96c0, 0x3416, 0x8600, 0xeb44, 0x94c0, 0x5213, 0x843f, 0x9ac0, 0x656a, 0x0fc6, 0x3104, 0x8008, 0xe8fc, 0x98c0, 0xcf4e, 0x07c4 }, 16, 0x000a0060, 1},
++	{{0x38b0, 0x8008, 0x8422, 0x9ac0, 0x6b07, 0xe81f, 0x3bc0, 0x2040, 0x8008, 0x96c0, 0x9b42, 0x2b03, 0x800a, 0xcf46, 0x5418, 0x92d0 }, 16, 0x000a0080, 1},
++	{{0x441b, 0x541f, 0x441b, 0x9ac0, 0x2a09, 0x8030, 0x90c0, 0x2a08, 0x8034, 0x12d1, 0xc798, 0x96c0, 0x351e, 0x8700, 0x5c10, 0x96c0 }, 16, 0x000a00a0, 1},
++	{{0x3416, 0x8600, 0xe844, 0x94c0, 0x5310, 0x843f, 0x9ac0, 0x65ea, 0x0bc6, 0x3104, 0x8008, 0xecfc, 0x98c0, 0xcb49, 0x05c4, 0x38b0 }, 16, 0x000a00c0, 1},
++	{{0x8008, 0x8422, 0x9ac0, 0x689b, 0xec1b, 0x38a0, 0x3e00, 0x8008, 0x96c0, 0x9b43, 0x2b03, 0x800a, 0xcf41, 0x551c, 0x92d0, 0x4518 }, 16, 0x000a00e0, 1},
++	{{0x551f, 0x4518, 0x9ac0, 0x2a09, 0x804c, 0x90c0, 0x2a0c, 0x8050, 0x15d1, 0xc09c, 0x96c0, 0x3b1d, 0x8700, 0x5914, 0x96c0, 0x3415 }, 16, 0x000a0100, 1},
++	{{0x8600, 0xec44, 0x96c0, 0x5214, 0x2718, 0x8148, 0x9ac0, 0x656a, 0x0cc6, 0x3104, 0x8008, 0xe9fc, 0x98c0, 0xcc4e, 0x07c4, 0x38b0 }, 16, 0x000a0120, 1},
++	{{0x8008, 0x2618, 0x812a, 0x9ac0, 0x6b03, 0xe91c, 0x3fa0, 0x3f80, 0x8008, 0x96c0, 0x9b42, 0x2b03, 0x800a, 0xc846, 0x5419, 0x92d0 }, 16, 0x000a0140, 1},
++	{{0x441f, 0x5618, 0x461f, 0x3104, 0x226c, 0x800a, 0x96c0, 0xfd45, 0x2d0e, 0x8008, 0x3a80, 0xa000, 0xe9ee, 0x3fc0, 0x26a0, 0x8008 }, 16, 0x000a0160, 1},
++	{{0x3480, 0xa000, 0xe964, 0x3680, 0xa100, 0x51d0, 0x5b11, 0x98c0, 0x331e, 0x8700, 0x5416, 0x5316, 0x3880, 0xa000, 0x3416, 0x8400 }, 16, 0x000a0180, 1},
++	{{0x5a92, 0x848d, 0x9ac0, 0x666a, 0xebfc, 0x0cc6, 0x3104, 0x8008, 0x8417, 0x9f44, 0x98c0, 0x3ac0, 0x34dc, 0x8008, 0xeb1c, 0x90c0 }, 16, 0x000a01a0, 1},
++	{{0x92d0, 0x90a3, 0x401a, 0x98c0, 0x00c4, 0x38b4, 0x8008, 0xff42, 0x94c0, 0xf402, 0xf001, 0x3a40, 0xa000, 0x39c0, 0x359c, 0x8008 }, 16, 0x000a01c0, 1},
++	{{0xf946, 0x98c0, 0xc25e, 0x3204, 0x2fd0, 0x800b, 0x3a40, 0xa000, 0x38c0, 0x34dc, 0x8008, 0xf847, 0x1816, 0xc256, 0x3640, 0xa000 }, 16, 0x000a01e0, 1},
++	{{0xc84c, 0xf9c6, 0x3c00, 0xa100, 0x7e41, 0x5b92, 0x38c0, 0x359c, 0x8008, 0x3640, 0xa000, 0x666a, 0xf8c7, 0x8431, 0x9f44, 0x90c0 }, 16, 0x000a0200, 1},
++	{{0x90c0, 0x92d0, 0x5518, 0x451b, 0x3104, 0x224a, 0x800a, 0x9ac0, 0x65ea, 0x08c6, 0x3104, 0x8008, 0xebfc, 0x8410, 0xeb18, 0x9f43 }, 16, 0x000a0220, 1},
++	{{0x90c0, 0x90c0, 0x92d0, 0x531b, 0x431a, 0x3880, 0xa000, 0x7be1, 0xee5c, 0xe85c, 0x3a00, 0xa100, 0x67ea, 0xe95c, 0x2f0f, 0x80d0 }, 16, 0x000a0240, 1},
++	{{0x3880, 0xa000, 0xea44, 0x2dff, 0x9f27, 0xfdc5, 0x98c0, 0x05c4, 0x38ae, 0x8008, 0xc684, 0x98c0, 0xd2a8, 0x3ec0, 0x30d0, 0x8008 }, 16, 0x000a0260, 1},
++	{{0x8431, 0x98c0, 0x3f20, 0x2528, 0x8009, 0xfd45, 0x92c0, 0x90c0, 0x189f, 0xc390, 0x3224, 0x3a38, 0x800a, 0x1996, 0xf301, 0x9760 }, 16, 0x000a0280, 1},
++	{{0x5b9e, 0x92d0, 0x5718, 0x471b, 0x7b61, 0x676a, 0x81e5, 0xfdc5, 0x98c0, 0x0425, 0x336a, 0x8009, 0xfd45, 0x75e4, 0xd1a1, 0x90c0 }, 16, 0x000a02a0, 1},
++	{{0x96c2, 0x3344, 0x3ad0, 0x800a, 0x94c0, 0xfdc5, 0xc684, 0x94c0, 0xc189, 0xf648, 0x3800, 0xa100, 0xf149, 0x2d0c, 0x8002, 0x3840 }, 16, 0x000a02c0, 1},
++	{{0xa000, 0xc781, 0x2c0e, 0x8004, 0x2e0f, 0x800c, 0x3680, 0xa000, 0x2f09, 0x8004, 0x3aa0, 0xa000, 0xeee9, 0x3222, 0x2538, 0x8009 }, 16, 0x000a02e0, 1},
++	{{0x3a80, 0xa000, 0xee68, 0x30c2, 0x2360, 0x8008, 0x15d5, 0x5b16, 0x3a80, 0xa100, 0x3b1d, 0x8700, 0x5996, 0x5851, 0x98c0, 0x3415 }, 16, 0x000a0300, 1},
++	{{0x8400, 0xebfc, 0x5697, 0x94c0, 0xcb4c, 0x84e1, 0x98c0, 0xf642, 0x38c0, 0x2100, 0x8008, 0x94c0, 0xf105, 0xf001, 0x94c0, 0xf406 }, 16, 0x000a0320, 1},
++	{{0xf707, 0x3640, 0xa000, 0xfd45, 0xf84a, 0x3660, 0xa000, 0xfc4b, 0xf94c, 0x32e4, 0x208e, 0x800a, 0x3620, 0xa000, 0xfe4d, 0xc25e }, 16, 0x000a0340, 1},
++	{{0x3640, 0xa000, 0x5816, 0xf8ca, 0x98c0, 0xc84c, 0x3cc0, 0x2100, 0x8008, 0x7e41, 0x266a, 0x36d4, 0xe8ec, 0x96c0, 0x76c5, 0x5858 }, 16, 0x000a0360, 1},
++	{{0x8425, 0x3ae1, 0x3c62, 0x7ce2, 0x9f45, 0x90c0, 0x2103, 0x8010, 0x94d0, 0x485c, 0x5858, 0x3c62, 0x7ce2, 0xc781, 0x4854, 0x3620 }, 16, 0x000a0380, 1},
++	{{0xa000, 0xf842, 0xf441, 0x39c0, 0x371c, 0x8008, 0x3204, 0x2ee0, 0x800b, 0x38c0, 0x2100, 0x8008, 0x3a20, 0xa000, 0xfccb, 0x0bc6 }, 16, 0x000a03a0, 1},
++	{{0x3104, 0x8008, 0x3620, 0xa000, 0xf8ca, 0x5316, 0x3820, 0xa100, 0x65ea, 0x5814, 0xf9cc, 0x3620, 0xa000, 0xfecd, 0xfdc5, 0x94c0 }, 16, 0x000a03c0, 1},
++	{{0xe8fc, 0xc256, 0x96c0, 0xe81b, 0x2718, 0x81ea, 0x9f43, 0x3bc0, 0x371c, 0x8008, 0x90c0, 0x92d0, 0x511b, 0x9180, 0x98c0, 0xc781 }, 16, 0x000a03e0, 1},
++	{{0x3104, 0x25ce, 0x800a, 0x3a00, 0xa100, 0x3415, 0x8600, 0x5a16, 0x5996, 0x3680, 0xa000, 0x5851, 0x84b1, 0x1697, 0xeafc, 0x94c0 }, 16, 0x000a0400, 1},
++	{{0xca4c, 0xf642, 0x94c0, 0xf001, 0xf406, 0x98c0, 0x38c0, 0x2100, 0x8008, 0xf105, 0x94c0, 0xf707, 0xfd45, 0x3660, 0xa000, 0xf84a }, 16, 0x000a0420, 1},
++	{{0xfc4b, 0x98c0, 0xc25e, 0x32e4, 0x208e, 0x800a, 0x3660, 0xa000, 0xf94c, 0xfe4d, 0x3620, 0xa000, 0xfccb, 0xc256, 0x98c0, 0x06c4 }, 16, 0x000a0440, 1},
++	{{0x38b0, 0x8008, 0xf3c9, 0x3c00, 0xa100, 0x6b2e, 0x5c14, 0x0bc6, 0x3104, 0x8008, 0x3640, 0xa000, 0xc946, 0xf9cc, 0x1516, 0xecfc }, 16, 0x000a0460, 1},
++	{{0x96c0, 0x66ea, 0xe9fc, 0xfdc5, 0x3a20, 0xa000, 0xf8ca, 0x3ac0, 0x2100, 0x8008, 0x96c0, 0xe91b, 0x2618, 0x813a, 0x3620, 0xa000 }, 16, 0x000a0480, 1},
++	{{0xfecd, 0xec1b, 0x96c0, 0x9b45, 0x2b03, 0x800a, 0x90c0, 0x551a, 0x92d0, 0x451c, 0x531a, 0x4319, 0x98c0, 0xc781, 0x3104, 0x25ce }, 16, 0x000a04a0, 1},
++	{{0x800a, 0x1616, 0x01c4, 0x38ae, 0x8008, 0x3800, 0xa100, 0xd0a8, 0x5996, 0x5597, 0x94c6, 0x84a1, 0x7f41, 0x3680, 0xa000, 0x5851 }, 16, 0x000a04c0, 1},
++	{{0xf606, 0x94c0, 0xf542, 0xf707, 0x94c0, 0xf105, 0xf001, 0x98c0, 0x38c0, 0x2100, 0x8008, 0xfd45, 0x3660, 0xa000, 0xf84a, 0xfc4b }, 16, 0x000a04e0, 1},
++	{{0x98c0, 0xc25e, 0x32e4, 0x208e, 0x800a, 0x3660, 0xa000, 0xf94c, 0xfe4d, 0x94c0, 0xc256, 0xc290, 0x98c0, 0xf201, 0x39c0, 0x2100 }, 16, 0x000a0500, 1},
++	{{0x8008, 0x3224, 0x3990, 0x800a, 0x3480, 0xa000, 0x5892, 0x3620, 0xa000, 0xfccb, 0xc256, 0x3a20, 0xa000, 0xf8ca, 0x0ac6, 0x3104 }, 16, 0x000a0520, 1},
++	{{0x8008, 0x3680, 0xa100, 0x5c14, 0x5892, 0x9750, 0x94c0, 0xe84c, 0xecfc, 0x3640, 0xa000, 0x5b90, 0xfecd, 0x3640, 0xa000, 0xfdc5 }, 16, 0x000a0540, 1},
++	{{0xf9cc, 0xec1a, 0x92d0, 0x531b, 0x431c, 0x98c0, 0xc781, 0x3104, 0x25ce, 0x800a, 0x3a80, 0xa000, 0x5814, 0x0bc6, 0x3104, 0x8008 }, 16, 0x000a0560, 1},
++	{{0x3680, 0xa000, 0x5851, 0xf606, 0x94c0, 0xe8fc, 0xf105, 0x94c0, 0xf542, 0xf001, 0x94c0, 0xe81b, 0xf707, 0x3640, 0xa000, 0xfd45 }, 16, 0x000a0580, 1},
++	{{0xf84a, 0x3660, 0xa000, 0xfc4b, 0xf94c, 0x32e4, 0x208e, 0x800a, 0x3620, 0xa000, 0xfe4d, 0xc25e, 0x94c0, 0xfdc5, 0xc256, 0x3660 }, 16, 0x000a05a0, 1},
++	{{0xa000, 0xf8ca, 0xfccb, 0x3660, 0xa000, 0xf9cc, 0xfecd, 0x94c0, 0xf2c8, 0xf3c9, 0x3a00, 0xa100, 0x7961, 0x79c2, 0xed5c, 0xee5c }, 16, 0x000a05c0, 1},
++	{{0x3880, 0xa000, 0x656a, 0xf349, 0xe95c, 0x94c0, 0xef5c, 0xf248, 0x3600, 0xa100, 0xee5c, 0xec5c, 0x2cff, 0x9d15, 0x38c0, 0xa100 }, 16, 0x000a05e0, 1},
++	{{0xea44, 0x2808, 0x80d0, 0x9ac0, 0x6c10, 0x39e8, 0x2c0c, 0xbfff, 0xc181, 0x0bc6, 0x310c, 0x8008, 0x1491, 0x36a1, 0x2800, 0x8008 }, 16, 0x000a0600, 1},
++	{{0x96c0, 0x38cd, 0x8200, 0xeb41, 0x66e9, 0x8429, 0x01c1, 0x38b6, 0x8008, 0x0bc2, 0x310c, 0x8008, 0x32e4, 0x3050, 0x8009, 0x06c2 }, 16, 0x000a0620, 1},
++	{{0x3104, 0x8008, 0x32e4, 0x3050, 0x8009, 0x6c10, 0x3104, 0x265a, 0x800a, 0x32e4, 0x3050, 0x8009, 0x6c10, 0x27e9, 0x9fc8, 0xe7e9 }, 16, 0x000a0640, 1},
++	{{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0660, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xc0a2, 0x270b, 0x8038, 0x32e4, 0x3a68, 0x8001, 0xe7eb, 0x98c0, 0x38a8 }, 16, 0x000a0680, 1},
++	{{0x3c20, 0xbfff, 0xc090, 0x0e26, 0x3350, 0x8009, 0x1990, 0x3c00, 0x20f8, 0x8008, 0x0922, 0x335c, 0x8009, 0x98c0, 0xe93e, 0x36c2 }, 16, 0x000a06a0, 1},
++	{{0x22f2, 0x8008, 0x0994, 0x3ac0, 0x341c, 0x8008, 0x3a80, 0xa000, 0x55d6, 0x0324, 0x3366, 0x8009, 0x3e60, 0xa100, 0x2e0e, 0x8004 }, 16, 0x000a06c0, 1},
++	{{0x79c1, 0x3b1a, 0x8700, 0xe8ee, 0x3c40, 0xa000, 0x3412, 0x8600, 0x5916, 0x2e0f, 0x8008, 0x2618, 0x8140, 0x98c0, 0x0320, 0x3366 }, 16, 0x000a06e0, 1},
++	{{0x8009, 0xee44, 0x1116, 0x0dc6, 0x3118, 0x8008, 0x96c0, 0x64ea, 0xcd4d, 0xe9fc, 0x98c0, 0x07c4, 0x38b2, 0x8008, 0xe91d, 0x94c0 }, 16, 0x000a0700, 1},
++	{{0x6a83, 0x841b, 0x96c0, 0x9b41, 0x2b03, 0x800a, 0xcb45, 0x5519, 0x92d0, 0x451a, 0x501b, 0x401a, 0x9ac0, 0x2e08, 0x8014, 0x90c0 }, 16, 0x000a0720, 1},
++	{{0x2e0c, 0x8018, 0x12d0, 0xc094, 0x96c0, 0x351c, 0x8700, 0x5f14, 0x98c0, 0x3414, 0x8600, 0xec44, 0xcd4c, 0x96c0, 0x6a03, 0x5514 }, 16, 0x000a0740, 1},
++	{{0x842f, 0x9ac0, 0x66ea, 0xeffc, 0x38c0, 0x37dc, 0x8008, 0x94c0, 0xef1d, 0x841b, 0x96c0, 0x9b45, 0x2b03, 0x800a, 0xc944, 0x561f }, 16, 0x000a0760, 1},
++	{{0x92d0, 0x4618, 0x5619, 0x4618, 0x9ac0, 0x2e09, 0x8030, 0x90c0, 0x2e08, 0x8034, 0x13d1, 0xc698, 0x98c0, 0x371b, 0x8700, 0x5b10 }, 16, 0x000a0780, 1},
++	{{0xcd48, 0x98c0, 0x3413, 0x8600, 0x681f, 0xe844, 0x94c0, 0x5110, 0x842d, 0x9ac0, 0x64ea, 0xebfc, 0x3ac0, 0x311c, 0x8008, 0x94c0 }, 16, 0x000a07a0, 1},
++	{{0xeb1d, 0x841b, 0x96c0, 0x9b41, 0x2b03, 0x800a, 0xc840, 0x501b, 0x92d0, 0x401a, 0x5618, 0x461a, 0x96c0, 0xc69c, 0x2e0b, 0x804c }, 16, 0x000a07c0, 1},
++	{{0x15d3, 0x38c0, 0x22da, 0x8008, 0x9ac0, 0x2e0b, 0x8054, 0x90c0, 0x3b19, 0x8700, 0x98c0, 0x3411, 0x8600, 0xcd49, 0x5c10, 0x98c0 }, 16, 0x000a07e0, 1},
++	{{0x689f, 0x5413, 0x2718, 0x812e, 0x9ac0, 0x666a, 0xecfc, 0x3bc0, 0x31dc, 0x8008, 0x96c0, 0xec1d, 0x2718, 0x8118, 0x96c0, 0x9b44 }, 16, 0x000a0800, 1},
++	{{0x2b03, 0x800a, 0xc941, 0x541c, 0x92d0, 0x441b, 0x5019, 0x401b, 0x3104, 0x292c, 0x800a, 0x94c0, 0xedef, 0xc784, 0x98c0, 0x3bc0 }, 16, 0x000a0820, 1},
++	{{0x3090, 0x8008, 0xed64, 0x3a40, 0xa000, 0x3ec0, 0x29e0, 0x8008, 0xfe45, 0x3680, 0xa000, 0x51d0, 0x5815, 0x98c0, 0x331b, 0x8700 }, 16, 0x000a0840, 1},
++	{{0x5217, 0x5117, 0x96c0, 0x3413, 0x8400, 0x5a93, 0x8485, 0x9ac0, 0x656a, 0xe8fc, 0x0cc6, 0x3118, 0x8008, 0x8417, 0x9f42, 0x98c0 }, 16, 0x000a0860, 1},
++	{{0x3ac0, 0x335c, 0x8008, 0xe81c, 0x90c0, 0x92d0, 0x93a0, 0x431a, 0x98c0, 0x05c4, 0x38b4, 0x8008, 0xfe42, 0x94c0, 0xf202, 0xf501 }, 16, 0x000a0880, 1},
++	{{0x98c0, 0x39c0, 0x329c, 0x8008, 0xfd46, 0x98c0, 0xcb4e, 0x3204, 0x2fd0, 0x800b, 0x3a40, 0xa000, 0x38c0, 0x335c, 0x8008, 0xf847 }, 16, 0x000a08a0, 1},
++	{{0x1c17, 0xcb46, 0x94c0, 0xcc49, 0xfdc6, 0x3cc1, 0x1a93, 0x3cc0, 0x329c, 0x8008, 0x3640, 0xa000, 0x64ea, 0xf8c7, 0x8431, 0x9f41 }, 16, 0x000a08c0, 1},
++	{{0x90c0, 0x90c0, 0x92d0, 0x541c, 0x441a, 0x3104, 0x290c, 0x800a, 0x9ac0, 0x64ea, 0x0cc6, 0x3118, 0x8008, 0xe8fc, 0x8410, 0xe81c }, 16, 0x000a08e0, 1},
++	{{0x9f41, 0x90c0, 0x90c0, 0x92d0, 0x5218, 0x421a, 0x3880, 0xa000, 0x7be1, 0xef5c, 0xe85c, 0x98c0, 0x67ea, 0xed5c, 0x2e0e, 0x80d0 }, 16, 0x000a0900, 1},
++	{{0x94c0, 0xeb44, 0x8133, 0x3420, 0xa000, 0xfec5, 0x06c4, 0x38ac, 0x8008, 0x9ac0, 0xd328, 0xc684, 0x3ec0, 0x3090, 0x8008, 0x8437 }, 16, 0x000a0920, 1},
++	{{0x3a40, 0xa000, 0x3f20, 0x2548, 0x8009, 0xfe45, 0x92c0, 0x90c0, 0x189f, 0xc590, 0x3224, 0x3a38, 0x800a, 0x1996, 0xf501, 0x9760 }, 16, 0x000a0940, 1},
++	{{0x5c9e, 0x92d0, 0x5718, 0x471c, 0x7b61, 0x676a, 0x81e5, 0x3420, 0xa000, 0xfec5, 0x3a40, 0xa000, 0x0425, 0x336a, 0x8009, 0xfe45 }, 16, 0x000a0960, 1},
++	{{0x7764, 0xd325, 0x90c0, 0x96c2, 0x3344, 0x3ad0, 0x800a, 0x3620, 0xa000, 0xfec5, 0xc584, 0x94c0, 0xc489, 0xf548, 0x3840, 0xa100 }, 16, 0x000a0980, 1},
++	{{0xf449, 0x2e0a, 0x8002, 0x3840, 0xa000, 0xc781, 0x2a0e, 0x8004, 0x2e0f, 0x800c, 0x3680, 0xa000, 0x2f0f, 0x8004, 0x3aa0, 0xa000 }, 16, 0x000a09a0, 1},
++	{{0xebef, 0x3522, 0x2558, 0x8009, 0x3a80, 0xa000, 0xeb68, 0x34c2, 0x2d20, 0x8008, 0x3680, 0xa000, 0x52d6, 0x5a16, 0x3a80, 0xa000 }, 16, 0x000a09c0, 1},
++	{{0x3518, 0x8700, 0x5993, 0x5497, 0x96c0, 0x3410, 0x8400, 0xeafc, 0x96c0, 0xca4d, 0x2718, 0x80ec, 0x3a80, 0xa000, 0x5857, 0x38a0 }, 16, 0x000a09e0, 1},
++	{{0x3ec0, 0x8008, 0x94c0, 0xf105, 0xf001, 0x94c0, 0xf506, 0xf707, 0x3640, 0xa000, 0xf442, 0xfe45, 0x3660, 0xa000, 0xfd4a, 0xfc4b }, 16, 0x000a0a00, 1},
++	{{0x3660, 0xa000, 0xfa4c, 0xff4d, 0x32e4, 0x208e, 0x800a, 0x3420, 0xa000, 0xfb4e, 0x3640, 0xa000, 0x5816, 0xfccb, 0x98c0, 0xc84a }, 16, 0x000a0a20, 1},
++	{{0x38a0, 0x3ec0, 0x8008, 0x7d41, 0x256a, 0x3652, 0xece8, 0x96c0, 0x7644, 0x585c, 0x8425, 0x3a61, 0x3c62, 0x7ce2, 0x9f44, 0x90c0 }, 16, 0x000a0a40, 1},
++	{{0x2103, 0x8010, 0x94d0, 0x4858, 0x585c, 0x3c62, 0x7ce2, 0xc781, 0x4850, 0x3620, 0xa000, 0xfc42, 0xf241, 0x39c0, 0x365c, 0x8008 }, 16, 0x000a0a60, 1},
++	{{0x3204, 0x2ee0, 0x800b, 0x38a0, 0x3ec0, 0x8008, 0x3a20, 0xa000, 0xfacc, 0x0dc6, 0x3118, 0x8008, 0x3620, 0xa000, 0xfccb, 0x5616 }, 16, 0x000a0a80, 1},
++	{{0x3820, 0xa100, 0x676a, 0x5c12, 0xffcd, 0x3660, 0xa000, 0xfbce, 0xfec5, 0x3640, 0xa000, 0xecfc, 0xfdca, 0x96c0, 0xec1d, 0x2718 }, 16, 0x000a0aa0, 1},
++	{{0x81fc, 0x9f46, 0x3dc0, 0x365c, 0x8008, 0x90c0, 0x92d0, 0x501d, 0x9084, 0x98c0, 0xc781, 0x3104, 0x2cb6, 0x800a, 0x3a00, 0xa100 }, 16, 0x000a0ac0, 1},
++	{{0x3410, 0x8600, 0x5d16, 0x5993, 0x3680, 0xa000, 0x5857, 0x84bb, 0x1297, 0xedfc, 0x98c0, 0xcd4c, 0x38a0, 0x3ec0, 0x8008, 0x94c0 }, 16, 0x000a0ae0, 1},
++	{{0xf001, 0xf406, 0x94c0, 0xf105, 0xf707, 0x3640, 0xa000, 0xf242, 0xfe45, 0x3660, 0xa000, 0xfd4a, 0xfc4b, 0x3660, 0xa000, 0xfa4c }, 16, 0x000a0b00, 1},
++	{{0xff4d, 0x32e4, 0x208e, 0x800a, 0x3420, 0xa000, 0xfb4e, 0x3a20, 0xa000, 0xfacc, 0x05c4, 0x38b2, 0x8008, 0x98c0, 0xf0c9, 0x08c6 }, 16, 0x000a0b20, 1},
++	{{0x3118, 0x8008, 0x3820, 0xa100, 0x6a21, 0x5d12, 0xfdca, 0x1316, 0xca44, 0x3820, 0xa000, 0x65ea, 0xedfc, 0xfec5, 0x3640, 0xa000 }, 16, 0x000a0b40, 1},
++	{{0xeafc, 0xfbce, 0x3a20, 0xa000, 0xffcd, 0x3ba0, 0x3ec0, 0x8008, 0x96c0, 0xea18, 0x2618, 0x8146, 0x3620, 0xa000, 0xfccb, 0xed18 }, 16, 0x000a0b60, 1},
++	{{0x96c0, 0x9b43, 0x2b03, 0x8010, 0x90c0, 0x94c0, 0x90c0, 0x90c0, 0x92d0, 0x585b, 0x401d, 0x411a, 0x98c0, 0xc781, 0x3104, 0x2cb6 }, 16, 0x000a0b80, 1},
++	{{0x800a, 0x1216, 0x06c4, 0x38ac, 0x8008, 0x3800, 0xa100, 0xd328, 0x5993, 0x5497, 0x94c6, 0x84a7, 0x7d41, 0x3680, 0xa000, 0x5857 }, 16, 0x000a0ba0, 1},
++	{{0xf442, 0x94c0, 0xf707, 0xf206, 0x94c0, 0xf105, 0xf001, 0x3a40, 0xa000, 0x38a0, 0x3ec0, 0x8008, 0xfe45, 0x3660, 0xa000, 0xfd4a }, 16, 0x000a0bc0, 1},
++	{{0xfc4b, 0x3660, 0xa000, 0xfa4c, 0xff4d, 0x32e4, 0x208e, 0x800a, 0x3420, 0xa000, 0xfb4e, 0x3620, 0xa000, 0xfdca, 0xc690, 0x98c0 }, 16, 0x000a0be0, 1},
++	{{0xf601, 0x39a0, 0x3ec0, 0x8008, 0x3224, 0x3990, 0x800a, 0x3480, 0xa000, 0x5895, 0x3660, 0xa000, 0xfdca, 0xfacc, 0x3a20, 0xa000 }, 16, 0x000a0c00, 1},
++	{{0xfccb, 0x08c6, 0x3118, 0x8008, 0x3680, 0xa100, 0x5c12, 0x5d95, 0x9750, 0x94c0, 0xed4c, 0xecfc, 0x3640, 0xa000, 0x5995, 0xfbce }, 16, 0x000a0c20, 1},
++	{{0x3660, 0xa000, 0xfec5, 0xffcd, 0xec18, 0x92d0, 0x5219, 0x421c, 0x98c0, 0xc781, 0x3104, 0x2cb6, 0x800a, 0x3a80, 0xa000, 0x5812 }, 16, 0x000a0c40, 1},
++	{{0x0dc6, 0x3118, 0x8008, 0x3680, 0xa000, 0x5857, 0xf206, 0x94c0, 0xe8fc, 0xf105, 0x94c0, 0xf442, 0xf001, 0x94c0, 0xe81d, 0xf707 }, 16, 0x000a0c60, 1},
++	{{0x3660, 0xa000, 0xfe45, 0xfd4a, 0x3660, 0xa000, 0xfc4b, 0xfa4c, 0x32e4, 0x208e, 0x800a, 0x3660, 0xa000, 0xff4d, 0xfb4e, 0x3660 }, 16, 0x000a0c80, 1},
++	{{0xa000, 0xfec5, 0xfdca, 0x3660, 0xa000, 0xfccb, 0xfacc, 0x3660, 0xa000, 0xffcd, 0xfbce, 0x94c0, 0xf1c8, 0xf0c9, 0x3a80, 0xa100 }, 16, 0x000a0ca0, 1},
++	{{0x78e1, 0x7842, 0xee5c, 0xeb5c, 0x3880, 0xa000, 0x64ea, 0xf049, 0xef5c, 0x94c0, 0xef5c, 0xf148, 0x3600, 0xa100, 0xee5c, 0xea5c }, 16, 0x000a0cc0, 1},
++	{{0x2cff, 0x9cf5, 0x38c0, 0xa100, 0xed44, 0x2c0c, 0x80d0, 0x98c0, 0x39e8, 0x280c, 0xbfff, 0xc081, 0x0fc6, 0x3114, 0x8008, 0x1291 }, 16, 0x000a0ce0, 1},
++	{{0x34a1, 0x2000, 0x8008, 0x96c0, 0x34ce, 0x8200, 0xef41, 0x2769, 0xc681, 0x8429, 0x06c1, 0x38ba, 0x8008, 0x0fc2, 0x3114, 0x8008 }, 16, 0x000a0d00, 1},
++	{{0x32e4, 0x3050, 0x8009, 0x04c2, 0x3118, 0x8008, 0x32e4, 0x3050, 0x8009, 0xc081, 0x3104, 0x2d42, 0x800a, 0x32e4, 0x3050, 0x8009 }, 16, 0x000a0d20, 1},
++	{{0xc081, 0x27e8, 0x9fc8, 0xe7e8, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0d40, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0d60, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3ce8, 0x2404, 0xbfff, 0xc090, 0x21e0, 0x83ff, 0x1294 }, 16, 0x000a0d80, 1},
++	{{0x3900, 0x2de0, 0x800a, 0x98c0, 0xdc82, 0x32e4, 0x3a5c, 0x8001, 0x4194, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc186, 0xc090, 0x32e4 }, 16, 0x000a0da0, 1},
++	{{0x3a5c, 0x8001, 0x98c0, 0x3900, 0x2ec0, 0x800a, 0xc08c, 0x30e4, 0x3a62, 0x8001, 0x94c0, 0xc186, 0xc08c, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0dc0, 1},
++	{{0x96c0, 0x7468, 0x9620, 0x9720, 0x32e4, 0x3a68, 0x8001, 0x94c0, 0x9e20, 0x9f20, 0x3d00, 0x20e4, 0x8008, 0x3ec0, 0x30f8, 0x8008 }, 16, 0x000a0de0, 1},
++	{{0x15d5, 0x3bc8, 0x3c14, 0xbfff, 0x3ac1, 0x3900, 0x2040, 0x8008, 0x2c10, 0x0515, 0x3a00, 0x2040, 0x8008, 0x5f96, 0x90c0, 0xef41 }, 16, 0x000a0e00, 1},
++	{{0x4f96, 0x5293, 0x96c0, 0x350c, 0x8400, 0x52d1, 0x9cc0, 0x351b, 0x8fff, 0x6669, 0x35ff, 0x90ff, 0xc481, 0x96c0, 0x3706, 0x9000 }, 16, 0x000a0e20, 1},
++	{{0x806d, 0x32e4, 0x2290, 0x8009, 0x4612, 0x32e4, 0x2290, 0x8009, 0xc081, 0x32e4, 0x3a7a, 0x8001, 0xc0aa, 0x32e4, 0x3a7a, 0x8001 }, 16, 0x000a0e40, 1},
++	{{0xc0ac, 0x32e4, 0x3a7a, 0x8001, 0xc0a2, 0x32e4, 0x3a7a, 0x8001, 0xc0a6, 0x32e4, 0x3a7a, 0x8001, 0xc0b2, 0x32e4, 0x3a7a, 0x8001 }, 16, 0x000a0e60, 1},
++	{{0xc0b4, 0x32e4, 0x3a7a, 0x8001, 0xc0b6, 0x32e4, 0x3a7a, 0x8001, 0xc0ae, 0x3de8, 0x3c0c, 0xbfff, 0x3001, 0x2ccc, 0x8f58, 0x0095 }, 16, 0x000a0e80, 1},
++	{{0x3104, 0x2eb2, 0x800a, 0x3f03, 0x8300, 0x4312, 0x04c1, 0x38d5, 0x8008, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000a0ea0, 1},
++	{{0x98c0, 0x7750, 0x7468, 0x9620, 0x9720, 0x32e4, 0x3a68, 0x8001, 0x94c0, 0x9e20, 0x9f20, 0x2d90, 0x3dc8, 0x3c14, 0xbfff, 0x3453 }, 16, 0x000a0ec0, 1},
++	{{0x34d3, 0x38c0, 0x2040, 0x8008, 0x1795, 0x3dc0, 0x21c0, 0x8008, 0x3f0a, 0x8100, 0x2569, 0x3553, 0x3ea0, 0x3e00, 0x8008, 0x8019 }, 16, 0x000a0ee0, 1},
++	{{0x9758, 0x39a0, 0x3f80, 0x8008, 0x90c0, 0x94d0, 0xc819, 0xc81e, 0x94c0, 0xc818, 0xc81d, 0x2760, 0x3ec8, 0x3c18, 0xbfff, 0xd32c }, 16, 0x000a0f00, 1},
++	{{0x8435, 0x1796, 0x3ac8, 0x3c10, 0xbfff, 0x3f1d, 0x8003, 0x66e9, 0x8425, 0x5092, 0x310b, 0x8800, 0x65e9, 0x90c0, 0x96c2, 0x3ce8 }, 16, 0x000a0f20, 1},
++	{{0x3c04, 0xbfff, 0x90c0, 0x92c2, 0x5294, 0x94c2, 0x0992, 0xa000, 0x92c2, 0x4294, 0x98c0, 0xc946, 0x3bc0, 0x30f0, 0x8008, 0x90c0 }, 16, 0x000a0f40, 1},
++	{{0xe96c, 0xc94f, 0x3ecf, 0x87c1, 0x7fc2, 0xce47, 0x90c0, 0xee1b, 0x5b96, 0x90c0, 0xeb41, 0x4b96, 0x94c0, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000a0f60, 1},
++	{{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3820, 0xa000, 0x0ac6, 0x38d0, 0x8008, 0x94c0, 0x9620, 0x9720 }, 16, 0x000a0f80, 1},
++	{{0x3620, 0xa000, 0x2a0b, 0x803c, 0x53d3, 0x98c0, 0x371f, 0x80ff, 0x9e20, 0x9f20, 0x3244, 0x3d90, 0x800a, 0x7467, 0x3ec0, 0x2298 }, 16, 0x000a0fa0, 1},
++	{{0x8008, 0x0bc6, 0x38d0, 0x8008, 0x4016, 0x2b08, 0x803e, 0x55d0, 0x3b19, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x98c0, 0x0ac6 }, 16, 0x000a0fc0, 1},
++	{{0x38d0, 0x8008, 0xee5c, 0x4016, 0x2a0f, 0x8040, 0x54d7, 0x391f, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7467, 0x98c0, 0x0dc6, 0x38d0 }, 16, 0x000a0fe0, 1},
++	{{0x8008, 0xee5c, 0x4016, 0x2d0d, 0x8042, 0x55d5, 0x3b1b, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7463, 0x98c0, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000a1000, 1},
++	{{0xee5c, 0x4016, 0x2a09, 0x803c, 0x52d1, 0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x96c0, 0xe8ee, 0x2c00, 0x8052, 0x09c6, 0x38d0 }, 16, 0x000a1020, 1},
++	{{0x8008, 0xe83c, 0x96c0, 0x4010, 0x290b, 0x803e, 0x50d3, 0x3c68, 0x3244, 0x3d90, 0x800a, 0x7460, 0x98c0, 0xcfb6, 0x0dc6, 0x38d0 }, 16, 0x000a1040, 1},
++	{{0x8008, 0xecee, 0x96c0, 0xec3f, 0x2d09, 0x8040, 0x4014, 0x53d1, 0x3de8, 0x3244, 0x3d90, 0x800a, 0x7463, 0x98c0, 0x0bc6, 0x38d0 }, 16, 0x000a1060, 1},
++	{{0x8008, 0xecee, 0xec7a, 0x96c0, 0x4014, 0x2b08, 0x8042, 0x52d0, 0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x98c0, 0x0ac6, 0x38d0 }, 16, 0x000a1080, 1},
++	{{0x8008, 0xee42, 0x4016, 0x2a09, 0x8044, 0x56d1, 0x3d19, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x3ec0, 0x2308, 0x8008, 0x0dc6 }, 16, 0x000a10a0, 1},
++	{{0x38d0, 0x8008, 0x4016, 0x2d08, 0x8046, 0x51d0, 0x331d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465, 0x98c0, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000a10c0, 1},
++	{{0xee5c, 0x4016, 0x2c0d, 0x8048, 0x53d5, 0x371e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x98c0, 0x0fc6, 0x38d0, 0x8008, 0xee5c }, 16, 0x000a10e0, 1},
++	{{0x4016, 0x2f0c, 0x804a, 0x55d4, 0x3b1d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465, 0x98c0, 0x0ac6, 0x38d0, 0x8008, 0xee5c, 0x4016 }, 16, 0x000a1100, 1},
++	{{0x2a09, 0x8044, 0x54d1, 0x3e68, 0x3244, 0x3d90, 0x800a, 0x7464, 0x96c0, 0xefee, 0x2a00, 0x8052, 0x0dc6, 0x38d0, 0x8008, 0xef3a }, 16, 0x000a1120, 1},
++	{{0x96c0, 0x4017, 0x2d0c, 0x8046, 0x53d4, 0x3de8, 0x3244, 0x3d90, 0x800a, 0x7463, 0x98c0, 0xc9b6, 0x08c6, 0x38d0, 0x8008, 0xefee }, 16, 0x000a1140, 1},
++	{{0x96c0, 0xef39, 0x280d, 0x8048, 0x4017, 0x50d5, 0x3c68, 0x3244, 0x3d90, 0x800a, 0x7460, 0x98c0, 0x08c6, 0x38d0, 0x8008, 0xefee }, 16, 0x000a1160, 1},
++	{{0xef7a, 0x96c0, 0x4017, 0x280c, 0x804a, 0x51d4, 0x3ce8, 0x3244, 0x3d90, 0x800a, 0x7461, 0xee42, 0x4016, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a1180, 1},
++	{{0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3610, 0x802a, 0x77d0, 0x9720, 0x8419, 0x3204, 0x30c0 }, 16, 0x000a11a0, 1},
++	{{0x800b, 0x30e1, 0x3000, 0x8003, 0x2744, 0x8650, 0x90c0, 0x90c0, 0x90c8, 0x2500, 0x9800, 0x283b, 0x3204, 0x30c0, 0x800b, 0x6460 }, 16, 0x000a11c0, 1},
++	{{0x9ac0, 0x2100, 0x9800, 0x90c0, 0x3e17, 0x8300, 0x32e4, 0x3c48, 0x8001, 0x7457, 0x3be8, 0x3c04, 0xbfff, 0x3300, 0x2000, 0x9200 }, 16, 0x000a11e0, 1},
++	{{0x98c0, 0xdd98, 0x39e8, 0x3c08, 0xbfff, 0x2744, 0x8e20, 0x0393, 0x0910, 0xb000, 0x4091, 0x90c8, 0x3cc8, 0x3c14, 0xbfff, 0x3400 }, 16, 0x000a1200, 1},
++	{{0x2d40, 0x8003, 0x1594, 0x3cc8, 0x3c14, 0xbfff, 0x3b0b, 0x8400, 0x65e9, 0x8015, 0x90c0, 0x7a61, 0x666a, 0x840d, 0x5094, 0x310b }, 16, 0x000a1220, 1},
++	{{0x8400, 0x65e9, 0x85f1, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x9f20, 0xe748, 0x9f7d, 0x1015, 0xa0e0 }, 16, 0x000a1240, 1},
++	{{0x90c0, 0x1115, 0xa0e0, 0x90c0, 0x9f7c, 0x1105, 0xa004, 0x90c0, 0x1105, 0xa008, 0x90c0, 0x90c0, 0x3344, 0x3a30, 0x800a, 0x32e4 }, 16, 0x000a1260, 1},
++	{{0x3aaa, 0x8001, 0xc083, 0x33e4, 0x3a56, 0x8001, 0x32e4, 0x3a74, 0x8001, 0x38e0, 0x3aa4, 0x8001, 0x32e4, 0x3a5c, 0x8001, 0x98c0 }, 16, 0x000a1280, 1},
++	{{0x39e0, 0x3bca, 0x8001, 0xc0ba, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc182, 0xc0ba, 0x98c0, 0x3fc8, 0x3800, 0xbfff, 0xc782, 0x98c0 }, 16, 0x000a12a0, 1},
++	{{0x3900, 0x3880, 0x800a, 0xc0bc, 0x32e4, 0x3a5c, 0x8001, 0x4797, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc182, 0xc0bc, 0x98c0, 0x3ac8 }, 16, 0x000a12c0, 1},
++	{{0x3800, 0xbfff, 0xc584, 0x98c0, 0x3900, 0x3850, 0x800a, 0xc0be, 0x32e4, 0x3a5c, 0x8001, 0x4592, 0x32e4, 0x3a62, 0x8001, 0x94c0 }, 16, 0x000a12e0, 1},
++	{{0xc182, 0xc0be, 0x32e4, 0x37c8, 0x8001, 0x6c10, 0x32e4, 0x37c2, 0x8001, 0x6c10, 0x32e4, 0x3a7a, 0x8001, 0xc084, 0x98c0, 0x0b06 }, 16, 0x000a1300, 1},
++	{{0x357c, 0x8008, 0xc3fd, 0x94c0, 0xc186, 0xc084, 0xeb4c, 0x56d3, 0x98c0, 0xdd86, 0x32e4, 0x3a62, 0x8001, 0x4313, 0x3204, 0x3270 }, 16, 0x000a1320, 1},
++	{{0x800b, 0xc08a, 0x9ac0, 0x6c10, 0x36e1, 0x3990, 0x8001, 0xc182, 0x32e4, 0x395a, 0x8001, 0xf641, 0x98c0, 0x34e1, 0x3990, 0x8001 }, 16, 0x000a1340, 1},
++	{{0xc182, 0x32e4, 0x395a, 0x8001, 0x94c0, 0xf441, 0xc081, 0x9f7d, 0x1015, 0xa0e0, 0x90c0, 0x9f7c, 0x9f7c, 0xe768, 0x9f21, 0x94c0 }, 16, 0x000a1360, 1},
++	{{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3800, 0x201c, 0x8008, 0x3d40, 0x30e8, 0x8008, 0x0267, 0x3f82 }, 16, 0x000a1380, 1},
++	{{0x8004, 0x0210, 0x3a00, 0x201e, 0x8008, 0x11d5, 0x3900, 0x2022, 0x8008, 0x0112, 0x3c00, 0x2024, 0x8008, 0x2b80, 0x94a3, 0x0b11 }, 16, 0x000a13a0, 1},
++	{{0x3aa8, 0x3c58, 0xbfff, 0x2020, 0x8002, 0x0014, 0x3d00, 0x2048, 0x8008, 0x5492, 0x98c0, 0x39eb, 0x9fff, 0x9620, 0x9720, 0x98c0 }, 16, 0x000a13c0, 1},
++	{{0x36c8, 0x8410, 0x9e20, 0x9f20, 0x0015, 0xe748, 0x3244, 0x37b0, 0x800a, 0x00a4, 0x33bc, 0x8009, 0x3304, 0x3a80, 0x800a, 0x3244 }, 16, 0x000a13e0, 1},
++	{{0x35a0, 0x800a, 0x38c0, 0x38c0, 0x8008, 0x3224, 0x2620, 0x800a, 0x38c0, 0x38c0, 0x8008, 0x32c4, 0x36e0, 0x800a, 0x00a4, 0x33bc }, 16, 0x000a1400, 1},
++	{{0x8009, 0x3224, 0x3720, 0x800a, 0x00a4, 0x33be, 0x8009, 0x9f7d, 0x02c5, 0x38b8, 0x8008, 0x37e2, 0x0fc6, 0x38d0, 0x8008, 0x67e9 }, 16, 0x000a1420, 1},
++	{{0x94c0, 0xef42, 0x845e, 0x92c3, 0xcd81, 0x96c0, 0x52d7, 0x2f0e, 0x80ae, 0x96c0, 0x351b, 0x8003, 0x56d6, 0x96c0, 0x65e9, 0x3d18 }, 16, 0x000a1440, 1},
++	{{0x8003, 0x843c, 0x92c3, 0xcd82, 0x96c0, 0x6469, 0x3d1e, 0x800c, 0x842e, 0x92c3, 0xcd83, 0x2769, 0xcfb6, 0x8424, 0x92c3, 0xcd84 }, 16, 0x000a1460, 1},
++	{{0xee3f, 0x55d6, 0x9ac0, 0x3b1e, 0x8007, 0x90c0, 0x3b9a, 0x8000, 0x6769, 0x800b, 0x6569, 0x8408, 0x92c3, 0xcd85, 0xcd86, 0x3204 }, 16, 0x000a1480, 1},
++	{{0x3c60, 0x800b, 0x0d21, 0x336a, 0x8009, 0x3f00, 0x2066, 0x8008, 0x3224, 0x2b00, 0x800a, 0x4017, 0x3304, 0x2d90, 0x800a, 0x33e4 }, 16, 0x000a14a0, 1},
++	{{0x2180, 0x800a, 0x96c0, 0x6c90, 0x2200, 0x8200, 0x32e4, 0x3c8a, 0x8001, 0x98c0, 0xf241, 0x3820, 0x2ad6, 0x8009, 0x0425, 0x336a }, 16, 0x000a14c0, 1},
++	{{0x8009, 0x7764, 0xd321, 0x90c0, 0x94c1, 0xe838, 0xc283, 0x96c3, 0x3244, 0x3a50, 0x800a, 0x96c2, 0x0221, 0x3369, 0x8009, 0x9f7d }, 16, 0x000a14e0, 1},
++	{{0x1015, 0xa0e0, 0x90c0, 0x9f7c, 0x9f7c, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1500, 1},
++	{{0x2f90, 0x2c90, 0x2f10, 0x3f00, 0x20e4, 0x8008, 0x3cc8, 0x3c00, 0xbfff, 0x0717, 0x3d00, 0x2048, 0x8008, 0x1394, 0x3800, 0x2064 }, 16, 0x000a1520, 1},
++	{{0x8008, 0x0395, 0x3f00, 0x2060, 0x8008, 0x0110, 0x3e00, 0x2062, 0x8008, 0x0117, 0x38e8, 0x3c00, 0xbfff, 0x0116, 0x35f9, 0x3fff }, 16, 0x000a1540, 1},
++	{{0xbff0, 0x1490, 0x39e8, 0x3c00, 0xbfff, 0x98c0, 0xde05, 0x3bc8, 0x2428, 0xbfff, 0x0914, 0xa009, 0x0491, 0x3fa8, 0x3c50, 0xbfff }, 16, 0x000a1560, 1},
++	{{0x1293, 0x3e00, 0x2034, 0x8008, 0x0902, 0xa080, 0x4293, 0x0601, 0x3c4a, 0x8008, 0x9ac0, 0x6e90, 0x3ce8, 0x2404, 0xbfff, 0xc486 }, 16, 0x000a1580, 1},
++	{{0x05c1, 0x38d5, 0x8008, 0x0421, 0x336a, 0x8009, 0x1394, 0x37f9, 0x3fff, 0xbffe, 0xdf83, 0x4794, 0x03a4, 0x33c0, 0x8009, 0x9f7d }, 16, 0x000a15a0, 1},
++	{{0x1015, 0xa0e0, 0x90c0, 0x1115, 0xa0e0, 0x90c0, 0x9f7c, 0x98c0, 0xd1a8, 0x09c6, 0x38d0, 0x8008, 0x843f, 0x2908, 0x8078, 0x15d0 }, 16, 0x000a15c0, 1},
++	{{0xebe8, 0x98c0, 0x3b58, 0x8000, 0xeb76, 0xe842, 0x2469, 0x11d3, 0x54d0, 0x96c0, 0x391c, 0x8007, 0x8425, 0x3318, 0x8007, 0x2c7c }, 16, 0x000a15e0, 1},
++	{{0xc09a, 0xd621, 0x8013, 0x3304, 0x31b0, 0x800a, 0x98c0, 0xc69a, 0x3104, 0x3620, 0x800a, 0x3204, 0x31b0, 0x800a, 0xc0ae, 0xc6ae }, 16, 0x000a1600, 1},
++	{{0x3304, 0x3250, 0x800a, 0x3920, 0x32d8, 0x8009, 0x3244, 0x3800, 0x800a, 0x3820, 0x32b8, 0x8009, 0x0ac6, 0x38d0, 0x8008, 0x3920 }, 16, 0x000a1620, 1},
++	{{0x32d8, 0x8009, 0x2a0a, 0x807a, 0x10d2, 0x3820, 0x32b8, 0x8009, 0x311c, 0x8007, 0x6669, 0x8015, 0x33e4, 0x3150, 0x8009, 0x3004 }, 16, 0x000a1640, 1},
++	{{0x3680, 0x800a, 0x00a0, 0x33bc, 0x8009, 0x32e4, 0x3150, 0x8009, 0x98c0, 0xe939, 0x3820, 0x32b8, 0x8009, 0x00a0, 0x33bc, 0x8009 }, 16, 0x000a1660, 1},
++	{{0x9ac0, 0xd028, 0xcc40, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x94c6, 0xecfc, 0xc288, 0x98c7, 0x0ca0, 0x33be, 0x8009, 0xc290, 0x98c0 }, 16, 0x000a1680, 1},
++	{{0x02a0, 0x33c0, 0x8009, 0xea44, 0x4212, 0x03a4, 0x33c0, 0x8009, 0x98c0, 0xd1a8, 0x0cc6, 0x38d0, 0x8008, 0x8415, 0x2c0b, 0x8078 }, 16, 0x000a16a0, 1},
++	{{0x50d3, 0x315a, 0x8000, 0x6569, 0x8008, 0x92c2, 0xc79a, 0xc7ae, 0x73f6, 0x2dff, 0x9eed, 0x33a4, 0x3270, 0x800a, 0x2d90, 0x3204 }, 16, 0x000a16c0, 1},
++	{{0x3390, 0x800a, 0x03c0, 0x2a40, 0x8009, 0x3ca8, 0x3c58, 0xbfff, 0x90c0, 0x5294, 0x35fd, 0x9fff, 0x66e9, 0x8423, 0x1797, 0x3840 }, 16, 0x000a16e0, 1},
++	{{0x31a0, 0x8008, 0x3f1c, 0x8800, 0x6669, 0x8413, 0x33e4, 0x37da, 0x8001, 0x98c0, 0xc78c, 0x3104, 0x371e, 0x800a, 0xc78b, 0x3ca8 }, 16, 0x000a1700, 1},
++	{{0x3c58, 0xbfff, 0x90c0, 0x5094, 0x31fb, 0x9fff, 0x3413, 0x8033, 0x807b, 0x5694, 0x3dfe, 0x9fff, 0x6769, 0x840f, 0x5097, 0x311b }, 16, 0x000a1720, 1},
++	{{0x8800, 0x3413, 0x8800, 0x8065, 0x3204, 0x31b0, 0x800a, 0xc09a, 0x32e4, 0x37da, 0x8001, 0x3840, 0x3186, 0x8008, 0x32e4, 0x3a7a }, 16, 0x000a1740, 1},
++	{{0x8001, 0xc094, 0x32e4, 0x3a7a, 0x8001, 0xc092, 0x32e4, 0x3a7a, 0x8001, 0xc0a2, 0x32e4, 0x3a7a, 0x8001, 0xc0a6, 0x32e4, 0x3a7a }, 16, 0x000a1760, 1},
++	{{0x8001, 0xc0aa, 0x32e4, 0x3a7a, 0x8001, 0xc0ac, 0x32e4, 0x3a7a, 0x8001, 0xc0ae, 0x32e4, 0x3a7a, 0x8001, 0xc090, 0x2e90, 0x3004 }, 16, 0x000a1780, 1},
++	{{0x37ac, 0x800a, 0x05c1, 0x38d5, 0x8008, 0x6f90, 0x2e10, 0x0716, 0x3b00, 0x2032, 0x8008, 0x31e1, 0x2268, 0x8009, 0x4413, 0x00c5 }, 16, 0x000a17a0, 1},
++	{{0x38d5, 0x8008, 0x2469, 0x0102, 0x3b30, 0x8008, 0x92c0, 0x8455, 0x3244, 0x2e20, 0x800a, 0x3800, 0x3c4c, 0x8008, 0x33e4, 0x3060 }, 16, 0x000a17c0, 1},
++	{{0x800a, 0x33e4, 0x22e0, 0x800a, 0x04c5, 0x38d4, 0x8008, 0x6669, 0x8011, 0x3304, 0x38a0, 0x800b, 0x6d90, 0x03c1, 0x38d4, 0x8008 }, 16, 0x000a17e0, 1},
++	{{0x32e4, 0x39f6, 0x8001, 0x2000, 0x83e8, 0x33a4, 0x28d0, 0x800a, 0x3344, 0x3ba0, 0x800a, 0x01c5, 0x38d5, 0x8008, 0x64e9, 0x81b3 }, 16, 0x000a1800, 1},
++	{{0x33e4, 0x3a38, 0x8001, 0x2764, 0x9530, 0x90c0, 0x90c0, 0x90c8, 0x3fa8, 0x3c50, 0xbfff, 0x3004, 0x3594, 0x800a, 0x3e00, 0x2034 }, 16, 0x000a1820, 1},
++	{{0x8008, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0xc840, 0xccba, 0x98c0, 0x39c8, 0x3800, 0xbfff, 0xc181 }, 16, 0x000a1840, 1},
++	{{0x94c0, 0xe83c, 0xc081, 0xc84a, 0x34cd, 0x87c1, 0xd495, 0x94c0, 0x4191, 0x9f70, 0x00c1, 0x38d4, 0x8008, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1860, 1},
++	{{0x96c0, 0x6c90, 0xc940, 0xcdba, 0x98c0, 0x38c8, 0x3800, 0xbfff, 0xc581, 0x98c0, 0xe93d, 0x3ac8, 0x2400, 0xbfff, 0x96c0, 0xc94b }, 16, 0x000a1880, 1},
++	{{0x2704, 0x8060, 0x36cb, 0x87c1, 0x98c0, 0xd693, 0x39e0, 0x3078, 0x8008, 0x0590, 0x38e0, 0x31f8, 0x8008, 0xc582, 0x4592, 0x94c8 }, 16, 0x000a18a0, 1},
++	{{0x4118, 0x4119, 0x3de8, 0x3c0c, 0xbfff, 0x30f9, 0x3fff, 0xbffe, 0x96c0, 0x5295, 0x2704, 0x83e8, 0xdc02, 0x4095, 0x90c8, 0x98c0 }, 16, 0x000a18c0, 1},
++	{{0x3b00, 0x2042, 0x8008, 0xc281, 0x3cc8, 0x3c00, 0xbfff, 0x13d3, 0x3d00, 0x2044, 0x8008, 0x79c1, 0x4313, 0x5094, 0x94c0, 0x4095 }, 16, 0x000a18e0, 1},
++	{{0x9f70, 0x02c1, 0x38d5, 0x8008, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1900, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9cc0, 0x6f10, 0x7650, 0x6d10, 0x6c90, 0x9620, 0x9720, 0x96c0 }, 16, 0x000a1920, 1},
++	{{0x6d90, 0x7456, 0x9750, 0x94c0, 0x9e20, 0x9f20, 0x3ae0, 0x2258, 0x8008, 0x3fe0, 0x2358, 0x8008, 0x38e0, 0x22d8, 0x8008, 0x39e0 }, 16, 0x000a1940, 1},
++	{{0x21d8, 0x8008, 0x90c0, 0x94d0, 0xc819, 0xc818, 0x94c0, 0xc81a, 0xc81f, 0x96c0, 0x7750, 0x7454, 0x9758, 0x2460, 0x3be0, 0x2118 }, 16, 0x000a1960, 1},
++	{{0x8008, 0x3650, 0x3456, 0x39e0, 0x2058, 0x8008, 0x3cc0, 0x3f98, 0x8008, 0x3ec0, 0x3ed8, 0x8008, 0x90c0, 0x94d0, 0xc81c, 0xc81e }, 16, 0x000a1980, 1},
++	{{0x94c0, 0xc819, 0xc81b, 0x3454, 0x3fe0, 0x301c, 0x8008, 0x2460, 0x3ce0, 0x302c, 0x8008, 0x2469, 0x31e1, 0x2358, 0x8008, 0x9cc6 }, 16, 0x000a19a0, 1},
++	{{0x36e1, 0x22d8, 0x8008, 0x6e90, 0x90c0, 0x6d90, 0x98c7, 0x01e2, 0x3018, 0x8008, 0xc581, 0x019f, 0x06e2, 0x3028, 0x8008, 0x069c }, 16, 0x000a19c0, 1},
++	{{0x3de0, 0x300c, 0x8008, 0x98c7, 0x3be0, 0x2ffc, 0x8008, 0xc381, 0x9cc1, 0xc081, 0x3161, 0x2966, 0x8008, 0x90c0, 0x6d10, 0x3c41 }, 16, 0x000a19e0, 1},
++	{{0xa000, 0x4194, 0x3461, 0x28e6, 0x8008, 0x6c10, 0x3a27, 0xa000, 0x4494, 0x37e1, 0x21d8, 0x8008, 0x98c6, 0x34e1, 0x2258, 0x8008 }, 16, 0x000a1a00, 1},
++	{{0x4197, 0x3a27, 0xa000, 0x4497, 0x07e2, 0x2ff8, 0x8008, 0x079b, 0x04e2, 0x3008, 0x8008, 0x96c0, 0x449d, 0x2c0e, 0x8004, 0x94c6 }, 16, 0x000a1a20, 1},
++	{{0x4516, 0x4195, 0x3641, 0xa000, 0x4193, 0x4495, 0x3827, 0xa000, 0x4493, 0x2f08, 0x8004, 0x94c0, 0x9e21, 0x9f21, 0x98c7, 0x2b0a }, 16, 0x000a1a40, 1},
++	{{0x8004, 0x90c0, 0xc281, 0x96c0, 0x4310, 0x2d09, 0x8004, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x0012, 0x4211, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1a60, 1},
++	{{0x9cc0, 0x6d10, 0x76d0, 0x6c10, 0x6d90, 0x9620, 0x9720, 0x94c0, 0x74d2, 0x9758, 0x94c0, 0x9e20, 0x9f20, 0x3fc0, 0x38d8, 0x8008 }, 16, 0x000a1a80, 1},
++	{{0x3ec0, 0x3a58, 0x8008, 0x3cc0, 0x3d58, 0x8008, 0x38c0, 0x3bd8, 0x8008, 0x90c0, 0x94d0, 0xc818, 0xc81c, 0x94c0, 0xc81f, 0xc81e }, 16, 0x000a1aa0, 1},
++	{{0x9ac0, 0x66e9, 0x3bc8, 0x3000, 0xbfff, 0xc483, 0x3cc8, 0x3008, 0xbfff, 0x96c6, 0x5093, 0x2500, 0x814d, 0x3119, 0x8001, 0x64e9 }, 16, 0x000a1ac0, 1},
++	{{0x803b, 0x1094, 0x3fc8, 0x3000, 0xbfff, 0x9ac0, 0x2e20, 0x8000, 0x90c0, 0x3118, 0x8fff, 0x3278, 0x3bc8, 0x3008, 0xbfff, 0x841d }, 16, 0x000a1ae0, 1},
++	{{0xee61, 0xeef1, 0x8017, 0x5097, 0x311e, 0x8001, 0x6769, 0x800d, 0x5193, 0x3318, 0x8fff, 0x7278, 0x81e9, 0x98c0, 0x3ec8, 0x3000 }, 16, 0x000a1b00, 1},
++	{{0xbfff, 0xc182, 0x98c0, 0x3fc8, 0x3400, 0xbfff, 0xc283, 0x0196, 0x3cc8, 0x3408, 0xbfff, 0x5697, 0x3d18, 0x8001, 0x6469, 0x803b }, 16, 0x000a1b20, 1},
++	{{0x1494, 0x3fc8, 0x3400, 0xbfff, 0x9ac0, 0x2820, 0x8000, 0x90c0, 0x3918, 0x8fff, 0x3178, 0x3ac8, 0x3408, 0xbfff, 0x841d, 0xe861 }, 16, 0x000a1b40, 1},
++	{{0xe8f1, 0x8017, 0x5097, 0x3118, 0x8001, 0x6469, 0x800d, 0x5692, 0x3d18, 0x8fff, 0x7178, 0x81e9, 0x98c0, 0x3ec8, 0x3400, 0xbfff }, 16, 0x000a1b60, 1},
++	{{0xc781, 0x96c0, 0x3b1a, 0x80ff, 0xc690, 0x0196, 0xd7c2, 0x3820, 0xa000, 0x05e4, 0x306a, 0x8008, 0x3a00, 0xa004, 0xd2a8, 0x03e1 }, 16, 0x000a1b80, 1},
++	{{0x306c, 0x8008, 0x801d, 0x3600, 0xa004, 0x3415, 0x8030, 0x8023, 0x3400, 0xa004, 0xd2b8, 0x801b, 0x3400, 0xa004, 0xd2b0, 0x8013 }, 16, 0x000a1ba0, 1},
++	{{0x96c0, 0x67e0, 0xc381, 0xc6a0, 0x27ee, 0x03e1, 0x306c, 0x8008, 0x98c0, 0x746b, 0xcc47, 0x21e0, 0x9f00, 0xdc85, 0xec61, 0x98c0 }, 16, 0x000a1bc0, 1},
++	{{0xcc4f, 0x3204, 0x3930, 0x800a, 0xd7c1, 0x3e00, 0xa00a, 0x3f18, 0x8100, 0x6d10, 0x3f19, 0x8200, 0x6f90, 0x3e40, 0xa000, 0x3f19 }, 16, 0x000a1be0, 1},
++	{{0x8400, 0x6469, 0x3f1d, 0x8800, 0xc281, 0x3e00, 0xa001, 0x3f3b, 0x8000, 0x6e10, 0x3ecc, 0x8088, 0xc0aa, 0x3a01, 0xa009, 0xe939 }, 16, 0x000a1c00, 1},
++	{{0x64e9, 0x64e9, 0xc981, 0x02e2, 0x23e8, 0x8008, 0x98c1, 0x64e9, 0xee3e, 0xce81, 0x64e9, 0x3c00, 0xa802, 0x3eea, 0x805f, 0x90c0 }, 16, 0x000a1c20, 1},
++	{{0x3ec8, 0x808a, 0x98c1, 0x66e9, 0xea3a, 0xca81, 0x66e9, 0x02e2, 0x23e8, 0x8008, 0x3a01, 0xa009, 0xeb3b, 0x66ea, 0x66ea, 0xcb81 }, 16, 0x000a1c40, 1},
++	{{0x3a07, 0xb004, 0x7ac7, 0x3eea, 0x805e, 0x65e9, 0x3a00, 0xa004, 0x7ee3, 0x02e2, 0x23e8, 0x8008, 0x3800, 0xb800, 0xd995, 0x34ea }, 16, 0x000a1c60, 1},
++	{{0x805d, 0x3466, 0x8006, 0x98c0, 0xcc46, 0x02e2, 0x23e8, 0x8008, 0x0ce0, 0x3068, 0x8008, 0x98c6, 0x3fe0, 0x23ec, 0x8008, 0xecf8 }, 16, 0x000a1c80, 1},
++	{{0x98c6, 0x35e1, 0x29f8, 0x8008, 0xecfc, 0x98c6, 0xd223, 0x0ce0, 0x3068, 0x8008, 0x98c0, 0xecf8, 0x38e0, 0x23dc, 0x8008, 0x98c0 }, 16, 0x000a1ca0, 1},
++	{{0xecfc, 0x3dc8, 0x3820, 0xbfff, 0x94c0, 0xcc4b, 0xcc4e, 0x98c6, 0x09e1, 0x306f, 0x8008, 0x75fb, 0x3e06, 0xa008, 0x90c0, 0x0be1 }, 16, 0x000a1cc0, 1},
++	{{0x306e, 0x8008, 0x7dc1, 0xd023, 0x98c6, 0x36ea, 0x8310, 0x90c0, 0x777e, 0x98c6, 0x02e2, 0x23e8, 0x8008, 0x7f41, 0x3600, 0xa800 }, 16, 0x000a1ce0, 1},
++	{{0x34ea, 0x804f, 0x02e2, 0x23e8, 0x8008, 0x059f, 0x0ae1, 0x306d, 0x8008, 0x2e10, 0x0ee1, 0x3071, 0x8008, 0x2c90, 0x0497, 0x3900 }, 16, 0x000a1d00, 1},
++	{{0x3eb0, 0x800a, 0x1497, 0x32e1, 0x23f8, 0x8008, 0x3600, 0xa800, 0x34ec, 0x805f, 0x4497, 0x5497, 0x3600, 0xa800, 0x34ec, 0x805e }, 16, 0x000a1d20, 1},
++	{{0x4497, 0x5497, 0x3600, 0xa800, 0x34ec, 0x805d, 0x4497, 0x5597, 0x36ed, 0x8310, 0x4597, 0x5597, 0x3600, 0xa800, 0x34ed, 0x804f }, 16, 0x000a1d40, 1},
++	{{0x459f, 0x4297, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008, 0x3600, 0xa004, 0x32ec, 0x805f, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008 }, 16, 0x000a1d60, 1},
++	{{0x3600, 0xa004, 0x32ec, 0x805e, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008, 0x3600, 0xa804, 0x34ec, 0x805d, 0x3820, 0xa000, 0x04e2 }, 16, 0x000a1d80, 1},
++	{{0x23d8, 0x8008, 0x3600, 0xa004, 0x3cec, 0x8310, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008, 0x3600, 0xa804, 0x34ec, 0x804f, 0x3820 }, 16, 0x000a1da0, 1},
++	{{0xa000, 0x04e2, 0x23d8, 0x8008, 0x35e1, 0x26f8, 0x8008, 0x4598, 0x4190, 0x1290, 0x35e1, 0x2cf8, 0x8008, 0x3600, 0xa800, 0x34ea }, 16, 0x000a1dc0, 1},
++	{{0x805f, 0x4290, 0x5290, 0x3600, 0xa800, 0x34ea, 0x805e, 0x4290, 0x5490, 0x3600, 0xa800, 0x34ec, 0x805d, 0x4490, 0x5290, 0x3cea }, 16, 0x000a1de0, 1},
++	{{0x8310, 0x4290, 0x5390, 0x3600, 0xa800, 0x34eb, 0x804f, 0x4398, 0x4590, 0x3201, 0x2000, 0x8030, 0x32e4, 0x3a5c, 0x8001, 0x4295 }, 16, 0x000a1e00, 1},
++	{{0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc184, 0xc0aa, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3900, 0x3eb0, 0x800a, 0xc0ac, 0x32e4, 0x3a62 }, 16, 0x000a1e20, 1},
++	{{0x8001, 0x94c0, 0xc184, 0xc0ac, 0x9f7d, 0x9ac0, 0x3f1c, 0x8300, 0x90c0, 0x3f1d, 0x8c00, 0x2669, 0x39e8, 0x3c2c, 0xbfff, 0x90c0 }, 16, 0x000a1e40, 1},
++	{{0x98c7, 0x4791, 0x33e0, 0x23e8, 0x8008, 0x94c3, 0x0903, 0xa001, 0x98c7, 0x66e9, 0x03e2, 0x3064, 0x8008, 0x90c0, 0x96c3, 0x36e0 }, 16, 0x000a1e60, 1},
++	{{0x23d8, 0x8008, 0x94c3, 0x0906, 0xa001, 0x96c3, 0x06e2, 0x305c, 0x8008, 0x9f7c, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000a1e80, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3410, 0x802a, 0x9620, 0x9720, 0x3a20, 0xa000, 0x08c6 }, 16, 0x000a1ea0, 1},
++	{{0x38d0, 0x8008, 0xc0aa, 0x94c0, 0x9e20, 0x9f20, 0x3840, 0xa000, 0xe748, 0x280e, 0x80b2, 0x1616, 0x3da8, 0x3c20, 0xbfff, 0x9ac0 }, 16, 0x000a1ec0, 1},
++	{{0x2618, 0x82fc, 0x90c0, 0x3d1e, 0x8007, 0x3ee8, 0x3c2c, 0xbfff, 0x1395, 0x32e4, 0x3a68, 0x8001, 0x0322, 0x334c, 0x8009, 0x1496 }, 16, 0x000a1ee0, 1},
++	{{0x3ac8, 0x3004, 0xbfff, 0x96c0, 0x391a, 0x8f00, 0xcf82, 0x9ac0, 0xdd28, 0x5892, 0x39e0, 0x23e8, 0x8008, 0x3518, 0x8003, 0x94c0 }, 16, 0x000a1f00, 1},
++	{{0xce40, 0xe9a8, 0x90c0, 0x98c7, 0xee61, 0x39e0, 0x29f8, 0x8008, 0x98c6, 0xee8f, 0x39e0, 0x23f8, 0x8008, 0x96c0, 0xeefe, 0x2518 }, 16, 0x000a1f20, 1},
++	{{0x820a, 0x3fe0, 0x3044, 0x8008, 0x07e7, 0x3068, 0x8008, 0x9ac0, 0x67ea, 0xee1f, 0x03e7, 0x3068, 0x8008, 0x1a96, 0x02e7, 0x3068 }, 16, 0x000a1f40, 1},
++	{{0x8008, 0x90c0, 0x9a61, 0x98c0, 0x67e1, 0x5119, 0x2718, 0x81de, 0x3be1, 0x02e6, 0x3058, 0x8008, 0x9ac0, 0x34c8, 0x950c, 0x9b47 }, 16, 0x000a1f60, 1},
++	{{0x2b03, 0x802c, 0x2e91, 0x3fc0, 0x3a58, 0x8008, 0xd545, 0x34cf, 0x950c, 0x2ca7, 0x02e2, 0x3058, 0x8008, 0xd496, 0x96c0, 0x64e1 }, 16, 0x000a1f80, 1},
++	{{0x2103, 0x8032, 0x98c0, 0x34c8, 0x950c, 0x7cc8, 0x5319, 0x2e13, 0x64e5, 0x3cc8, 0xd544, 0x96c0, 0x34cc, 0x950c, 0x74d9, 0x9ad0 }, 16, 0x000a1fa0, 1},
++	{{0x6cac, 0x415f, 0x02e2, 0x3058, 0x8008, 0xd496, 0x64e1, 0x7cc8, 0x64e5, 0x7cc8, 0x34d9, 0x3024, 0x2144, 0x800a, 0x4157, 0x25ea }, 16, 0x000a1fc0, 1},
++	{{0x25e1, 0x1219, 0x05e6, 0x3050, 0x8008, 0x9ac0, 0x3ac9, 0x950c, 0x79e1, 0x2718, 0x815a, 0x98c0, 0x6c98, 0x9b43, 0x2b03, 0x802a }, 16, 0x000a1fe0, 1},
++	{{0x98c0, 0xd6c1, 0x3fc0, 0x38d8, 0x8008, 0x3acb, 0x950c, 0x2c3d, 0x05e2, 0x3050, 0x8008, 0xd416, 0x96c0, 0x6461, 0x2103, 0x8032 }, 16, 0x000a2000, 1},
++	{{0x98c0, 0x3acc, 0x950c, 0x7c48, 0x5319, 0x2fac, 0x6465, 0x3c48, 0xd6c7, 0x96c0, 0x3acc, 0x950c, 0x7458, 0x9ad0, 0x6c2c, 0x405f }, 16, 0x000a2020, 1},
++	{{0x05e2, 0x3050, 0x8008, 0xd416, 0x6461, 0x7c48, 0x6465, 0x7c48, 0x3458, 0x3024, 0x2144, 0x800a, 0x4057, 0x256a, 0x2561, 0x1119 }, 16, 0x000a2040, 1},
++	{{0x07e6, 0x3058, 0x8008, 0x9ac0, 0x3ecd, 0x950c, 0x7961, 0x5019, 0x84df, 0x9ac0, 0x6d21, 0x03e6, 0x3050, 0x8008, 0x9b42, 0x9ac0 }, 16, 0x000a2060, 1},
++	{{0x36cc, 0x950c, 0xd7c2, 0x2b03, 0x8052, 0x96c0, 0x6e24, 0x3ecd, 0x950c, 0x9ac0, 0xd5c4, 0x6d21, 0x3fc0, 0x3a58, 0x8008, 0x96c0 }, 16, 0x000a2080, 1},
++	{{0x36cc, 0x950c, 0xd516, 0x2ea4, 0x2561, 0x3cc0, 0x38d8, 0x8008, 0x98c0, 0xd696, 0x03e2, 0x3050, 0x8008, 0x26e1, 0x07e2, 0x3058 }, 16, 0x000a20a0, 1},
++	{{0x8008, 0x9cc0, 0x2103, 0x806e, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3d48, 0x3ec8, 0x1419, 0x03e6, 0x3050, 0x8008, 0x3e00, 0xa004 }, 16, 0x000a20c0, 1},
++	{{0x3ecd, 0x950c, 0x6565, 0x36c9, 0x950c, 0x5019, 0x3a00, 0xa088, 0x66e5, 0x6e21, 0x6c84, 0x7d48, 0x3a00, 0xb000, 0x7ec8, 0xd7c4 }, 16, 0x000a20e0, 1},
++	{{0xd5c1, 0x755a, 0x9cc0, 0x36c9, 0x950c, 0x76dd, 0x3eca, 0x950c, 0x425f, 0x9cd0, 0x6e84, 0x6d32, 0x455c, 0x03e2, 0x3050, 0x8008 }, 16, 0x000a2100, 1},
++	{{0x9ac0, 0xd696, 0xd516, 0x07e2, 0x3058, 0x8008, 0x26e1, 0x6561, 0x3ec8, 0x7d48, 0x26e5, 0x6565, 0x3ec8, 0x7d48, 0x36dd, 0x755a }, 16, 0x000a2120, 1},
++	{{0x0554, 0x4257, 0x3ce0, 0x3024, 0x8008, 0x01e5, 0x306f, 0x8008, 0x3561, 0x1614, 0x07e7, 0x3068, 0x8008, 0x2569, 0x7b41, 0xd79e }, 16, 0x000a2140, 1},
++	{{0x98c3, 0xc281, 0x35e1, 0x3018, 0x8008, 0x94c3, 0xf204, 0xf703, 0x98c3, 0xf541, 0x39e0, 0x2118, 0x8008, 0x96c3, 0x3224, 0x3afe }, 16, 0x000a2160, 1},
++	{{0x800a, 0x96c3, 0x38c0, 0x3a58, 0x8008, 0x03e5, 0x3071, 0x8008, 0x75e3, 0x65e9, 0x90c0, 0x98c3, 0xc181, 0x34e1, 0x3008, 0x8008 }, 16, 0x000a2180, 1},
++	{{0x94c3, 0xf104, 0xf703, 0x98c3, 0xf441, 0x39e0, 0x2058, 0x8008, 0x96c3, 0x3224, 0x3afe, 0x800a, 0x96c3, 0x38c0, 0x38d8, 0x8008 }, 16, 0x000a21a0, 1},
++	{{0x0725, 0x336a, 0x8009, 0x7567, 0xd123, 0x2718, 0x82f0, 0x3344, 0x3ad0, 0x800a, 0x3124, 0x24ba, 0x800a, 0x1595, 0xc0ac, 0x32e4 }, 16, 0x000a21c0, 1},
++	{{0x3a68, 0x8001, 0x0522, 0x3314, 0x8009, 0x1496, 0x38c8, 0x3404, 0xbfff, 0x96c0, 0x391c, 0x8f00, 0xcc82, 0x9ac0, 0xde2a, 0x3be0 }, 16, 0x000a21e0, 1},
++	{{0x23d8, 0x8008, 0x5e90, 0xcd44, 0xebae, 0x98c0, 0xed61, 0x3be0, 0x3038, 0x8008, 0x96c2, 0x39e0, 0x2cf8, 0x8008, 0x98c7, 0xed8c }, 16, 0x000a2200, 1},
++	{{0x39e0, 0x26f8, 0x8008, 0x96c0, 0xedfe, 0x2518, 0x8204, 0x98c0, 0xed1b, 0x00e7, 0x3068, 0x8008, 0x246a, 0x1895, 0x04e7, 0x3068 }, 16, 0x000a2220, 1},
++	{{0x8008, 0x05e7, 0x3068, 0x8008, 0x9861, 0x98c0, 0x6461, 0x5419, 0x2718, 0x81e0, 0x3861, 0x03e6, 0x3054, 0x8008, 0x9ac0, 0x36c9 }, 16, 0x000a2240, 1},
++	{{0x950c, 0x9b40, 0x2b03, 0x8034, 0x2f84, 0x38c0, 0x3d58, 0x8008, 0xd5c7, 0x36cd, 0x950c, 0x2eb5, 0x03e2, 0x3054, 0x8008, 0xd696 }, 16, 0x000a2260, 1},
++	{{0x9ec0, 0x66e1, 0x2103, 0x803a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x36ca, 0x950c, 0x7ec8, 0x5119, 0x2d38, 0x66e5, 0x3ec8 }, 16, 0x000a2280, 1},
++	{{0xd5c2, 0x96c0, 0x36ca, 0x950c, 0x76dd, 0x9ad0, 0x6eb8, 0x4558, 0x03e2, 0x3054, 0x8008, 0xd696, 0x66e1, 0x7ec8, 0x66e5, 0x7ec8 }, 16, 0x000a22a0, 1},
++	{{0x36dd, 0x3024, 0x242a, 0x800a, 0x4550, 0x266a, 0x2661, 0x1219, 0x00e6, 0x3060, 0x8008, 0x9ac0, 0x30cd, 0x950c, 0x7a61, 0x2718 }, 16, 0x000a22c0, 1},
++	{{0x8154, 0x98c0, 0x6fa9, 0x9b44, 0x2b03, 0x802e, 0x98c0, 0xd447, 0x3dc0, 0x3bd8, 0x8008, 0x30cf, 0x950c, 0x2e2b, 0x00e2, 0x3060 }, 16, 0x000a22e0, 1},
++	{{0x8008, 0xd616, 0x9ac0, 0x6661, 0x2103, 0x8036, 0x90c0, 0x90c0, 0x98c0, 0x30c9, 0x950c, 0x7e48, 0x5319, 0x2d19, 0x6665, 0x3e48 }, 16, 0x000a2300, 1},
++	{{0xd442, 0x96c0, 0x30cf, 0x950c, 0x765c, 0x9ad0, 0x6e2f, 0x445d, 0x00e2, 0x3060, 0x8008, 0xd616, 0x6661, 0x7e48, 0x6665, 0x7e48 }, 16, 0x000a2320, 1},
++	{{0x365c, 0x3024, 0x242a, 0x800a, 0x4455, 0x26ea, 0x26e1, 0x1019, 0x07e6, 0x3054, 0x8008, 0x9ac0, 0x3ec9, 0x950c, 0x7ae1, 0x5419 }, 16, 0x000a2340, 1},
++	{{0x84d5, 0x9ac0, 0x6c84, 0x03e6, 0x3060, 0x8008, 0x9b45, 0x9ac0, 0x36ca, 0x950c, 0xd7c1, 0x2b03, 0x8046, 0x96c0, 0x6eb2, 0x3eca }, 16, 0x000a2360, 1},
++	{{0x950c, 0x98c0, 0xd5c5, 0x3fc0, 0x3d58, 0x8008, 0x36cd, 0x950c, 0x2c21, 0x2e88, 0x3cc0, 0x3bd8, 0x8008, 0x9ac0, 0xd416, 0xd696 }, 16, 0x000a2380, 1},
++	{{0x03e2, 0x3060, 0x8008, 0x2461, 0x26e1, 0x07e2, 0x3054, 0x8008, 0x2103, 0x8066, 0x3c48, 0x3ec8, 0x1219, 0x04e6, 0x3060, 0x8008 }, 16, 0x000a23a0, 1},
++	{{0x3e00, 0xa004, 0x3eca, 0x950c, 0x6465, 0x38cb, 0x950c, 0x5119, 0x3a00, 0xa088, 0x66e5, 0x6e38, 0x6dbd, 0x7c48, 0x3a00, 0xb000 }, 16, 0x000a23c0, 1},
++	{{0x7ec8, 0xd7c4, 0xd643, 0x7458, 0x98c0, 0x76dd, 0x3ec8, 0x950c, 0x405c, 0x96c0, 0x38cd, 0x950c, 0x455f, 0x9ad0, 0x6c29, 0x6e91 }, 16, 0x000a23e0, 1},
++	{{0x04e2, 0x3060, 0x8008, 0x9ac0, 0xd416, 0xd696, 0x07e2, 0x3054, 0x8008, 0x2461, 0x66e1, 0x3c48, 0x7ec8, 0x2465, 0x66e5, 0x3c48 }, 16, 0x000a2400, 1},
++	{{0x7ec8, 0x3458, 0x76dd, 0x0054, 0x4557, 0x3de0, 0x3034, 0x8008, 0x05e5, 0x306d, 0x8008, 0x3465, 0x1515, 0x07e7, 0x3068, 0x8008 }, 16, 0x000a2420, 1},
++	{{0x2469, 0x7ac1, 0xd79d, 0x98c3, 0xc681, 0x32e1, 0x3028, 0x8008, 0x94c3, 0xf604, 0xf703, 0x98c3, 0xf241, 0x39c0, 0x3ed8, 0x8008 }, 16, 0x000a2440, 1},
++	{{0x96c3, 0x3224, 0x3afe, 0x800a, 0x96c3, 0x38c0, 0x3d58, 0x8008, 0x01e5, 0x306e, 0x8008, 0x7461, 0x6469, 0x90c0, 0x98c3, 0xc581 }, 16, 0x000a2460, 1},
++	{{0x33e1, 0x2ff8, 0x8008, 0x94c3, 0xf504, 0xf703, 0x98c3, 0xf341, 0x39c0, 0x3f98, 0x8008, 0x96c3, 0x3224, 0x3afe, 0x800a, 0x96c3 }, 16, 0x000a2480, 1},
++	{{0x38c0, 0x3bd8, 0x8008, 0x0025, 0x336a, 0x8009, 0x77e0, 0xd3a4, 0x90c0, 0x96c2, 0x3344, 0x3ad0, 0x800a, 0xe768, 0x94c0, 0x9e21 }, 16, 0x000a24a0, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a24c0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x04c4, 0x22cc, 0x8009, 0xe748, 0x94c0, 0xd230, 0xf004 }, 16, 0x000a24e0, 1},
++	{{0x8045, 0x3414, 0x8030, 0x802d, 0x96c0, 0x3414, 0x8060, 0x7540, 0x94c0, 0xd892, 0x801f, 0x96c0, 0x3414, 0x8020, 0x7440, 0x94c0 }, 16, 0x000a2500, 1},
++	{{0xd990, 0x8427, 0x3024, 0x2544, 0x800a, 0x03fe, 0x9ff8, 0x01fe, 0x9ff8, 0x9ac0, 0x03fc, 0x9ff8, 0x90c0, 0x2521, 0x8aaa, 0x64ad }, 16, 0x000a2520, 1},
++	{{0x01fe, 0x9ff8, 0x98c0, 0xf284, 0x3181, 0x2937, 0x8000, 0x98c0, 0x2400, 0x8041, 0xd992, 0xe768, 0x3465, 0x8001, 0x96c0, 0xd81d }, 16, 0x000a2540, 1},
++	{{0x3ac9, 0x8343, 0x6808, 0x7c4d, 0x94c0, 0x6461, 0x9f70, 0xd441, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a2560, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x34d0, 0x2460, 0x3211, 0x2000, 0x8000, 0x3160, 0x24e6, 0x2461 }, 16, 0x000a2580, 1},
++	{{0x3508, 0x2000, 0x8000, 0x98c6, 0x33e1, 0x3fff, 0x803f, 0x6c90, 0x334c, 0x8000, 0x2669, 0x3b40, 0x31e8, 0x8008, 0x3940, 0x33e8 }, 16, 0x000a25a0, 1},
++	{{0x8008, 0x94c3, 0xca41, 0xcd42, 0x90c0, 0x92c3, 0xed3a, 0x92c3, 0xcd49, 0x72e1, 0x90c0, 0x98c6, 0x6468, 0x31e0, 0x3fff, 0xbfff }, 16, 0x000a25c0, 1},
++	{{0x96c0, 0xdd81, 0x32c9, 0x9296, 0x96c0, 0x7cc1, 0x36ca, 0x8647, 0x94c0, 0xd892, 0xca41, 0x90c0, 0xeb1a, 0x1313, 0xea19, 0x1052 }, 16, 0x000a25e0, 1},
++	{{0xda93, 0x66e1, 0x6291, 0x92c3, 0x66e4, 0x94c0, 0x76cd, 0x9f70, 0xd81d, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a2600, 1},
++	{{0x98c0, 0x3bc8, 0x2400, 0xbfff, 0xc482, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x0493, 0xefe8, 0x3a20, 0xa000, 0x08c6 }, 16, 0x000a2620, 1},
++	{{0x38d0, 0x8008, 0x5397, 0x98c0, 0x03e2, 0x35c0, 0x8008, 0xe748, 0x3a80, 0xa000, 0xe850, 0x3d20, 0x336c, 0x8009, 0x3a80, 0xa000 }, 16, 0x000a2640, 1},
++	{{0x51d0, 0x3ee0, 0x35a0, 0x8008, 0x3c20, 0xa000, 0x2808, 0x8028, 0x90c0, 0x331d, 0x80ff, 0x3ec2, 0x3621, 0x3474, 0x8009, 0xcc45 }, 16, 0x000a2660, 1},
++	{{0x90c0, 0xec1d, 0x5394, 0x03e2, 0x359c, 0x8008, 0x3480, 0xa000, 0x55d0, 0x3ac9, 0x8208, 0xc941, 0x90c0, 0xe9fe, 0xe91d, 0x5391 }, 16, 0x000a2680, 1},
++	{{0x439e, 0x4696, 0x53d0, 0x371d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xee44, 0x4016, 0x290a }, 16, 0x000a26a0, 1},
++	{{0x8038, 0x54d2, 0x38cc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464, 0x9ac0, 0x6f10, 0x0ac6, 0x38d0, 0x8008, 0xee42, 0x001e, 0x3c20 }, 16, 0x000a26c0, 1},
++	{{0x336c, 0x8009, 0x0616, 0xea52, 0x12d2, 0x3ee0, 0x358c, 0x8008, 0x9ac0, 0x2a0b, 0x8028, 0x90c0, 0x351c, 0x80ff, 0x3e42, 0x3321 }, 16, 0x000a26e0, 1},
++	{{0x3474, 0x8009, 0xc944, 0x90c0, 0xe91c, 0x5791, 0x07e2, 0x3588, 0x8008, 0x56d2, 0x3ccd, 0x8208, 0xc945, 0x90c0, 0xe9fe, 0xe91c }, 16, 0x000a2700, 1},
++	{{0x5491, 0x449e, 0x4396, 0x53d3, 0x3719, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xee44, 0x4016 }, 16, 0x000a2720, 1},
++	{{0x290b, 0x803a, 0x52d3, 0x34cc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464, 0x9ac0, 0x6d10, 0x6e90, 0x6c90, 0xee42, 0x9770, 0x3455 }, 16, 0x000a2740, 1},
++	{{0x401e, 0x0216, 0x32e1, 0x359c, 0x8008, 0x33e1, 0x3588, 0x8008, 0x3ee0, 0x31f8, 0x8008, 0x3de0, 0x3078, 0x8008, 0x03e2, 0x35c4 }, 16, 0x000a2760, 1},
++	{{0x8008, 0x02e2, 0x35bc, 0x8008, 0x94c8, 0xc01e, 0xc01d, 0x98c0, 0x09e6, 0x35c0, 0x8008, 0xc782, 0x3401, 0x2000, 0x8030, 0xe9f1 }, 16, 0x000a2780, 1},
++	{{0x39e0, 0x35b0, 0x8008, 0x96c2, 0x3101, 0x2605, 0x8020, 0x96c2, 0x01e2, 0x35c0, 0x8008, 0x05e6, 0x35c0, 0x8008, 0x9ac0, 0x3b09 }, 16, 0x000a27a0, 1},
++	{{0x8030, 0x90c0, 0x3b1e, 0x8300, 0x3261, 0xdf28, 0x92c3, 0x6c90, 0x96c6, 0x737f, 0xc181, 0x7f42, 0x8026, 0x98c0, 0x01e1, 0x37cf }, 16, 0x000a27c0, 1},
++	{{0x8008, 0xcb46, 0xcca0, 0xeb19, 0x5a93, 0x90c0, 0x9a61, 0x3124, 0x2800, 0x800a, 0x3024, 0x2800, 0x800a, 0x2c00, 0x8060, 0xcc90 }, 16, 0x000a27e0, 1},
++	{{0x9ec0, 0x6e90, 0x6e10, 0x64e9, 0x0ce0, 0x37cc, 0x8008, 0xc681, 0x9ac0, 0x6f90, 0xecf8, 0x05e2, 0x3378, 0x8008, 0x98c0, 0x38ed }, 16, 0x000a2800, 1},
++	{{0x805f, 0xecfc, 0xc0ae, 0x98c0, 0xcc4b, 0x05e2, 0x3378, 0x8008, 0x98c7, 0x38ed, 0x805e, 0x90c0, 0x75fb, 0x98c7, 0x05e2, 0x3378 }, 16, 0x000a2820, 1},
++	{{0x8008, 0x7dc1, 0x96c0, 0x3ced, 0x805d, 0x6e10, 0x05e2, 0x3378, 0x8008, 0x36ed, 0x8310, 0x3be0, 0x337c, 0x8008, 0x05e2, 0x3378 }, 16, 0x000a2840, 1},
++	{{0x8008, 0x3eed, 0x804f, 0x31e1, 0x3078, 0x8008, 0x05e2, 0x3378, 0x8008, 0x419b, 0x4793, 0x1193, 0x32e1, 0x31f8, 0x8008, 0x3ce9 }, 16, 0x000a2860, 1},
++	{{0x805f, 0x4193, 0x5193, 0x3ce9, 0x805e, 0x4193, 0x5793, 0x3cef, 0x805d, 0x4793, 0x5793, 0x36ef, 0x8310, 0x4793, 0x5193, 0x38e9 }, 16, 0x000a2880, 1},
++	{{0x804f, 0x019b, 0x32e4, 0x3a68, 0x8001, 0x4293, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3920, 0x2f60, 0x800a, 0xc0ae, 0x32e4, 0x3a62 }, 16, 0x000a28a0, 1},
++	{{0x8001, 0x94c0, 0xc184, 0xc0ae, 0x32e4, 0x3a68, 0x8001, 0xc09a, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3920, 0x34d0, 0x800a, 0xc09a }, 16, 0x000a28c0, 1},
++	{{0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc184, 0xc09a, 0x9f7d, 0x9ac0, 0x6c90, 0x3ac8, 0x2418, 0xbfff, 0xc7b0, 0x98c0, 0xf741, 0x3bc8 }, 16, 0x000a28e0, 1},
++	{{0x2418, 0xbfff, 0x1592, 0x39c8, 0x241c, 0xbfff, 0x96c0, 0x3b0f, 0x8010, 0xef44, 0x27e9, 0x38e0, 0x3540, 0x8008, 0x90c0, 0x96c2 }, 16, 0x000a2900, 1},
++	{{0x02e6, 0x35c0, 0x8008, 0x96c2, 0x36f9, 0x3fff, 0xbfef, 0x98c1, 0x05e6, 0x35c0, 0x8008, 0xdf02, 0x94c1, 0x4592, 0x4692, 0x5593 }, 16, 0x000a2920, 1},
++	{{0x3b0d, 0x8020, 0x66e9, 0x90c0, 0x96c2, 0x3cc8, 0x2418, 0xbfff, 0x96c3, 0x3ac8, 0x2418, 0xbfff, 0x96c2, 0x07e6, 0x35c0, 0x8008 }, 16, 0x000a2940, 1},
++	{{0x96c2, 0x33f9, 0x3fff, 0xbfdf, 0x98c1, 0x04e6, 0x35c0, 0x8008, 0xdd87, 0x94c1, 0x4492, 0x4394, 0x1797, 0x32e4, 0x3c8a, 0x8001 }, 16, 0x000a2960, 1},
++	{{0x4791, 0x3ac8, 0x241c, 0xbfff, 0x39e0, 0x3544, 0x8008, 0x1192, 0x3cc8, 0x241c, 0xbfff, 0x96c0, 0x331a, 0x8f00, 0xebe9, 0x94c0 }, 16, 0x000a2980, 1},
++	{{0xdd28, 0xeb62, 0x0211, 0x4213, 0x1194, 0xe94c, 0x96c0, 0x33f8, 0x9000, 0xeae9, 0x9ac0, 0xdc2c, 0xea62, 0x3bc8, 0x241c, 0xbfff }, 16, 0x000a29a0, 1},
++	{{0x0011, 0x4012, 0x1494, 0xe94c, 0x96c0, 0x390b, 0x800f, 0xece9, 0x9ac0, 0xd80b, 0xec62, 0x3ae8, 0x3c30, 0xbfff, 0x0011, 0x4014 }, 16, 0x000a29c0, 1},
++	{{0x1693, 0xe94c, 0x3d0f, 0x80f0, 0x98c0, 0xdfb4, 0x3309, 0x20ff, 0x9f55, 0x4709, 0x4711, 0x4392, 0x02e6, 0x35c0, 0x8008, 0x350f }, 16, 0x000a29e0, 1},
++	{{0x8030, 0x67e9, 0x90c0, 0x98c3, 0x32e0, 0x3378, 0x8008, 0xc783, 0x94c3, 0x0902, 0xa001, 0x96c3, 0x02e2, 0x35c8, 0x8008, 0x96c3 }, 16, 0x000a2a00, 1},
++	{{0x07e1, 0x37d0, 0x8008, 0x9f7c, 0x00e7, 0x37cc, 0x8008, 0x32e4, 0x3c48, 0x8001, 0x01a4, 0x33be, 0x8009, 0x9ec0, 0x77f0, 0x7750 }, 16, 0x000a2a20, 1},
++	{{0x6e90, 0xc2a0, 0x39e0, 0x378c, 0x8008, 0x9ac0, 0xd3a1, 0x38e0, 0x3464, 0x8008, 0xc381, 0x8087, 0x94c0, 0xf602, 0xf542, 0x3224 }, 16, 0x000a2a40, 1},
++	{{0x3600, 0x800a, 0xf201, 0x96c0, 0x6e10, 0xc2a0, 0xf602, 0x94c0, 0xf442, 0xf201, 0x39e0, 0x374c, 0x8008, 0x3224, 0x3600, 0x800a }, 16, 0x000a2a60, 1},
++	{{0x38e0, 0x3388, 0x8008, 0x9ac0, 0xd3a6, 0x6d10, 0x3be0, 0x346c, 0x8008, 0x841d, 0x3ce0, 0x3390, 0x8008, 0x3561, 0x2324, 0x8008 }, 16, 0x000a2a80, 1},
++	{{0x0593, 0x4594, 0x94c0, 0xeb52, 0xec52, 0x0213, 0x4214, 0x9ac0, 0xd3a3, 0x6f10, 0x39e0, 0x346c, 0x8008, 0x8433, 0x3be0, 0x3390 }, 16, 0x000a2aa0, 1},
++	{{0x8008, 0x3761, 0x27a6, 0x8008, 0x0791, 0x4793, 0x94c0, 0xe952, 0xeb52, 0x3024, 0x2aec, 0x800a, 0x0611, 0x4613, 0x39e0, 0x3476 }, 16, 0x000a2ac0, 1},
++	{{0x8008, 0x3be0, 0x339a, 0x8008, 0x4311, 0x4313, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a2ae0, 1},
++	{{0x3e00, 0xa10c, 0x74d7, 0x7456, 0x07c5, 0x38b8, 0x8008, 0xe8ee, 0x3667, 0x0ec6, 0x38d0, 0x8008, 0xd226, 0x9ac0, 0x2e0e, 0x8010 }, 16, 0x000a2b00, 1},
++	{{0x90c0, 0x2718, 0x8184, 0x52d6, 0x351d, 0x80ff, 0xd2a5, 0x8025, 0xd2a6, 0x8021, 0xd2a7, 0x801d, 0xd2a8, 0x90c0, 0x98c3, 0x38e0 }, 16, 0x000a2b20, 1},
++	{{0x35ae, 0x8008, 0xc3fe, 0x90c0, 0x94c7, 0x843a, 0x5710, 0x92c3, 0xdd87, 0x9ac0, 0x6f90, 0x38e0, 0x35a4, 0x8008, 0xc081, 0x03e6 }, 16, 0x000a2b40, 1},
++	{{0x359c, 0x8008, 0x0390, 0x3221, 0x3474, 0x8009, 0xe848, 0xeae8, 0xea64, 0x5412, 0x4418, 0x02e2, 0x359c, 0x8008, 0x4712, 0x5310 }, 16, 0x000a2b60, 1},
++	{{0xdd98, 0x4310, 0x54d6, 0x38ca, 0x8208, 0x6561, 0xd125, 0x8025, 0xd126, 0x8021, 0xd127, 0x801d, 0xd128, 0x90c0, 0x98c3, 0x39e0 }, 16, 0x000a2b80, 1},
++	{{0x35ae, 0x8008, 0xc0fd, 0x90c0, 0x94c7, 0x8436, 0x5411, 0x92c3, 0xdc04, 0x9ac0, 0x6d90, 0x39e0, 0x35a4, 0x8008, 0xc182, 0x3621 }, 16, 0x000a2ba0, 1},
++	{{0x3474, 0x8009, 0xece9, 0xec64, 0x5594, 0x4591, 0xe948, 0xede9, 0xed62, 0x5415, 0x4419, 0x4694, 0x4315, 0x5011, 0xdc19, 0x0011 }, 16, 0x000a2bc0, 1},
++	{{0xee42, 0x56d6, 0x3d1e, 0x80ff, 0xd325, 0x8025, 0xd326, 0x8021, 0xd327, 0x801d, 0xd328, 0x90c0, 0x98c3, 0x38e0, 0x359a, 0x8008 }, 16, 0x000a2be0, 1},
++	{{0xc3fe, 0x90c0, 0x94c7, 0x843a, 0x5110, 0x92c3, 0xdd81, 0x9ac0, 0x6e90, 0x38e0, 0x3590, 0x8008, 0xc281, 0x06e6, 0x3588, 0x8008 }, 16, 0x000a2c00, 1},
++	{{0x0690, 0x3121, 0x3474, 0x8009, 0xe848, 0xebe8, 0xeb64, 0x5713, 0x4718, 0x01e2, 0x3588, 0x8008, 0x1310, 0x4513, 0xdd9a, 0x4310 }, 16, 0x000a2c20, 1},
++	{{0x52d6, 0x34ca, 0x8208, 0x6561, 0xd125, 0x8029, 0xd126, 0x8025, 0xd127, 0x8021, 0xd128, 0x90c0, 0x98c3, 0x3ae0, 0x359a, 0x8008 }, 16, 0x000a2c40, 1},
++	{{0xc5fd, 0x90c0, 0x92c3, 0x5212, 0x94c7, 0x8436, 0xde82, 0x92c3, 0x4512, 0x2f90, 0x3be0, 0x3590, 0x8008, 0x3221, 0x3474, 0x8009 }, 16, 0x000a2c60, 1},
++	{{0xe9eb, 0xe964, 0x5591, 0x4593, 0xeb48, 0xe8eb, 0xe862, 0x5010, 0x401b, 0x4291, 0x4710, 0x5013, 0x0900, 0xa002, 0x4013, 0x07c5 }, 16, 0x000a2c80, 1},
++	{{0x38bb, 0x8008, 0x7767, 0xd326, 0x8009, 0xd325, 0x2718, 0x8124, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0xec50, 0x53d4, 0x371b, 0x80ff }, 16, 0x000a2ca0, 1},
++	{{0xd1a9, 0x800f, 0xd1aa, 0x800b, 0xd1ab, 0x8007, 0xd1ac, 0x8433, 0x2d10, 0x3de0, 0x35a4, 0x8008, 0x07e6, 0x359c, 0x8008, 0x0795 }, 16, 0x000a2cc0, 1},
++	{{0x3021, 0x3474, 0x8009, 0xed48, 0xeaed, 0xea64, 0x5112, 0x411d, 0x00e2, 0x359c, 0x8008, 0x4212, 0x5515, 0x0905, 0xa001, 0x4515 }, 16, 0x000a2ce0, 1},
++	{{0x51d4, 0x32cf, 0x8208, 0x67e1, 0xd3a9, 0x800f, 0xd3aa, 0x800b, 0xd3ab, 0x8007, 0xd3ac, 0x842f, 0x2e90, 0x39e0, 0x35a4, 0x8008 }, 16, 0x000a2d00, 1},
++	{{0x3021, 0x3474, 0x8009, 0xe8e9, 0xe864, 0x5390, 0x4391, 0xe948, 0xeee9, 0xee62, 0x5616, 0x4619, 0x4090, 0x4516, 0x5611, 0x0906 }, 16, 0x000a2d20, 1},
++	{{0xa002, 0x4611, 0xec42, 0x53d4, 0x3718, 0x80ff, 0xd029, 0x800f, 0xd02a, 0x800b, 0xd02b, 0x8007, 0xd02c, 0x8433, 0x2e10, 0x3ae0 }, 16, 0x000a2d40, 1},
++	{{0x3590, 0x8008, 0x06e6, 0x3588, 0x8008, 0x0692, 0x3721, 0x3474, 0x8009, 0xea48, 0xebea, 0xeb64, 0x5213, 0x421a, 0x07e2, 0x3588 }, 16, 0x000a2d60, 1},
++	{{0x8008, 0x4413, 0x5312, 0x0903, 0xa001, 0x4312, 0x56d4, 0x3ccb, 0x8208, 0x65e1, 0xd1a9, 0x800f, 0xd1aa, 0x800b, 0xd1ab, 0x8007 }, 16, 0x000a2d80, 1},
++	{{0xd1ac, 0x842f, 0x2f10, 0x3ce0, 0x3590, 0x8008, 0x3421, 0x3474, 0x8009, 0xe8ec, 0xe864, 0x5790, 0x4794, 0xec48, 0xedec, 0xed62 }, 16, 0x000a2da0, 1},
++	{{0x5715, 0x471c, 0x4490, 0x4615, 0x5114, 0x0901, 0xa002, 0x4114, 0x3a20, 0xb800, 0x77d1, 0x7750, 0xeee8, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a2dc0, 1},
++	{{0x0ae6, 0x35bc, 0x8008, 0x3820, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0xea52, 0x94c0, 0x9620, 0x9720, 0x3840, 0xa100, 0x5712, 0x2e0d }, 16, 0x000a2de0, 1},
++	{{0x8038, 0x3880, 0xa000, 0x3f1b, 0x8001, 0x52d5, 0x9ac0, 0x65e9, 0x3519, 0x80ff, 0x9e20, 0x9f20, 0x94c0, 0x7461, 0x8017, 0x3344 }, 16, 0x000a2e00, 1},
++	{{0x3d90, 0x800a, 0x98c0, 0xc590, 0x3124, 0x2e38, 0x800a, 0x3244, 0x3d90, 0x800a, 0x7461, 0xc58c, 0x98c0, 0xcb45, 0x09e6, 0x35bc }, 16, 0x000a2e20, 1},
++	{{0x8008, 0x90c0, 0xeb19, 0x4013, 0x0ee6, 0x35bc, 0x8008, 0x0cc6, 0x38d0, 0x8008, 0xee52, 0x96c0, 0x5416, 0x2c0c, 0x8038, 0x96c0 }, 16, 0x000a2e40, 1},
++	{{0x3918, 0x8002, 0x56d4, 0x96c0, 0x6469, 0x3cc9, 0x8208, 0x94c0, 0x7461, 0x8017, 0x3344, 0x3d90, 0x800a, 0x98c0, 0xc390, 0x3124 }, 16, 0x000a2e60, 1},
++	{{0x2e92, 0x800a, 0x3cc9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0xc38e, 0x98c0, 0x0ce6, 0x35bc, 0x8008, 0xc843, 0x90c0, 0xe81c }, 16, 0x000a2e80, 1},
++	{{0x4010, 0x0fe6, 0x35c4, 0x8008, 0x0dc6, 0x38d0, 0x8008, 0xef52, 0x96c0, 0x5017, 0x2d0c, 0x803a, 0x96c0, 0x311e, 0x8001, 0x50d4 }, 16, 0x000a2ea0, 1},
++	{{0x6769, 0x96c7, 0x801b, 0x3118, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7460, 0x98c0, 0xc590, 0x3124, 0x2eea, 0x800a, 0x311c, 0x80ff }, 16, 0x000a2ec0, 1},
++	{{0x3244, 0x3d90, 0x800a, 0x7464, 0xc58c, 0x98c0, 0xcf45, 0x0de6, 0x35c4, 0x8008, 0x90c0, 0xef1d, 0x4017, 0x0be6, 0x35c4, 0x8008 }, 16, 0x000a2ee0, 1},
++	{{0x0dc6, 0x38d0, 0x8008, 0xeb52, 0x96c0, 0x5113, 0x2d08, 0x803a, 0x96c0, 0x331f, 0x8002, 0x55d0, 0x96c0, 0x67e9, 0x3ac8, 0x8208 }, 16, 0x000a2f00, 1},
++	{{0x94c0, 0x7460, 0x8017, 0x3344, 0x3d90, 0x800a, 0x98c0, 0xc590, 0x3124, 0x2f44, 0x800a, 0x3acd, 0x8208, 0x3244, 0x3d90, 0x800a }, 16, 0x000a2f20, 1},
++	{{0x7465, 0xc58e, 0x98c0, 0xcd45, 0x09e6, 0x35c4, 0x8008, 0x94c0, 0x9e21, 0x9f21, 0xed19, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4015 }, 16, 0x000a2f40, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x98c0, 0x36aa, 0x3c20, 0xbfff, 0xc0ae, 0x94c0, 0x9e20, 0x9f20, 0x3680, 0xa000, 0x5696, 0xe750, 0x0622 }, 16, 0x000a2f60, 1},
++	{{0x333c, 0x8009, 0x3ee0, 0x35cc, 0x8008, 0x32e4, 0x3a68, 0x8001, 0x3fe0, 0x368c, 0x8008, 0x0125, 0x336a, 0x8009, 0x7461, 0xd022 }, 16, 0x000a2f80, 1},
++	{{0x90c0, 0x96c2, 0x3344, 0x3ad0, 0x800a, 0x3324, 0x2de0, 0x800a, 0x2f10, 0x3dc8, 0x3c14, 0xbfff, 0x39c0, 0x2040, 0x8008, 0x1295 }, 16, 0x000a2fa0, 1},
++	{{0x3dc0, 0x21c0, 0x8008, 0x3509, 0x8100, 0x24e9, 0x3ba0, 0x3e00, 0x8008, 0x8019, 0x2704, 0x8060, 0x3ca0, 0x3f80, 0x8008, 0x90c0 }, 16, 0x000a2fc0, 1},
++	{{0x94d0, 0x461c, 0x461b, 0x0619, 0x461d, 0x98c0, 0x0ae6, 0x35bc, 0x8008, 0xc781, 0x98c0, 0xf707, 0x02a4, 0x33be, 0x8009, 0x1992 }, 16, 0x000a2fe0, 1},
++	{{0xea4c, 0x1412, 0xecea, 0x94c0, 0xea42, 0xec68, 0x1794, 0x5312, 0x94c0, 0xf206, 0xf742, 0x94c0, 0xf305, 0xf401, 0x32e4, 0x208e }, 16, 0x000a3000, 1},
++	{{0x800a, 0x38e0, 0x35cc, 0x8008, 0x98c0, 0x0ce6, 0x35c4, 0x8008, 0xc681, 0x98c0, 0x01a4, 0x33be, 0x8009, 0xf607, 0x1994, 0xec4c }, 16, 0x000a3020, 1},
++	{{0x1714, 0xedec, 0x94c0, 0xed68, 0xec42, 0x1495, 0x5514, 0x94c0, 0xf106, 0xf442, 0x94c0, 0xf505, 0xf701, 0x32e4, 0x208e, 0x800a }, 16, 0x000a3040, 1},
++	{{0x38e0, 0x368c, 0x8008, 0x02e6, 0x35c0, 0x8008, 0x3508, 0x8010, 0x2469, 0x3ae0, 0x3476, 0x8008, 0x802b, 0x1612, 0x39e0, 0x35cc }, 16, 0x000a3060, 1},
++	{{0x8008, 0x98c0, 0xd321, 0x06a4, 0x33be, 0x8009, 0x8017, 0x3224, 0x3a38, 0x800a, 0x98c0, 0xf601, 0x38e0, 0x3464, 0x8008, 0x90c0 }, 16, 0x000a3080, 1},
++	{{0xeee8, 0x03e6, 0x35c0, 0x8008, 0x3708, 0x8020, 0x2469, 0x3de0, 0x339a, 0x8008, 0x802b, 0x1715, 0x00a4, 0x33be, 0x8009, 0x98c0 }, 16, 0x000a30a0, 1},
++	{{0xd3a1, 0x39e0, 0x368c, 0x8008, 0x8017, 0x3224, 0x3a38, 0x800a, 0x98c0, 0xf001, 0x38e0, 0x3388, 0x8008, 0x90c0, 0xefe8, 0x98c0 }, 16, 0x000a30c0, 1},
++	{{0x0de6, 0x35bc, 0x8008, 0xc281, 0x98c0, 0x06e4, 0x37cc, 0x8008, 0xe9ee, 0x98c0, 0xed50, 0x3481, 0x2000, 0x8000, 0x1715, 0xed68 }, 16, 0x000a30e0, 1},
++	{{0x27e9, 0x1195, 0xe8ee, 0x8017, 0x94c0, 0xf207, 0xf606, 0x94c0, 0xf705, 0xf142, 0x32e4, 0x208e, 0x800a, 0xf401, 0x98c0, 0x0de6 }, 16, 0x000a3100, 1},
++	{{0x35c4, 0x8008, 0xc581, 0x98c0, 0x04e4, 0x37cc, 0x8008, 0xe9ef, 0x98c0, 0xed50, 0x3381, 0x2000, 0x8000, 0x1015, 0xed68, 0x2469 }, 16, 0x000a3120, 1},
++	{{0x1795, 0xe8ef, 0x8017, 0x94c0, 0xf507, 0xf406, 0x94c0, 0xf005, 0xf742, 0x32e4, 0x208e, 0x800a, 0xf301, 0x3ac8, 0x2404, 0xbfff }, 16, 0x000a3140, 1},
++	{{0x3be0, 0x3378, 0x8008, 0x1c92, 0x01e5, 0x37cf, 0x8008, 0x02e7, 0x37cc, 0x8008, 0xebac, 0x90c0, 0x96c2, 0x3ce0, 0x31f8, 0x8008 }, 16, 0x000a3160, 1},
++	{{0x98c7, 0x64e9, 0x3ce0, 0x3078, 0x8008, 0x8043, 0x9ac0, 0x656a, 0x3de0, 0x355e, 0x8008, 0xcaa4, 0x8499, 0x1015, 0xed4c, 0x1415 }, 16, 0x000a3180, 1},
++	{{0xe8ed, 0x96c0, 0x6c7c, 0xe83a, 0xed78, 0x96c0, 0x9b42, 0x2b03, 0x800e, 0x1110, 0x5515, 0x6d7c, 0x521f, 0xd51c, 0x421c, 0x92d0 }, 16, 0x000a31a0, 1},
++	{{0x521e, 0xd51d, 0x421c, 0x3124, 0x3230, 0x800a, 0x02e6, 0x35c0, 0x8008, 0x350a, 0x8010, 0x2569, 0x00e7, 0x37cc, 0x8008, 0x802b }, 16, 0x000a31c0, 1},
++	{{0x246a, 0x38e0, 0x3546, 0x8008, 0x8449, 0x1310, 0xe84c, 0x96c0, 0x9b40, 0x2b03, 0x800c, 0x5710, 0x6f7c, 0x92d0, 0x521e, 0xd51f }, 16, 0x000a31e0, 1},
++	{{0x421c, 0x3124, 0x3230, 0x800a, 0x07e7, 0x37cc, 0x8008, 0x27ea, 0x38e0, 0x355e, 0x8008, 0x841b, 0x1010, 0xe84c, 0x96c0, 0x9b47 }, 16, 0x000a3200, 1},
++	{{0x2b03, 0x800c, 0x5410, 0x6c7c, 0x92d0, 0x501f, 0xd41c, 0x401c, 0x9cc0, 0x6e90, 0x6c90, 0x00e5, 0x37ce, 0x8008, 0xc298, 0x9ac0 }, 16, 0x000a3220, 1},
++	{{0x6469, 0x3ae0, 0x3542, 0x8008, 0xc088, 0x2518, 0x826a, 0x96c0, 0x9344, 0x2a0e, 0x8004, 0x96c0, 0xe8ee, 0x2b03, 0x802a, 0x98c0 }, 16, 0x000a3240, 1},
++	{{0x3de0, 0x3540, 0x8008, 0xe862, 0x3cc8, 0x241c, 0xbfff, 0x39c8, 0x2420, 0xbfff, 0x3fc8, 0x2418, 0xbfff, 0x94c0, 0x2e0b, 0x8002 }, 16, 0x000a3260, 1},
++	{{0x94c0, 0x97bd, 0x5413, 0x67e9, 0x2518, 0x8212, 0x3820, 0xa000, 0x6669, 0xc581, 0xcb85, 0x98c7, 0x2618, 0x8204, 0x90c0, 0x7a61 }, 16, 0x000a3280, 1},
++	{{0x92c3, 0x4413, 0x3a20, 0xa000, 0x9dbd, 0x30e2, 0x3570, 0x8008, 0x90c0, 0x34a0, 0xa000, 0xed8b, 0x3880, 0xa000, 0xedfe, 0x2518 }, 16, 0x000a32a0, 1},
++	{{0x81e2, 0x36a0, 0xa000, 0xed18, 0xc783, 0x3840, 0xa100, 0xd791, 0x5e95, 0x5316, 0x94c0, 0xc483, 0xc683, 0x3880, 0xa000, 0xd611 }, 16, 0x000a32c0, 1},
++	{{0xd711, 0x9e61, 0x1391, 0x5410, 0x98c0, 0xdf83, 0x7a41, 0x5310, 0xc683, 0x67e0, 0x27e9, 0xc78f, 0x94c0, 0xd790, 0x8041, 0x25e9 }, 16, 0x000a32e0, 1},
++	{{0x39e1, 0xc78f, 0x94c0, 0xd790, 0x801f, 0x96c0, 0xdb07, 0xd590, 0x4310, 0x5794, 0xdf07, 0x98c0, 0xdd9e, 0x3024, 0x332c, 0x800a }, 16, 0x000a3300, 1},
++	{{0x4394, 0x1616, 0xc382, 0x7b41, 0x4616, 0x939d, 0x98c0, 0xc7b2, 0x3024, 0x349a, 0x800a, 0x4713, 0x3a00, 0xa004, 0xda07, 0xd610 }, 16, 0x000a3320, 1},
++	{{0x4410, 0xc3b2, 0x5794, 0x3400, 0xa004, 0xde07, 0x3400, 0xa800, 0xde1c, 0x4494, 0x0313, 0x3024, 0x349a, 0x800a, 0x969d, 0x1491 }, 16, 0x000a3340, 1},
++	{{0xc783, 0x94c0, 0xd791, 0xc6b2, 0xdf84, 0x67e0, 0x27e9, 0xc784, 0x94c6, 0x8031, 0x79e1, 0x39c1, 0xc781, 0x3673, 0x0316, 0xd792 }, 16, 0x000a3360, 1},
++	{{0x94c0, 0xd230, 0xdb87, 0x840f, 0x5397, 0xdf83, 0x4797, 0x3420, 0xa000, 0x9b9d, 0x98c0, 0xc6b2, 0x3024, 0x349a, 0x800a, 0x4613 }, 16, 0x000a3380, 1},
++	{{0x4316, 0x0613, 0x3024, 0x349a, 0x800a, 0x979d, 0x1791, 0x5610, 0x1310, 0xde07, 0x6660, 0x2669, 0x5412, 0x8041, 0x98c0, 0x6769 }, 16, 0x000a33a0, 1},
++	{{0x7b61, 0xc78f, 0xc481, 0x94c0, 0xd790, 0x801f, 0x96c0, 0xdb87, 0xd710, 0x4610, 0x5394, 0xdf83, 0x98c0, 0xdf1f, 0x3024, 0x33ec }, 16, 0x000a33c0, 1},
++	{{0x800a, 0x4694, 0x1616, 0xc482, 0x7b41, 0x4616, 0x94c0, 0x949d, 0xc7b2, 0x0713, 0x3124, 0x349a, 0x800a, 0x98c0, 0x7263, 0x79c1 }, 16, 0x000a33e0, 1},
++	{{0xc68f, 0xc4b2, 0x96c0, 0xd710, 0xc783, 0x802d, 0x3800, 0xa004, 0xdb06, 0xd590, 0x4310, 0x5694, 0x3400, 0xa004, 0xdf06, 0x3400 }, 16, 0x000a3400, 1},
++	{{0xa800, 0xdd9e, 0x4394, 0x0413, 0x3024, 0x349a, 0x800a, 0x979d, 0x2d90, 0x3024, 0x349a, 0x800a, 0x939d, 0x5491, 0xdf04, 0x6760 }, 16, 0x000a3420, 1},
++	{{0x6769, 0x90c0, 0x94c3, 0x5716, 0xc4b2, 0x94c3, 0x7bc1, 0xc682, 0x92c3, 0x4716, 0x94c7, 0x8446, 0x4413, 0x92c3, 0x969d, 0x1416 }, 16, 0x000a3440, 1},
++	{{0xc38f, 0x2669, 0xd590, 0x3607, 0xa008, 0x7a61, 0xdb03, 0x94c3, 0x4416, 0xc6b2, 0x94c7, 0x8427, 0x4613, 0x1710, 0xc6b2, 0x3bc1 }, 16, 0x000a3460, 1},
++	{{0xc483, 0x0710, 0xd790, 0x5394, 0x3400, 0xa004, 0xdf03, 0x3400, 0xa800, 0xdf9e, 0x4794, 0x4613, 0x949d, 0x9ad0, 0x78c2, 0x7844 }, 16, 0x000a3480, 1},
++	{{0x7941, 0xeb4c, 0xe84c, 0x94c0, 0xee4c, 0xea4c, 0xed4c, 0x05e1, 0x37ce, 0x8008, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a34a0, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x32e4, 0x3a68, 0x8001, 0xc09a, 0x94c0, 0xc181, 0x9f70, 0x01e1 }, 16, 0x000a34c0, 1},
++	{{0x37ce, 0x8008, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a34e0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6e90, 0x9720, 0x4998, 0x94c0, 0x9e20, 0x9f20, 0x0990 }, 16, 0x000a3500, 1},
++	{{0xf38d, 0x96c0, 0x65ea, 0xe84c, 0xc2a0, 0x4310, 0x94c0, 0xe846, 0x8412, 0x4210, 0x9f43, 0x90c0, 0x90c0, 0x92c8, 0x4519, 0x98c0 }, 16, 0x000a3520, 1},
++	{{0x6e90, 0x6d90, 0xf4c8, 0xefe8, 0x98c0, 0x6669, 0xef6a, 0x2304, 0x8060, 0x96c0, 0xebe8, 0x2b03, 0x8016, 0x96c1, 0x4497, 0x2f09 }, 16, 0x000a3540, 1},
++	{{0x8010, 0x94c6, 0xeb6a, 0x4997, 0x3ac2, 0x1d93, 0xce45, 0x90d0, 0xed1e, 0x4315, 0x94c0, 0xebe8, 0xf78e, 0x94c0, 0xd3a2, 0xeb64 }, 16, 0x000a3560, 1},
++	{{0x94c0, 0x4713, 0x8055, 0xd3a1, 0x8043, 0x9ac0, 0xd3a3, 0x3561, 0x26e6, 0x8008, 0xc381, 0x96c0, 0x8029, 0x2200, 0x8060, 0x9ac0 }, 16, 0x000a3580, 1},
++	{{0xd3a6, 0x3061, 0x24a4, 0x8008, 0xc382, 0x96c0, 0x842b, 0x2200, 0x80c0, 0xe86e, 0x0090, 0x3024, 0x35ee, 0x800a, 0xe84c, 0xe86e }, 16, 0x000a35a0, 1},
++	{{0x0590, 0x3024, 0x35ee, 0x800a, 0xe84c, 0x98c0, 0xe862, 0x3124, 0x35ee, 0x800a, 0x94c0, 0xc082, 0xe86e, 0x0013, 0x3261, 0x2866 }, 16, 0x000a35c0, 1},
++	{{0x8008, 0x0290, 0xc381, 0x96c0, 0xe84c, 0x2200, 0x8040, 0x4310, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0xe844, 0x9721, 0x9f70, 0x4210 }, 16, 0x000a35e0, 1},
++	{{0x96c0, 0x6f10, 0x9620, 0x9720, 0x0998, 0xc0a0, 0x94c0, 0x9e20, 0x9f20, 0x0990, 0xf38d, 0x25ea, 0xe84c, 0x4310, 0x94c0, 0xe846 }, 16, 0x000a3600, 1},
++	{{0x8412, 0x4010, 0x9f43, 0x90c0, 0x90c0, 0x92c8, 0x4619, 0x98c0, 0x6f90, 0x6e90, 0xf4c8, 0xeae8, 0x98c0, 0x6669, 0xea6a, 0x2304 }, 16, 0x000a3620, 1},
++	{{0x8060, 0x96c0, 0xefe8, 0x2b03, 0x8016, 0x96c1, 0x4492, 0x2a0e, 0x8010, 0x94c6, 0xef6a, 0x4e92, 0x3bc2, 0x1997, 0xcb47, 0x90d0 }, 16, 0x000a3640, 1},
++	{{0xe91b, 0x4511, 0x94c0, 0xede8, 0xf18e, 0x94c0, 0xd0a2, 0xed64, 0x94c0, 0x4115, 0x8073, 0xd0a1, 0x805f, 0x9ac0, 0xd0a3, 0x3461 }, 16, 0x000a3660, 1},
++	{{0x26e6, 0x8008, 0xc381, 0x96c0, 0x8037, 0x2000, 0x8060, 0x9ac0, 0xd0a6, 0x3461, 0x24a4, 0x8008, 0xc782, 0x96c0, 0x8449, 0x2340 }, 16, 0x000a3680, 1},
++	{{0x8000, 0x96c0, 0xe86e, 0x2000, 0x80c0, 0x4490, 0xe84c, 0x4710, 0x98c0, 0xe846, 0x3024, 0x3704, 0x800a, 0x4308, 0xe86e, 0x96c0 }, 16, 0x000a36a0, 1},
++	{{0x4490, 0x2440, 0x8000, 0xe84c, 0x4310, 0x98c0, 0xe846, 0x3024, 0x3704, 0x800a, 0x4408, 0xe862, 0x0510, 0x3024, 0x3704, 0x800a }, 16, 0x000a36c0, 1},
++	{{0xe844, 0x96c0, 0x6c90, 0xc582, 0xe86e, 0x0515, 0x3761, 0x2866, 0x8008, 0x0790, 0xc381, 0x96c0, 0xe84c, 0x2000, 0x8040, 0x4310 }, 16, 0x000a36e0, 1},
++	{{0xe846, 0x4108, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4010, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a3700, 1},
++	{{0x3e00, 0xa10c, 0x7456, 0x74d7, 0x02a4, 0x33be, 0x8009, 0xe8ef, 0x98c0, 0x3612, 0x8020, 0xe748, 0xc481, 0x2718, 0x8102, 0x9ac0 }, 16, 0x000a3720, 1},
++	{{0x2200, 0x80c0, 0x90c0, 0x3412, 0x8030, 0x98c0, 0x3181, 0x26a0, 0x8009, 0xf201, 0x94c1, 0xc783, 0xc782, 0x94c0, 0xf142, 0xf702 }, 16, 0x000a3740, 1},
++	{{0x39e0, 0x3a00, 0x8008, 0x3224, 0x3510, 0x800a, 0x3820, 0x2178, 0x8009, 0x98c0, 0x3081, 0x23a0, 0x8009, 0xf702, 0x96c0, 0xf042 }, 16, 0x000a3760, 1},
++	{{0x2400, 0x80c0, 0x98c0, 0xf401, 0x3900, 0x2e00, 0x8009, 0x3224, 0x3510, 0x800a, 0x3800, 0x3804, 0x8009, 0x98c0, 0x3181, 0x22e0 }, 16, 0x000a3780, 1},
++	{{0x8009, 0xf702, 0x96c0, 0xf142, 0x2000, 0x80c0, 0x98c0, 0xf001, 0x3900, 0x2600, 0x8009, 0x3224, 0x3510, 0x800a, 0x3800, 0x3494 }, 16, 0x000a37a0, 1},
++	{{0x8009, 0x98c0, 0x3281, 0x25e0, 0x8009, 0xf702, 0x96c0, 0xf242, 0x2600, 0x80c0, 0x98c0, 0xf601, 0x39e0, 0x3e00, 0x8008, 0x3224 }, 16, 0x000a37c0, 1},
++	{{0x3510, 0x800a, 0x3800, 0x3200, 0x8009, 0x98c0, 0x3481, 0x29a0, 0x8009, 0xc6a0, 0x94c0, 0xf442, 0xf702, 0x98c0, 0xf601, 0x3900 }, 16, 0x000a37e0, 1},
++	{{0x3080, 0x8009, 0x3224, 0x3600, 0x800a, 0x3800, 0x3d2c, 0x8009, 0x98c0, 0x3481, 0x2b20, 0x8009, 0xc5a0, 0x94c0, 0xf442, 0xf702 }, 16, 0x000a3800, 1},
++	{{0x98c0, 0xf501, 0x3900, 0x31c0, 0x8009, 0x3224, 0x3600, 0x800a, 0x3800, 0x3b74, 0x8009, 0x3124, 0x386c, 0x800a, 0x3a00, 0x3d3e }, 16, 0x000a3820, 1},
++	{{0x8009, 0x3800, 0x3b86, 0x8009, 0x0412, 0x3920, 0x218a, 0x8009, 0x0410, 0x3d00, 0x3816, 0x8009, 0x0411, 0x3c00, 0x34a6, 0x8009 }, 16, 0x000a3840, 1},
++	{{0x0415, 0x3f00, 0x3212, 0x8009, 0x4414, 0x4417, 0x3a40, 0xb800, 0x77d1, 0x7750, 0xe768, 0xefe8, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a3860, 1},
++	{{0x3e80, 0xa10b, 0xd028, 0x75d6, 0x76d7, 0x7451, 0xe8ee, 0xe9ef, 0x98c0, 0x3e20, 0x24e8, 0x8009, 0xc784, 0x98c0, 0xe748, 0x3c20 }, 16, 0x000a3880, 1},
++	{{0x2508, 0x8009, 0x3a40, 0xa000, 0x3f20, 0x2538, 0x8009, 0xc4a0, 0x94c1, 0xc681, 0xc682, 0x3222, 0x2528, 0x8009, 0x3620, 0xa000 }, 16, 0x000a38a0, 1},
++	{{0x2100, 0x80c0, 0x3800, 0xa100, 0x6d90, 0x589a, 0x599e, 0x94c0, 0xf342, 0xf602, 0x3224, 0x3600, 0x800a, 0x3420, 0xa000, 0xf401 }, 16, 0x000a38c0, 1},
++	{{0x2d10, 0x189f, 0x599c, 0x94c0, 0xf242, 0xf602, 0x3224, 0x3510, 0x800a, 0x3420, 0xa000, 0xf101, 0x7be1, 0x67ea, 0x81c9, 0x3c00 }, 16, 0x000a38e0, 1},
++	{{0xa800, 0x74d0, 0xc784, 0x3c20, 0x2518, 0x8009, 0x3c20, 0xa000, 0xd0a8, 0x3f20, 0x24f8, 0x8009, 0xc0a0, 0x3e20, 0x2558, 0x8009 }, 16, 0x000a3900, 1},
++	{{0x94c1, 0xc681, 0xc682, 0x3622, 0x2548, 0x8009, 0x3620, 0xa000, 0x2200, 0x80c0, 0x3800, 0xa100, 0x6d90, 0x589e, 0x599f, 0x94c0 }, 16, 0x000a3920, 1},
++	{{0xf342, 0xf602, 0x3224, 0x3600, 0x800a, 0x3420, 0xa000, 0xf001, 0x2e10, 0x189e, 0x599c, 0x94c0, 0xf442, 0xf602, 0x3224, 0x3510 }, 16, 0x000a3940, 1},
++	{{0x800a, 0x3420, 0xa000, 0xf201, 0x7be1, 0x67ea, 0x81c9, 0x3a40, 0xb800, 0x77d5, 0x7753, 0xe768, 0xefe9, 0x3620, 0xa000, 0xeee8 }, 16, 0x000a3960, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3600, 0xa100, 0xf185, 0xefe8, 0x9730, 0x94c0, 0x9c22, 0x9530 }, 16, 0x000a3980, 1},
++	{{0x1c98, 0x1005, 0xa004, 0x3420, 0xa000, 0x5c98, 0x3820, 0xa000, 0x5898, 0x2803, 0x8040, 0x3420, 0xa000, 0x5e98, 0x3640, 0xa100 }, 16, 0x000a39a0, 1},
++	{{0x5018, 0xeaec, 0x1418, 0x6c50, 0x1518, 0xcc50, 0x94c0, 0x9841, 0x5018, 0x3420, 0xa000, 0x5118, 0x3620, 0xa008, 0x5018, 0x64ed }, 16, 0x000a39c0, 1},
++	{{0x3a40, 0xa000, 0x3703, 0x2800, 0x8008, 0xe8ee, 0x9d44, 0x3420, 0xa000, 0xebe8, 0x90c0, 0x92d0, 0x5059, 0x903c, 0x2c10, 0xeaec }, 16, 0x000a39e0, 1},
++	{{0x3420, 0xa000, 0x9d41, 0x90c0, 0x125a, 0x535b, 0x96c8, 0x601d, 0x525a, 0x535b, 0x641d, 0x92d0, 0xd41d, 0x7458, 0x94c0, 0x9028 }, 16, 0x000a3a00, 1},
++	{{0x6c10, 0x94c0, 0x9c23, 0x9531, 0x90c0, 0x90c0, 0x9731, 0x9f70, 0x36c0, 0xa000, 0x4c97, 0xe8ee, 0x3600, 0xa100, 0xf185, 0xefe8 }, 16, 0x000a3a20, 1},
++	{{0x9730, 0x94c0, 0x9b22, 0x9c22, 0x94c0, 0x9530, 0x5c98, 0x3820, 0xa000, 0x5c98, 0x1005, 0xa004, 0x3420, 0xa000, 0x5898, 0x3420 }, 16, 0x000a3a40, 1},
++	{{0xa000, 0x5e98, 0x3640, 0xa100, 0x5018, 0xeaec, 0x98c0, 0x6c50, 0x5418, 0x2803, 0x802e, 0x1518, 0xcc50, 0x3620, 0xa000, 0x5118 }, 16, 0x000a3a60, 1},
++	{{0x9841, 0x1018, 0xcb54, 0x3c40, 0xa004, 0x64ed, 0x5058, 0x3703, 0x2800, 0x8008, 0x3420, 0xa000, 0xe8ee, 0x96c0, 0x9944, 0x2903 }, 16, 0x000a3a80, 1},
++	{{0x8012, 0x5059, 0x3640, 0xa000, 0x983c, 0xede8, 0x3420, 0xa000, 0x9e41, 0x94c0, 0xebed, 0xeaec, 0x3640, 0xa000, 0x6c10, 0x571d }, 16, 0x000a3aa0, 1},
++	{{0x125a, 0x537b, 0x96c8, 0x601d, 0x525a, 0x537b, 0x3610, 0xa008, 0x601d, 0x6469, 0x3611, 0xb000, 0x7448, 0x6410, 0x4058, 0x3620 }, 16, 0x000a3ac0, 1},
++	{{0xa000, 0x574c, 0x6c10, 0x9531, 0x90c0, 0x90c0, 0x94c0, 0x9b23, 0x9c23, 0x9731, 0x9f70, 0x36c0, 0xa000, 0x4c97, 0xe8ee, 0xfbc3 }, 16, 0x000a3ae0, 1},
++	{{0xf287, 0x94c0, 0x9530, 0x9822, 0x94c0, 0x9730, 0x9c22, 0x3820, 0xa000, 0x5a9b, 0x1005, 0xa004, 0x1a9b, 0xedeb, 0x96c0, 0x5c9b }, 16, 0x000a3b00, 1},
++	{{0x2803, 0x8028, 0x94c0, 0x9842, 0x5313, 0x9ac0, 0x2c02, 0x8080, 0x90c0, 0x187a, 0x9fe0, 0x3703, 0x2800, 0x8000, 0x3680, 0xa000 }, 16, 0x000a3b20, 1},
++	{{0xe8ec, 0x65e9, 0x957f, 0x94c1, 0xc118, 0x5198, 0x94c1, 0xc01a, 0x419a, 0x115a, 0x105c, 0x6d10, 0x96d8, 0x6111, 0x505c, 0x515a }, 16, 0x000a3b40, 1},
++	{{0x3840, 0xa000, 0x6511, 0xece8, 0x65e9, 0x4261, 0x94c0, 0x9731, 0x9c23, 0x94c0, 0x9531, 0x9823, 0x90c0, 0x90c0, 0x9f70, 0x4a95 }, 16, 0x000a3b60, 1},
++	{{0x3620, 0xa100, 0xf785, 0xe9e8, 0x3680, 0xa000, 0xca47, 0xe9e8, 0x3600, 0xa008, 0x9730, 0x74d1, 0x94c0, 0x9c22, 0x9530, 0x3c02 }, 16, 0x000a3b80, 1},
++	{{0x2016, 0x8000, 0x94c0, 0x9632, 0x9732, 0x94c0, 0x9620, 0x9720, 0x1005, 0xa004, 0xe90a, 0x3703, 0x2080, 0x8000, 0x3a60, 0x22a0 }, 16, 0x000a3ba0, 1},
++	{{0x8008, 0x944a, 0x2c10, 0x2c90, 0x2d10, 0x6d90, 0x3640, 0xa000, 0x4dda, 0x5059, 0x3e48, 0xa0f0, 0x6000, 0x6081, 0x6102, 0x6183 }, 16, 0x000a3bc0, 1},
++	{{0x4dda, 0x5059, 0x3a00, 0xa0f0, 0x6000, 0x6081, 0x6102, 0x6183, 0x2465, 0x24e5, 0x2565, 0x65e5, 0x3600, 0xb800, 0x7651, 0x76d1 }, 16, 0x000a3be0, 1},
++	{{0x3600, 0xa004, 0x3683, 0x8005, 0x3400, 0xa804, 0xd99b, 0x3600, 0xa004, 0x3883, 0x8005, 0x3600, 0xa004, 0x38a3, 0x8004, 0x3600 }, 16, 0x000a3c00, 1},
++	{{0xa804, 0xd99b, 0xda1c, 0x3600, 0xa004, 0x3883, 0x8005, 0x3800, 0xba01, 0x7653, 0x76d3, 0x7551, 0x3c00, 0xa846, 0x3645, 0x8003 }, 16, 0x000a3c20, 1},
++	{{0x90c0, 0x3686, 0x8005, 0x3600, 0xb80c, 0xda9d, 0xdb1e, 0x3c00, 0xa846, 0x3845, 0x8003, 0x90c0, 0x3886, 0x8005, 0x3c00, 0xa846 }, 16, 0x000a3c40, 1},
++	{{0x3865, 0x8002, 0x90c0, 0x38a6, 0x8004, 0x3a00, 0xba0d, 0xda9d, 0xdb1e, 0xd91a, 0xda1c, 0x3c00, 0xa846, 0x3845, 0x8003, 0x90c0 }, 16, 0x000a3c60, 1},
++	{{0x3886, 0x8005, 0x3800, 0xa00d, 0x7451, 0x7552, 0x7653, 0x3c00, 0xac60, 0x3605, 0x8001, 0x90c0, 0x3646, 0x8003, 0x3a00, 0xa840 }, 16, 0x000a3c80, 1},
++	{{0x3687, 0x8005, 0xda9d, 0xdb1e, 0x3c00, 0xac60, 0x3805, 0x8001, 0xdb9f, 0x3846, 0x8003, 0x3600, 0xa840, 0x3887, 0x8005, 0x3c00 }, 16, 0x000a3ca0, 1},
++	{{0xac60, 0x3025, 0x8000, 0x90c0, 0x3066, 0x8002, 0x3a00, 0xa840, 0x30a7, 0x8004, 0xda9d, 0xdb1e, 0x3a00, 0xb603, 0xdb9f, 0xda19 }, 16, 0x000a3cc0, 1},
++	{{0xd99b, 0xdb9d, 0x3c00, 0xac20, 0x3085, 0x8000, 0x90c0, 0x3066, 0x8002, 0x3600, 0xa840, 0x30e7, 0x8004, 0x3600, 0xa004, 0x6fc1 }, 16, 0x000a3ce0, 1},
++	{{0x6cdf, 0x3400, 0xa804, 0x6fc7, 0x3400, 0xa004, 0x6769, 0x90c0, 0x96c2, 0x3124, 0x3dc4, 0x800a, 0x3a60, 0x22f8, 0x8008, 0x944a }, 16, 0x000a3d00, 1},
++	{{0x2c10, 0x6c90, 0x3640, 0xa000, 0x5d5a, 0x5059, 0x3a48, 0xa0c0, 0x6000, 0x6081, 0x5d5a, 0x5059, 0x3a00, 0xa6c3, 0x6000, 0x6081 }, 16, 0x000a3d20, 1},
++	{{0x7651, 0x76d6, 0x3600, 0xa840, 0x3683, 0x8005, 0xd99b, 0x3600, 0xa840, 0x3883, 0x8005, 0x3600, 0xa840, 0x38a3, 0x8004, 0x3600 }, 16, 0x000a3d40, 1},
++	{{0xb008, 0xd99b, 0xda1c, 0x3a00, 0xa841, 0x3883, 0x8005, 0x7650, 0x7551, 0x3c00, 0xa840, 0x3684, 0x8005, 0x90c0, 0x3645, 0x8003 }, 16, 0x000a3d60, 1},
++	{{0x94c0, 0xda1c, 0xda9d, 0x3c00, 0xa840, 0x3884, 0x8005, 0x90c0, 0x3845, 0x8003, 0x3c00, 0xa840, 0x30a4, 0x8004, 0x90c0, 0x3065 }, 16, 0x000a3d80, 1},
++	{{0x8002, 0x3a00, 0xa200, 0xda1c, 0xda9d, 0xdb1d, 0xdb9b, 0x3c00, 0xa800, 0x30c4, 0x8004, 0x90c0, 0x30e5, 0x8002, 0x6d55, 0x3400 }, 16, 0x000a3da0, 1},
++	{{0xa804, 0x6fcb, 0x3600, 0xa808, 0x745f, 0x67e5, 0x94c0, 0x9621, 0x9721, 0x94c0, 0x9633, 0x9733, 0x94c0, 0x9531, 0x9c23, 0x90c0 }, 16, 0x000a3dc0, 1},
++	{{0x90c0, 0x9731, 0x9f70, 0x3400, 0xa800, 0x7457, 0x9730, 0x94c0, 0x9c22, 0x9530, 0x5c58, 0x1a98, 0x6d54, 0x2d5c, 0x1998, 0xece8 }, 16, 0x000a3de0, 1},
++	{{0x3800, 0xa100, 0x7a61, 0xe9e8, 0xcc52, 0x1005, 0xa004, 0x3703, 0x2080, 0x8000, 0x9c44, 0x4191, 0x2c10, 0x2c90, 0x135a, 0x5299 }, 16, 0x000a3e00, 1},
++	{{0x98c8, 0x6c61, 0x609d, 0x535a, 0x5299, 0x2c61, 0x609d, 0x1489, 0xd818, 0x2c51, 0x4994, 0xd415, 0x94c0, 0x9531, 0x9c23, 0x90c0 }, 16, 0x000a3e20, 1},
++	{{0x90c0, 0x94c0, 0x9731, 0x7458, 0x9f70, 0xd818, 0x90c0, 0x90c0, 0x3a00, 0xa004, 0x7450, 0x0226, 0x28a0, 0x8009, 0x98c0, 0x3412 }, 16, 0x000a3e40, 1},
++	{{0x8208, 0x9620, 0x9720, 0x2618, 0x8108, 0x94c0, 0x9e20, 0x9f20, 0x3121, 0x2ad6, 0x8009, 0x0526, 0x28a0, 0x8009, 0x66e9, 0x2518 }, 16, 0x000a3e60, 1},
++	{{0x80d8, 0x98c0, 0x0f06, 0x357c, 0x8008, 0xc68f, 0x90c0, 0x2f0c, 0x8008, 0x5294, 0x351a, 0x8f00, 0x98c0, 0xdd28, 0x0424, 0x28a2 }, 16, 0x000a3e80, 1},
++	{{0x8009, 0x76fa, 0x6c1a, 0x6c7d, 0x9f7d, 0x377c, 0x0926, 0x28b8, 0x8009, 0x2769, 0x0a06, 0x357c, 0x8008, 0x8095, 0x96c0, 0x7b61 }, 16, 0x000a3ea0, 1},
++	{{0x9cb9, 0xea42, 0x94c0, 0x4c12, 0x9b46, 0x0826, 0x28b8, 0x8009, 0x0726, 0x28a0, 0x8009, 0x98c0, 0x7be1, 0xe841, 0x2b03, 0x8020 }, 16, 0x000a3ec0, 1},
++	{{0x98c0, 0xc84c, 0x0722, 0x28a0, 0x8009, 0x30fc, 0x0822, 0x28b8, 0x8009, 0x2103, 0x804a, 0x96c3, 0x3f20, 0x28ce, 0x8009, 0x96c3 }, 16, 0x000a3ee0, 1},
++	{{0x0f22, 0x28b8, 0x8009, 0x0c26, 0x28b8, 0x8009, 0x0806, 0x357c, 0x8008, 0x9fbc, 0xe842, 0x4f10, 0x0d26, 0x28b8, 0x8009, 0x0626 }, 16, 0x000a3f00, 1},
++	{{0x28a0, 0x8009, 0x3b61, 0xed41, 0x98d0, 0xcd4d, 0x0d22, 0x28b8, 0x8009, 0x30fd, 0x0622, 0x28a0, 0x8009, 0x90c0, 0x90c0, 0x96c3 }, 16, 0x000a3f20, 1},
++	{{0x3f20, 0x28ce, 0x8009, 0x96c3, 0x0f22, 0x28b8, 0x8009, 0x9f7c, 0x3124, 0x3f58, 0x800a, 0x90c0, 0x0326, 0x28a0, 0x8009, 0x3413 }, 16, 0x000a3f40, 1},
++	{{0x8208, 0x2dff, 0x9f15, 0x3400, 0xa800, 0x7450, 0x6460, 0xc569, 0x9f7d, 0x0426, 0x28a0, 0x8009, 0x2669, 0x0906, 0x357c, 0x8008 }, 16, 0x000a3f60, 1},
++	{{0x8419, 0xe948, 0x5691, 0x3d1d, 0x8020, 0x66e9, 0x90c0, 0x94c7, 0x844e, 0xe966, 0x92c3, 0x4011, 0x0626, 0x28a0, 0x8009, 0x3b41 }, 16, 0x000a3f80, 1},
++	{{0x3b20, 0x2ad6, 0x8009, 0x0622, 0x28a0, 0x8009, 0x0926, 0x28b4, 0x8009, 0x90c0, 0x9099, 0x0e26, 0x28b4, 0x8009, 0x90c0, 0xee41 }, 16, 0x000a3fa0, 1},
++	{{0x98c0, 0xeb8e, 0x0e22, 0x28b4, 0x8009, 0x90c0, 0x96c3, 0x3521, 0x28ce, 0x8009, 0x96c3, 0x0522, 0x28b4, 0x8009, 0xc561, 0x90c0 }, 16, 0x000a3fc0, 1},
++	{{0x9f7c, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x98c0, 0x77d0, 0x6f10, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000a3fe0, 1},
++	{{0x98c0, 0xefe9, 0x3224, 0x3e50, 0x800a, 0x96c0, 0xe750, 0x2000, 0x8082, 0x3224, 0x3e50, 0x800a, 0x107c, 0x9fd7, 0x3c00, 0xa002 }, 16, 0x000a4000, 1},
++	{{0x147c, 0x9fd7, 0x90c0, 0x3ece, 0x8208, 0x3800, 0xb000, 0x6669, 0x746e, 0xf441, 0x2718, 0x8228, 0x3324, 0x3e50, 0x800a, 0x3600 }, 16, 0x000a4020, 1},
++	{{0xa004, 0x3f1d, 0x80ff, 0x3224, 0x3e50, 0x800a, 0x3400, 0xa800, 0x746d, 0x9ac0, 0x67ea, 0xe9ef, 0x3ec8, 0x3800, 0xbfff, 0x2718 }, 16, 0x000a4040, 1},
++	{{0x81dc, 0x3a40, 0xa000, 0x3ac8, 0x3c10, 0xbfff, 0xf642, 0x3420, 0xa000, 0xf543, 0x3f00, 0x200e, 0x8008, 0x3800, 0x200c, 0x8008 }, 16, 0x000a4060, 1},
++	{{0xefa9, 0x2518, 0x8166, 0x98c0, 0xe8a9, 0x3d00, 0x200a, 0x8008, 0x2518, 0x8158, 0x98c0, 0xeda9, 0x3c00, 0x2008, 0x8008, 0x2518 }, 16, 0x000a4080, 1},
++	{{0x814a, 0xeca9, 0x2518, 0x8144, 0x3c00, 0x2004, 0x8008, 0x3800, 0x201a, 0x8008, 0xeca9, 0x2518, 0x8132, 0x98c0, 0xe8a9, 0x3c00 }, 16, 0x000a40a0, 1},
++	{{0x2018, 0x8008, 0x2518, 0x8116, 0x98c0, 0xeca9, 0x38e8, 0x2418, 0xbfff, 0x2518, 0x80fc, 0x3c00, 0x2016, 0x8008, 0x3d00, 0x2014 }, 16, 0x000a40c0, 1},
++	{{0x8008, 0x98c0, 0xeca9, 0x3bc8, 0x3c14, 0xbfff, 0x80db, 0x98c0, 0xeda9, 0x3b00, 0x2012, 0x8008, 0x80bb, 0x98c0, 0xeba9, 0x3c00 }, 16, 0x000a40e0, 1},
++	{{0x2010, 0x8008, 0x80a7, 0x98c0, 0xeca9, 0x3f00, 0x2006, 0x8008, 0x808f, 0x98c0, 0xefa9, 0x3b00, 0x2002, 0x8008, 0x807b, 0x98c0 }, 16, 0x000a4100, 1},
++	{{0xeba9, 0x3d00, 0x2000, 0x8008, 0x8063, 0x98c0, 0xeda9, 0x3be8, 0x2400, 0xbfff, 0x84b5, 0x1193, 0x3820, 0x28c0, 0x8009, 0x96c0 }, 16, 0x000a4120, 1},
++	{{0x33eb, 0x9fff, 0xefe9, 0x98c0, 0xd1a0, 0x0122, 0x28c0, 0x8009, 0x842b, 0x33e4, 0x3a92, 0x8001, 0x98c0, 0x0b26, 0x28c0, 0x8009 }, 16, 0x000a4140, 1},
++	{{0xe9ef, 0x90c0, 0xebf1, 0x3be8, 0x2400, 0xbfff, 0x90c0, 0x92c2, 0x5293, 0x96c2, 0x0222, 0x28c0, 0x8009, 0x0426, 0x28c0, 0x8009 }, 16, 0x000a4160, 1},
++	{{0x3044, 0x21ea, 0x800a, 0x38ca, 0x8410, 0x3044, 0x21ea, 0x800a, 0x0227, 0x28c2, 0x8009, 0x1296, 0x3144, 0x21ea, 0x800a, 0x1192 }, 16, 0x000a4180, 1},
++	{{0x3044, 0x21ea, 0x800a, 0x32ca, 0x8410, 0x1292, 0x3144, 0x21ea, 0x800a, 0x3bc8, 0x3c14, 0xbfff, 0x90c0, 0x1393, 0x3044, 0x21ea }, 16, 0x000a41a0, 1},
++	{{0x800a, 0x36ca, 0x8410, 0x1293, 0x3144, 0x21ea, 0x800a, 0x1290, 0x3044, 0x21ea, 0x800a, 0x34ca, 0x8410, 0x38e8, 0x2418, 0xbfff }, 16, 0x000a41c0, 1},
++	{{0x3044, 0x21ea, 0x800a, 0x5290, 0x52d1, 0x377a, 0x757e, 0x96c0, 0x3ccc, 0x8208, 0xefe9, 0x35ec, 0x346c, 0x3224, 0x3e50, 0x800a }, 16, 0x000a41e0, 1},
++	{{0x3400, 0xa004, 0x6e3d, 0x3600, 0xb000, 0x6760, 0x76fc, 0x3d1c, 0x80ff, 0x346c, 0x366c, 0x3224, 0x3e50, 0x800a, 0x6f15, 0x9ac0 }, 16, 0x000a4200, 1},
++	{{0x7be1, 0xe9ef, 0x3ac8, 0x3c10, 0xbfff, 0x27ea, 0xe942, 0x2dff, 0x9e47, 0x3660, 0xa000, 0xf6c2, 0xf5c3, 0x3600, 0xa008, 0x777e }, 16, 0x000a4220, 1},
++	{{0x6761, 0x3c16, 0x8082, 0x747e, 0x3400, 0xa040, 0x6d22, 0x36fa, 0x3044, 0x2262, 0x800a, 0x3400, 0xa040, 0x6366, 0x36e1, 0x3f7e }, 16, 0x000a4240, 1},
++	{{0x8000, 0x36fe, 0xf4c1, 0x6f15, 0x77fe, 0x3ece, 0x8208, 0x3224, 0x3e50, 0x800a, 0x746e, 0x67e0, 0x3f1e, 0x80ff, 0x3224, 0x3e50 }, 16, 0x000a4260, 1},
++	{{0x800a, 0x746e, 0x2d90, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x0322, 0x28c4, 0x8009, 0x90c0, 0x90c0 }, 16, 0x000a4280, 1},
++	{{0x3224, 0x3e50, 0x800a, 0x3800, 0xa004, 0x77d0, 0x2000, 0x8092, 0x3224, 0x3e50, 0x800a, 0x3400, 0xa800, 0x7457, 0x30e1, 0x3f6e }, 16, 0x000a42a0, 1},
++	{{0x8000, 0x74f8, 0x3400, 0xa044, 0x6f27, 0x3600, 0xa800, 0x3cc9, 0x8208, 0x3224, 0x3e50, 0x800a, 0x7469, 0x3400, 0xa800, 0x757e }, 16, 0x000a42c0, 1},
++	{{0x351b, 0x80ff, 0x3224, 0x3e50, 0x800a, 0x746b, 0x94c0, 0x6d90, 0x9f70, 0x0322, 0x28c4, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a42e0, 1},
++	{{0x98c0, 0x6f10, 0x77d1, 0x9620, 0x9720, 0x96c0, 0x6c90, 0x9e20, 0x9f20, 0x94c0, 0xeee8, 0xe750, 0x32e4, 0x3a14, 0x8001, 0xe838 }, 16, 0x000a4300, 1},
++	{{0x9cc0, 0x6469, 0x6e90, 0xce4b, 0x0806, 0x3c00, 0x8008, 0x96c0, 0xcb43, 0x2518, 0x8aa2, 0x96c0, 0xe848, 0x057c, 0x9ff0, 0x1c90 }, 16, 0x000a4320, 1},
++	{{0x0e26, 0x28c4, 0x8009, 0x96c0, 0xc181, 0x27e8, 0x9ff0, 0x9c62, 0x94c0, 0xee1b, 0xefeb, 0x9ac0, 0x6469, 0xebef, 0x0425, 0x32a7 }, 16, 0x000a4340, 1},
++	{{0x8009, 0x98c7, 0x2718, 0x8aa0, 0x90c0, 0x6c10, 0x96c0, 0xd620, 0xcf44, 0xcc83, 0x2718, 0x82ba, 0x96c0, 0xef61, 0x2700, 0x80c8 }, 16, 0x000a4360, 1},
++	{{0x98c0, 0xef8c, 0x0722, 0x28a8, 0x8009, 0x96c0, 0xeffe, 0x2518, 0x827c, 0x98c0, 0x3820, 0x2890, 0x8009, 0xcc82, 0x98c0, 0x0b26 }, 16, 0x000a4380, 1},
++	{{0x28a4, 0x8009, 0xce82, 0x98c0, 0xef18, 0x3a20, 0x327d, 0x8009, 0x1997, 0xc884, 0x3f20, 0x327d, 0x8009, 0x96c0, 0x9961, 0x157c }, 16, 0x000a43a0, 1},
++	{{0x9ff0, 0x9ac0, 0x6f90, 0x0926, 0x28a4, 0x8009, 0xc282, 0x147c, 0x9ff0, 0x98c0, 0xef19, 0x3a20, 0x3280, 0x8009, 0x94c0, 0xe941 }, 16, 0x000a43c0, 1},
++	{{0x949f, 0x98c0, 0xe8a9, 0x0922, 0x28a4, 0x8009, 0x96c0, 0xeeea, 0x2718, 0x823a, 0x94c0, 0x90ba, 0xea62, 0x98c0, 0x0325, 0x327d }, 16, 0x000a43e0, 1},
++	{{0x8009, 0xee61, 0x96c0, 0x7dd8, 0x95ba, 0x94be, 0x9ac0, 0xdb15, 0x7e48, 0x0221, 0x32a7, 0x8009, 0x98c0, 0xdf1b, 0x0722, 0x28a4 }, 16, 0x000a4400, 1},
++	{{0x8009, 0xdf1c, 0x98c0, 0xdf18, 0x3044, 0x2626, 0x800a, 0x0622, 0x28bc, 0x8009, 0x98c0, 0x3920, 0x327d, 0x8009, 0xc684, 0x90c0 }, 16, 0x000a4420, 1},
++	{{0xe91b, 0x96c0, 0x6e90, 0xeb41, 0x9599, 0x98c0, 0xecab, 0x0b22, 0x28a4, 0x8009, 0x2718, 0x81d2, 0x3c20, 0x327e, 0x8009, 0x0425 }, 16, 0x000a4440, 1},
++	{{0x327d, 0x8009, 0x9ac0, 0x7e48, 0x92bc, 0x0522, 0x28a4, 0x8009, 0x98c0, 0xdd1c, 0x0621, 0x32a7, 0x8009, 0x36fa, 0x0220, 0x28c8 }, 16, 0x000a4460, 1},
++	{{0x8009, 0x9ac0, 0x3615, 0x8100, 0x7475, 0x2700, 0x80e3, 0x2718, 0x8198, 0x077c, 0x9fff, 0x3224, 0x3ff0, 0x800a, 0x0926, 0x28bc }, 16, 0x000a4480, 1},
++	{{0x8009, 0x9ac0, 0x6d10, 0x0705, 0x3c4a, 0x8008, 0xc6ff, 0x27e9, 0x0221, 0x32a7, 0x8009, 0x2418, 0x8170, 0x0622, 0x28a8, 0x8009 }, 16, 0x000a44a0, 1},
++	{{0x0427, 0x28c8, 0x8009, 0x98c0, 0xf442, 0x3461, 0x2055, 0x8008, 0x32e4, 0x37e6, 0x8001, 0xf441, 0x3144, 0x2626, 0x800a, 0x98c0 }, 16, 0x000a44c0, 1},
++	{{0x0c26, 0x28a4, 0x8009, 0xcd80, 0x157c, 0x9ff0, 0x98c0, 0xea1c, 0x0226, 0x28bc, 0x8009, 0x9cc0, 0x34cf, 0x8208, 0xec41, 0x3518 }, 16, 0x000a44e0, 1},
++	{{0x80ff, 0x959a, 0x9ac0, 0xd7c0, 0xeeac, 0x0c22, 0x28a4, 0x8009, 0x9ac0, 0x2718, 0x8116, 0x90c0, 0x34ce, 0x8210, 0x98c0, 0xd7c6 }, 16, 0x000a4500, 1},
++	{{0x34cd, 0x8218, 0xc942, 0x94c0, 0xc845, 0xcc47, 0x0627, 0x28c8, 0x8009, 0x9ac0, 0x3ccc, 0x8208, 0xec18, 0x3d1b, 0x80ff, 0x9ac0 }, 16, 0x000a4520, 1},
++	{{0x6661, 0xed3c, 0x3f20, 0x327e, 0x8009, 0x9ac0, 0x6fcc, 0xcd48, 0x0525, 0x327d, 0x8009, 0x96c0, 0x7678, 0x7ec8, 0x93bf, 0x2e37 }, 16, 0x000a4540, 1},
++	{{0xdd9d, 0x36fc, 0x347b, 0x0320, 0x28cc, 0x8009, 0x3c15, 0x8081, 0x37fd, 0x3401, 0x2000, 0x8008, 0x3067, 0x7476, 0x8017, 0x2600 }, 16, 0x000a4560, 1},
++	{{0x80e5, 0x3224, 0x3ff0, 0x800a, 0x067c, 0x9fff, 0x3144, 0x25f0, 0x800a, 0x327a, 0x3001, 0x3000, 0x8008, 0x8043, 0x3178, 0x75d6 }, 16, 0x000a4580, 1},
++	{{0x94c0, 0xd5c2, 0x803d, 0x9cc0, 0x2400, 0x80e4, 0x6e90, 0x71f8, 0x7476, 0xc942, 0x8413, 0x3224, 0x3ff0, 0x800a, 0x047c, 0x9fff }, 16, 0x000a45a0, 1},
++	{{0x3144, 0x25f0, 0x800a, 0x3224, 0x3ff0, 0x800a, 0x98c0, 0x7476, 0xc942, 0x057c, 0x9fff, 0x3144, 0x25f0, 0x800a, 0x98c0, 0x2500 }, 16, 0x000a45c0, 1},
++	{{0x80e2, 0x7476, 0xc942, 0x3224, 0x3ff0, 0x800a, 0x057c, 0x9fff, 0x2c10, 0xc7ff, 0x0021, 0x32a7, 0x8009, 0x3044, 0x2626, 0x800a }, 16, 0x000a45e0, 1},
++	{{0x0722, 0x28a8, 0x8009, 0x0005, 0x3c4a, 0x8008, 0x6469, 0x90c0, 0x98c3, 0x3041, 0x3fe6, 0x8008, 0xf442, 0x96c3, 0x32e4, 0x37e6 }, 16, 0x000a4600, 1},
++	{{0x8001, 0x92c3, 0xf041, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x98c0, 0x0025, 0x32a8, 0x8009, 0xcf85, 0x94c0, 0xd420, 0xc940, 0x9ac0 }, 16, 0x000a4620, 1},
++	{{0x157c, 0x9ff0, 0x90c0, 0x2718, 0x84ec, 0x96c0, 0xe961, 0x2400, 0x87d0, 0x98c0, 0xe98f, 0x0422, 0x28a8, 0x8009, 0x96c0, 0xe9fe }, 16, 0x000a4640, 1},
++	{{0x2518, 0x84a6, 0x9cc0, 0x6d10, 0x6c90, 0x3c20, 0x2878, 0x8009, 0xca82, 0x98c0, 0x0e26, 0x28a4, 0x8009, 0xc882, 0x98c0, 0xe91c }, 16, 0x000a4660, 1},
++	{{0x0d26, 0x28a4, 0x8009, 0x1c91, 0x0926, 0x28a4, 0x8009, 0x0627, 0x28c8, 0x8009, 0x96c0, 0x9c61, 0x147c, 0x9ff0, 0x9ac0, 0x6d10 }, 16, 0x000a4680, 1},
++	{{0x3b20, 0x327d, 0x8009, 0xcc84, 0xc082, 0xeb1e, 0x94c0, 0xee41, 0x949b, 0x98c0, 0xecae, 0x0e22, 0x28a4, 0x8009, 0x2718, 0x8466 }, 16, 0x000a46a0, 1},
++	{{0x3b20, 0x3280, 0x8009, 0x0525, 0x327d, 0x8009, 0x96c0, 0x7ed8, 0xefeb, 0x97bb, 0x94c0, 0xeb62, 0xef61, 0x94c0, 0x94bb, 0x96bf }, 16, 0x000a46c0, 1},
++	{{0x9ac0, 0xd994, 0x7f48, 0x0021, 0x32a8, 0x8009, 0x98c0, 0xdd9d, 0x0222, 0x28a4, 0x8009, 0xdd9e, 0x98c0, 0xdd9f, 0x3044, 0x2b22 }, 16, 0x000a46e0, 1},
++	{{0x800a, 0x0322, 0x28bc, 0x8009, 0x98c0, 0x3e20, 0x327d, 0x8009, 0xc384, 0x107c, 0x9ff0, 0x98c0, 0xee19, 0x0220, 0x28ca, 0x8009 }, 16, 0x000a4700, 1},
++	{{0x96c0, 0x6c10, 0xe941, 0x909e, 0x98c0, 0xeaa9, 0x0922, 0x28a4, 0x8009, 0x2718, 0x83f0, 0x3f20, 0x327e, 0x8009, 0x0625, 0x327d }, 16, 0x000a4720, 1},
++	{{0x8009, 0x9ac0, 0x7f48, 0x95bf, 0x0321, 0x32a8, 0x8009, 0x98c0, 0xde9e, 0x0022, 0x28a4, 0x8009, 0x3044, 0x2b22, 0x800a, 0x0520 }, 16, 0x000a4740, 1},
++	{{0x28c8, 0x8009, 0x9ac0, 0x6f10, 0x3e20, 0x327d, 0x8009, 0xc982, 0x177c, 0x9ff0, 0x98c0, 0xee1d, 0x3a20, 0x327e, 0x8009, 0x94c0 }, 16, 0x000a4760, 1},
++	{{0xed41, 0x979e, 0x98c0, 0xe9ad, 0x0d22, 0x28a4, 0x8009, 0x96c0, 0x92ba, 0x2718, 0x8394, 0x0e27, 0x28ca, 0x8009, 0x0525, 0x327d }, 16, 0x000a4780, 1},
++	{{0x8009, 0x9ac0, 0x7ec8, 0x0426, 0x28bc, 0x8009, 0xeefc, 0x9ac0, 0xdd1d, 0x3001, 0x2000, 0x8008, 0xee1b, 0x3278, 0x0622, 0x28a4 }, 16, 0x000a47a0, 1},
++	{{0x8009, 0x844b, 0x3501, 0x3000, 0x8008, 0x327d, 0x0727, 0x28c8, 0x8009, 0x803b, 0x3617, 0x8100, 0x8035, 0x2f90, 0x4216, 0x0327 }, 16, 0x000a47c0, 1},
++	{{0x28ca, 0x8009, 0x39c1, 0x0527, 0x28c8, 0x8009, 0x367b, 0x0320, 0x28ca, 0x8009, 0x72fc, 0x2518, 0x832c, 0x0f21, 0x32a8, 0x8009 }, 16, 0x000a47e0, 1},
++	{{0x3044, 0x2b22, 0x800a, 0x0722, 0x28a4, 0x8009, 0x98c0, 0xc286, 0x3044, 0x2b22, 0x800a, 0x0221, 0x32a8, 0x8009, 0x9ac0, 0x2000 }, 16, 0x000a4800, 1},
++	{{0x80e3, 0x90c0, 0x3616, 0x8100, 0x840f, 0x3344, 0x22a0, 0x800a, 0x3144, 0x2840, 0x800a, 0x3244, 0x22a0, 0x800a, 0x2000, 0x80e2 }, 16, 0x000a4820, 1},
++	{{0x2f90, 0xc0ff, 0x0721, 0x32a8, 0x8009, 0x3044, 0x2b22, 0x800a, 0x0022, 0x28a8, 0x8009, 0x98c0, 0x3a20, 0x327d, 0x8009, 0xeeeb }, 16, 0x000a4840, 1},
++	{{0x0d26, 0x28a4, 0x8009, 0x147c, 0x9ff0, 0x98c0, 0xea1d, 0x0527, 0x28ca, 0x8009, 0x96c0, 0x7ec1, 0xed41, 0x949a, 0x98c0, 0xe8ad }, 16, 0x000a4860, 1},
++	{{0x0d22, 0x28a4, 0x8009, 0x2718, 0x829c, 0x26ea, 0x3a20, 0x327e, 0x8009, 0x0325, 0x327d, 0x8009, 0x9ac0, 0x7dc8, 0x90ba, 0x0d26 }, 16, 0x000a4880, 1},
++	{{0x28bc, 0x8009, 0x94c0, 0xdc1b, 0x841a, 0x0020, 0x28cc, 0x8009, 0x9f45, 0x90c0, 0x90c0, 0x94d0, 0x76f9, 0x93a3, 0x6c8d, 0x9ac0 }, 16, 0x000a48a0, 1},
++	{{0x7778, 0x0426, 0x28bc, 0x8009, 0xcc41, 0x9ac0, 0x391d, 0x80ff, 0x90c0, 0x38cb, 0x8208, 0x9cc0, 0x38cd, 0x8210, 0xd5c5, 0x38c8 }, 16, 0x000a48c0, 1},
++	{{0x8218, 0xecf8, 0x9ac0, 0xd5c5, 0xcf40, 0x0027, 0x28c8, 0x8009, 0x9ac0, 0x30cd, 0x8208, 0xcb43, 0x311a, 0x80ff, 0x66e1, 0x2d49 }, 16, 0x000a48e0, 1},
++	{{0xeb1f, 0xec3b, 0xcc4f, 0x76ff, 0x6d09, 0x757a, 0x3c12, 0x8091, 0x77fa, 0x3367, 0x3701, 0x3000, 0x8008, 0x8013, 0x3244, 0x22a0 }, 16, 0x000a4900, 1},
++	{{0x800a, 0x2000, 0x80e5, 0x3144, 0x2aec, 0x800a, 0x36d0, 0x6f10, 0xd6c4, 0x72ff, 0x8413, 0x3244, 0x22a0, 0x800a, 0x2000, 0x80e4 }, 16, 0x000a4920, 1},
++	{{0x3144, 0x2aec, 0x800a, 0x2469, 0x0620, 0x28ca, 0x8009, 0x2518, 0x8196, 0x3cc8, 0x3804, 0xbfff, 0x3fc8, 0x3c10, 0xbfff, 0x39c8 }, 16, 0x000a4940, 1},
++	{{0x3c12, 0xbfff, 0x38c8, 0x3c14, 0xbfff, 0x3ac8, 0x3c16, 0xbfff, 0x3be8, 0x2418, 0xbfff, 0x98c0, 0x30ea, 0x241a, 0xbfff, 0x90c0 }, 16, 0x000a4960, 1},
++	{{0x0126, 0x28bc, 0x8009, 0x3701, 0x2000, 0x8008, 0x33f9, 0x3501, 0x201a, 0x8008, 0x2518, 0x8128, 0x9ac0, 0x70fd, 0xc551, 0x3402 }, 16, 0x000a4980, 1},
++	{{0x200e, 0x8008, 0x96c0, 0x50d6, 0x2518, 0x8118, 0x34a0, 0xa000, 0xecad, 0x2518, 0x80fa, 0x3402, 0x200c, 0x8008, 0x3302, 0x200a }, 16, 0x000a49a0, 1},
++	{{0x8008, 0x34a0, 0xa000, 0xecad, 0x2518, 0x80e4, 0x34a0, 0xa000, 0xebad, 0x2518, 0x80da, 0x3302, 0x2008, 0x8008, 0x3602, 0x2004 }, 16, 0x000a49c0, 1},
++	{{0x8008, 0x34a0, 0xa000, 0xebad, 0x80c5, 0x34a0, 0xa000, 0xeead, 0x80bd, 0x98c0, 0x3602, 0x2002, 0x8008, 0xc157, 0x90c0, 0x34a0 }, 16, 0x000a49e0, 1},
++	{{0xa000, 0xeead, 0x80a9, 0x36a0, 0xa000, 0xe9ad, 0xc355, 0x809f, 0x3aa0, 0xa000, 0xebad, 0x3102, 0x2018, 0x8008, 0x8085, 0x34a0 }, 16, 0x000a4a00, 1},
++	{{0xa000, 0xe9ad, 0x8075, 0x3102, 0x2016, 0x8008, 0x3302, 0x2014, 0x8008, 0x34a0, 0xa000, 0xe9ad, 0x8059, 0x3aa0, 0xa000, 0xebad }, 16, 0x000a4a20, 1},
++	{{0x3602, 0x2012, 0x8008, 0x8043, 0x3aa0, 0xa000, 0xeead, 0x3302, 0x2010, 0x8008, 0x802d, 0x3aa0, 0xa000, 0xebad, 0x3602, 0x2006 }, 16, 0x000a4a40, 1},
++	{{0x8008, 0x8017, 0x38a0, 0xa000, 0x31fc, 0x9fff, 0xeead, 0x843f, 0x0494, 0x3144, 0x2ac0, 0x800a, 0x0017, 0x3144, 0x2ac0, 0x800a }, 16, 0x000a4a60, 1},
++	{{0x0011, 0x3144, 0x2ac0, 0x800a, 0x0010, 0x3144, 0x2ac0, 0x800a, 0x0012, 0x3144, 0x2ac0, 0x800a, 0x0013, 0x3144, 0x2ac0, 0x800a }, 16, 0x000a4a80, 1},
++	{{0x3a80, 0xa000, 0x4010, 0x3144, 0x2ac0, 0x800a, 0xd7c1, 0xc657, 0x3044, 0x2ac0, 0x800a, 0x3480, 0xa000, 0x4016, 0x51d6, 0x4115 }, 16, 0x000a4aa0, 1},
++	{{0x98c0, 0x0427, 0x28ca, 0x8009, 0xee42, 0x9ac0, 0x7a41, 0x0227, 0x28c8, 0x8009, 0xed42, 0x36fc, 0x0420, 0x28ca, 0x8009, 0x717d }, 16, 0x000a4ac0, 1},
++	{{0x2dff, 0x9ea1, 0x3244, 0x22a0, 0x800a, 0x6c10, 0x2d10, 0xc4ff, 0x0221, 0x32a8, 0x8009, 0x3044, 0x2b22, 0x800a, 0x0422, 0x28a8 }, 16, 0x000a4ae0, 1},
++	{{0x8009, 0x0405, 0x3c4a, 0x8008, 0x6669, 0x90c0, 0x98c3, 0xf042, 0x3041, 0x3ff8, 0x8008, 0x96c3, 0x32e4, 0x37e6, 0x8001, 0x92c3 }, 16, 0x000a4b00, 1},
++	{{0xf041, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x98c0, 0x3415, 0x8081, 0x6d90, 0xc281, 0x94c0, 0x6c90, 0x844d, 0x98c0, 0xc684, 0x3820 }, 16, 0x000a4b20, 1},
++	{{0x327d, 0x8009, 0x98c0, 0xf641, 0x0221, 0x32a7, 0x8009, 0x0322, 0x28a4, 0x8009, 0x0320, 0x28c8, 0x8009, 0x0301, 0x3c4a, 0x8008 }, 16, 0x000a4b40, 1},
++	{{0x32e4, 0x3c8a, 0x8001, 0x0322, 0x28bc, 0x8009, 0x96c0, 0x6c10, 0x2200, 0x80c8, 0x3044, 0x2e02, 0x800a, 0x0222, 0x28a8, 0x8009 }, 16, 0x000a4b60, 1},
++	{{0x96c0, 0x3415, 0x8091, 0xc381, 0x94c6, 0x844f, 0x6f10, 0x9ac0, 0x6c90, 0xc784, 0x3820, 0x327d, 0x8009, 0x98c0, 0xf741, 0x0321 }, 16, 0x000a4b80, 1},
++	{{0x32a8, 0x8009, 0x0622, 0x28a4, 0x8009, 0x0620, 0x28c8, 0x8009, 0x0601, 0x3c4a, 0x8008, 0x32e4, 0x3c8a, 0x8001, 0x0622, 0x28bc }, 16, 0x000a4ba0, 1},
++	{{0x8009, 0x96c0, 0x6c10, 0x2300, 0x80c8, 0x3044, 0x2e02, 0x800a, 0x0322, 0x28a8, 0x8009, 0x3415, 0x8083, 0x8415, 0x3224, 0x3e50 }, 16, 0x000a4bc0, 1},
++	{{0x800a, 0x2000, 0x8084, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x96c0, 0x3415, 0x8085, 0x6c90, 0x841b, 0x2000, 0x8086, 0x3224, 0x3e50 }, 16, 0x000a4be0, 1},
++	{{0x800a, 0x0101, 0x3c4a, 0x8008, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x96c0, 0x3415, 0x8087, 0xc281, 0x841b, 0x2000, 0x8088, 0x3224 }, 16, 0x000a4c00, 1},
++	{{0x3e50, 0x800a, 0x0201, 0x3c4a, 0x8008, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x6669, 0x2718, 0x81cc, 0x6469, 0x2718, 0x81c6, 0xd2aa }, 16, 0x000a4c20, 1},
++	{{0x2518, 0x812a, 0x94c0, 0xd2ad, 0xc28a, 0x2518, 0x811c, 0xd2a5, 0x2518, 0x8100, 0x96c0, 0x3415, 0x803b, 0xc481, 0x80c5, 0x3415 }, 16, 0x000a4c40, 1},
++	{{0x807f, 0x8077, 0xd2a8, 0x8073, 0xd2bb, 0x90c0, 0x96c2, 0x3341, 0x3dc0, 0x8008, 0x2418, 0x812c, 0x96c2, 0x0322, 0x28b0, 0x8009 }, 16, 0x000a4c60, 1},
++	{{0x66e9, 0x2518, 0x811e, 0x3615, 0x807f, 0x2518, 0x8116, 0x0225, 0x32a9, 0x8009, 0x96c0, 0x6569, 0x27e8, 0x9ff0, 0x90c0, 0x92c2 }, 16, 0x000a4c80, 1},
++	{{0x959e, 0x96c2, 0x0126, 0x28c4, 0x8009, 0x98c6, 0x0525, 0x32ac, 0x8009, 0x78c1, 0x9ac6, 0x66e9, 0x0122, 0x28c4, 0x8009, 0xc181 }, 16, 0x000a4ca0, 1},
++	{{0x80e1, 0x0906, 0x3c00, 0x8008, 0x90c0, 0xe944, 0x5f91, 0x90c0, 0x9f63, 0x3144, 0x2da0, 0x800a, 0x0526, 0x28c4, 0x8009, 0x26ea }, 16, 0x000a4cc0, 1},
++	{{0x0225, 0x32ac, 0x8009, 0x84bb, 0x6569, 0x90c0, 0x98c3, 0x0f06, 0x3c00, 0x8008, 0xc183, 0x96c3, 0x3860, 0x2088, 0x8008, 0x92c3 }, 16, 0x000a4ce0, 1},
++	{{0xef44, 0x92c3, 0x5b97, 0x90c0, 0x92c3, 0x9b63, 0x0426, 0x28c4, 0x8009, 0x3a61, 0x3044, 0x2da0, 0x800a, 0x0422, 0x28c4, 0x8009 }, 16, 0x000a4d00, 1},
++	{{0x0125, 0x32ac, 0x8009, 0x9ac0, 0x64e9, 0x0421, 0x32a9, 0x8009, 0xc181, 0x96c0, 0x806f, 0x27e8, 0x9ff0, 0x0f06, 0x3c00, 0x8008 }, 16, 0x000a4d20, 1},
++	{{0x90c0, 0xef44, 0x5e97, 0x90c0, 0x9e63, 0x3144, 0x2da0, 0x800a, 0x959e, 0x0426, 0x28c4, 0x8009, 0x3a41, 0x3044, 0x2da0, 0x800a }, 16, 0x000a4d40, 1},
++	{{0x0422, 0x28c4, 0x8009, 0x027c, 0x9ff0, 0x6d10, 0x9286, 0x0325, 0x32ac, 0x8009, 0x65e9, 0x90c0, 0x98c3, 0x0c06, 0x3c00, 0x8008 }, 16, 0x000a4d60, 1},
++	{{0xc181, 0x94c3, 0x27e8, 0x9ff0, 0x92c3, 0xec44, 0x92c3, 0x5f94, 0x90c0, 0x92c3, 0x9f63, 0x6d10, 0x929e, 0x0221, 0x32a9, 0x8009 }, 16, 0x000a4d80, 1},
++	{{0x3be1, 0x0026, 0x28c4, 0x8009, 0x33f0, 0x3860, 0x201b, 0x8008, 0x800f, 0x33e4, 0x37da, 0x8001, 0xc58a, 0x057c, 0x9ff0, 0x177c }, 16, 0x000a4da0, 1},
++	{{0x9ff0, 0xd3aa, 0x843d, 0x98c0, 0xc681, 0x3144, 0x2e00, 0x800a, 0x0726, 0x28a8, 0x8009, 0x67ea, 0x8429, 0x67ed, 0x98c6, 0x0722 }, 16, 0x000a4dc0, 1},
++	{{0x28a8, 0x8009, 0x6c90, 0x98c2, 0xc2ff, 0x0121, 0x32a8, 0x8009, 0x96c2, 0x0121, 0x32a7, 0x8009, 0x96c2, 0x0222, 0x28a8, 0x8009 }, 16, 0x000a4de0, 1},
++	{{0x7456, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a4e00, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x98c0, 0x0626, 0x28a0, 0x8009, 0x9f20, 0x2769, 0xe750, 0x2518, 0x80de, 0x98c0, 0x0a06, 0x357c, 0x8008 }, 16, 0x000a4e20, 1},
++	{{0xc68f, 0x90c0, 0x2a0d, 0x8008, 0x5295, 0x351a, 0x8f00, 0x98c0, 0xdd28, 0x0424, 0x28a2, 0x8009, 0x74fa, 0x6c06, 0x6c7d, 0x9f7d }, 16, 0x000a4e40, 1},
++	{{0x34fc, 0x0d26, 0x28b8, 0x8009, 0x24e9, 0x38e1, 0x0c06, 0x357c, 0x8008, 0x8099, 0x94c0, 0x97bd, 0xec42, 0x94c0, 0x4714, 0x9b41 }, 16, 0x000a4e60, 1},
++	{{0x0a26, 0x28b8, 0x8009, 0x0726, 0x28a0, 0x8009, 0x98c0, 0x7be1, 0xea41, 0x2b03, 0x8026, 0x98c0, 0x3321, 0x2ad6, 0x8009, 0xca4d }, 16, 0x000a4e80, 1},
++	{{0x31fd, 0x0722, 0x28a0, 0x8009, 0x0a22, 0x28b8, 0x8009, 0x2103, 0x804a, 0x96c3, 0x3c20, 0x28ce, 0x8009, 0x96c3, 0x0c22, 0x28b8 }, 16, 0x000a4ea0, 1},
++	{{0x8009, 0x0a26, 0x28b8, 0x8009, 0x0806, 0x357c, 0x8008, 0x95ba, 0xe842, 0x4510, 0x0f26, 0x28b8, 0x8009, 0x0126, 0x28a0, 0x8009 }, 16, 0x000a4ec0, 1},
++	{{0x38e1, 0xef41, 0x98d0, 0xcf4e, 0x0f22, 0x28b8, 0x8009, 0x31fe, 0x0122, 0x28a0, 0x8009, 0x90c0, 0x90c0, 0x96c3, 0x3c20, 0x28ce }, 16, 0x000a4ee0, 1},
++	{{0x8009, 0x96c3, 0x0c22, 0x28b8, 0x8009, 0x9f7c, 0x3144, 0x2f14, 0x800a, 0x90c0, 0x33e4, 0x3a20, 0x8001, 0x0225, 0x32ab, 0x8009 }, 16, 0x000a4f00, 1},
++	{{0x2569, 0x3621, 0x328d, 0x8009, 0x841d, 0x98c0, 0x3061, 0x2083, 0x8008, 0xf642, 0x32e4, 0x37e6, 0x8001, 0xf041, 0xc781, 0x0721 }, 16, 0x000a4f20, 1},
++	{{0x32ab, 0x8009, 0x2100, 0x8200, 0x3244, 0x2300, 0x800a, 0x3820, 0x2ad6, 0x8009, 0x96c0, 0xd021, 0x27e9, 0x9ff0, 0x2718, 0x8128 }, 16, 0x000a4f40, 1},
++	{{0x98c0, 0xf941, 0x3920, 0x2568, 0x8009, 0x32e4, 0x3816, 0x8001, 0x3820, 0x2ad6, 0x8009, 0x96c0, 0x6c10, 0xf6c4, 0xc185, 0x9ac0 }, 16, 0x000a4f60, 1},
++	{{0x6769, 0xc481, 0x0926, 0x2568, 0x8009, 0x96c0, 0x8053, 0x27e8, 0x9ff4, 0x32e4, 0x3ca2, 0x8001, 0x96c0, 0xf441, 0x017c, 0x9ff4 }, 16, 0x000a4f80, 1},
++	{{0x2469, 0x3860, 0x2069, 0x8008, 0x8423, 0x33e4, 0x37da, 0x8001, 0x6d90, 0x0321, 0x32ac, 0x8009, 0x0321, 0x32ab, 0x8009, 0x3044 }, 16, 0x000a4fa0, 1},
++	{{0x3084, 0x800a, 0x0322, 0x28c4, 0x8009, 0x0926, 0x2568, 0x8009, 0x32e4, 0x3804, 0x8001, 0x0826, 0x28b0, 0x8009, 0x2468, 0x2f10 }, 16, 0x000a4fc0, 1},
++	{{0x3840, 0x3f54, 0x8008, 0x94c0, 0xf1c4, 0x8055, 0x33e4, 0x37da, 0x8001, 0x0426, 0x28c4, 0x8009, 0x6669, 0x90c0, 0x96c3, 0x0426 }, 16, 0x000a4fe0, 1},
++	{{0x2568, 0x8009, 0x98c3, 0x3261, 0x2072, 0x8008, 0xf442, 0x96c3, 0x32e4, 0x37e6, 0x8001, 0x92c3, 0xf241, 0x32e4, 0x37da, 0x8001 }, 16, 0x000a5000, 1},
++	{{0x3860, 0x208e, 0x8008, 0x6e90, 0x0521, 0x32ab, 0x8009, 0x3044, 0x3084, 0x800a, 0x0522, 0x28c4, 0x8009, 0x24e9, 0x0622, 0x28c4 }, 16, 0x000a5020, 1},
++	{{0x8009, 0x94c6, 0x8042, 0x6d10, 0x96c2, 0x0221, 0x32ab, 0x8009, 0x24e9, 0x3c44, 0x0f26, 0x28b0, 0x8009, 0x94c0, 0xca40, 0x8023 }, 16, 0x000a5040, 1},
++	{{0x90c0, 0xea1f, 0xea4c, 0x5392, 0x65e9, 0x90c0, 0x98c3, 0xc943, 0x3820, 0x2568, 0x8009, 0x90c0, 0x92c3, 0x9963, 0x6d90, 0x0321 }, 16, 0x000a5060, 1},
++	{{0x32ab, 0x8009, 0xe770, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x98c0, 0x9620, 0x3840, 0x3fd3, 0x8008, 0x32e4, 0x37da, 0x8001 }, 16, 0x000a5080, 1},
++	{{0xe758, 0x32e4, 0x37e0, 0x8001, 0x98c0, 0xc184, 0x3081, 0x34a3, 0x8000, 0x3d00, 0x2024, 0x8008, 0x3840, 0x3f98, 0x8008, 0x10d5 }, 16, 0x000a50a0, 1},
++	{{0x32e4, 0x37da, 0x8001, 0x7750, 0x9ac0, 0x7456, 0xc194, 0x32e4, 0x37e0, 0x8001, 0x6460, 0x32e4, 0x37da, 0x8001, 0x3860, 0x208b }, 16, 0x000a50c0, 1},
++	{{0x8008, 0x3b40, 0x30d8, 0x8008, 0x3041, 0x3e70, 0x8008, 0x159b, 0xf041, 0x109b, 0xf542, 0x149b, 0xf043, 0x1293, 0xf444, 0x32e4 }, 16, 0x000a50e0, 1},
++	{{0x37e6, 0x8001, 0xf245, 0xe778, 0x9621, 0x9f71, 0x90c0, 0x90c0, 0x96c0, 0xd4a1, 0xe748, 0xc481, 0x94c0, 0xf442, 0x842f, 0x96c0 }, 16, 0x000a5100, 1},
++	{{0xc181, 0x27ea, 0x9ff8, 0x32e4, 0x389a, 0x8001, 0xfa41, 0x34f0, 0x9fff, 0x8415, 0x32e4, 0x37da, 0x8001, 0x3840, 0x3f6c, 0x8008 }, 16, 0x000a5120, 1},
++	{{0x3144, 0x3192, 0x800a, 0x3204, 0x33b0, 0x800b, 0x10fc, 0x9ffa, 0x98c0, 0xd026, 0x0105, 0x3c4a, 0x8008, 0x8419, 0x24e9, 0x3840 }, 16, 0x000a5140, 1},
++	{{0x3fad, 0x8008, 0x802f, 0x33e4, 0x37da, 0x8001, 0x3144, 0x3192, 0x800a, 0x98c0, 0xd021, 0x0405, 0x3c4a, 0x8008, 0x8417, 0x6669 }, 16, 0x000a5160, 1},
++	{{0x90c0, 0x96c3, 0x32e4, 0x37da, 0x8001, 0x96c3, 0x3840, 0x3fc0, 0x8008, 0xe768, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5180, 1},
++	{{0x94c0, 0xc481, 0x9f70, 0x0421, 0x32ac, 0x8009, 0x90c0, 0x90c0, 0x94c0, 0x6c10, 0x9f70, 0x0021, 0x32ac, 0x8009, 0x90c0, 0x90c0 }, 16, 0x000a51a0, 1},
++	{{0x98c0, 0x3de8, 0x2400, 0xbfff, 0xe750, 0x3840, 0x3eea, 0x8008, 0x1395, 0x32e4, 0x37da, 0x8001, 0x0322, 0x28ac, 0x8009, 0x0126 }, 16, 0x000a51c0, 1},
++	{{0x28ac, 0x8009, 0x9ac0, 0x32ca, 0x8410, 0x90c0, 0x33f9, 0x9fff, 0x98c0, 0x3061, 0x205f, 0x8008, 0xf143, 0x32e4, 0x37e6, 0x8001 }, 16, 0x000a51e0, 1},
++	{{0x94c0, 0xf242, 0xf041, 0xe770, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0xd0a1, 0x7751, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000a5200, 1},
++	{{0x94c0, 0xeee8, 0xe750, 0x96c2, 0x32e4, 0x37da, 0x8001, 0x96c2, 0x3840, 0x3f37, 0x8008, 0x9ac0, 0xd721, 0xee44, 0x0826, 0x28b0 }, 16, 0x000a5220, 1},
++	{{0x8009, 0x94c0, 0x5996, 0x843f, 0x33e4, 0x3804, 0x8001, 0x2468, 0x3c44, 0x0826, 0x28b0, 0x8009, 0x94c0, 0xca40, 0x848b, 0x3461 }, 16, 0x000a5240, 1},
++	{{0x200a, 0x8008, 0x94c0, 0xea18, 0xf441, 0xea44, 0x529a, 0x1292, 0xf242, 0x32e4, 0x37e6, 0x8001, 0xf243, 0x3144, 0x32e2, 0x800a }, 16, 0x000a5260, 1},
++	{{0x32e4, 0x37da, 0x8001, 0x3860, 0x203d, 0x8008, 0x9ac0, 0x6f90, 0x0826, 0x28b0, 0x8009, 0xef3f, 0x90c0, 0x5690, 0x6769, 0x8045 }, 16, 0x000a5280, 1},
++	{{0xe81f, 0x5e90, 0x90c0, 0x90fe, 0x3410, 0x802e, 0x90c0, 0x98c3, 0xe844, 0x3261, 0x2079, 0x8008, 0x94c3, 0x5390, 0xf241, 0x96c3 }, 16, 0x000a52a0, 1},
++	{{0x32e4, 0x37e6, 0x8001, 0x92c3, 0xf342, 0x9ac0, 0x7bd0, 0x0826, 0x28b0, 0x8009, 0xef50, 0xcb47, 0x90c0, 0xeb18, 0x5293, 0x6569 }, 16, 0x000a52c0, 1},
++	{{0x85c1, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a52e0, 1},
++	{{0x96c0, 0xd0a1, 0x7751, 0x9620, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xeee8, 0xe750, 0x96c2, 0x32e4, 0x37da, 0x8001, 0x96c2, 0x3820 }, 16, 0x000a5300, 1},
++	{{0x3206, 0x8009, 0x9ac0, 0xd721, 0xee44, 0x3820, 0x2778, 0x8009, 0x94c0, 0x5996, 0x843f, 0x33e4, 0x3804, 0x8001, 0x2468, 0x3c44 }, 16, 0x000a5320, 1},
++	{{0x3f20, 0x2778, 0x8009, 0x94c0, 0xca40, 0x8487, 0x3161, 0x202c, 0x8008, 0x94c0, 0xea1f, 0xf141, 0xea44, 0x519a, 0x1192, 0xf142 }, 16, 0x000a5340, 1},
++	{{0x32e4, 0x37e6, 0x8001, 0xf143, 0x3144, 0x33cc, 0x800a, 0x32e4, 0x37da, 0x8001, 0x3860, 0x2049, 0x8008, 0x0426, 0x2778, 0x8009 }, 16, 0x000a5360, 1},
++	{{0x2669, 0x3c20, 0x2778, 0x8009, 0x8045, 0x3f20, 0x2778, 0x8009, 0x3e20, 0x277c, 0x8009, 0x5d97, 0x90c0, 0x92fd, 0x3412, 0x802e }, 16, 0x000a5380, 1},
++	{{0x90c0, 0x98c3, 0x5296, 0x3661, 0x207e, 0x8008, 0x94c3, 0xf641, 0xf242, 0x98c7, 0xcc4e, 0x33e4, 0x37e6, 0x8001, 0x94c0, 0xcc46 }, 16, 0x000a53a0, 1},
++	{{0xee50, 0xef50, 0xec50, 0x5694, 0x6769, 0x85cd, 0x32e4, 0x37da, 0x8001, 0x3840, 0x3f11, 0x8008, 0xe770, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a53c0, 1},
++	{{0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xe750 }, 16, 0x000a53e0, 1},
++	{{0x3621, 0x30f3, 0x8009, 0x32e4, 0x37e6, 0x8001, 0xf641, 0x0626, 0x3318, 0x8009, 0x98c0, 0x3421, 0x30d7, 0x8009, 0xf642, 0x32e4 }, 16, 0x000a5400, 1},
++	{{0x37e6, 0x8001, 0xf441, 0x0226, 0x330c, 0x8009, 0x98c0, 0x3621, 0x30bb, 0x8009, 0xf242, 0x32e4, 0x37e6, 0x8001, 0xf641, 0x0126 }, 16, 0x000a5420, 1},
++	{{0x3330, 0x8009, 0x98c0, 0x0626, 0x3338, 0x8009, 0xf143, 0x98c0, 0x3521, 0x2fbd, 0x8009, 0xf642, 0x32e4, 0x37e6, 0x8001, 0xf541 }, 16, 0x000a5440, 1},
++	{{0x0026, 0x3328, 0x8009, 0x32e4, 0x3c4e, 0x8001, 0x96c0, 0x6460, 0x2100, 0x83e8, 0x34d0, 0x0026, 0x3318, 0x8009, 0x32e4, 0x3c4e }, 16, 0x000a5460, 1},
++	{{0x8001, 0x6460, 0x32e4, 0x3c4e, 0x8001, 0x3750, 0xc18a, 0x94c0, 0xc78a, 0xca46, 0x9ac0, 0x3a00, 0x8007, 0xf042, 0x3607, 0x8007 }, 16, 0x000a5480, 1},
++	{{0x98c0, 0xda90, 0x3421, 0x2f4d, 0x8009, 0x94c0, 0xd7c5, 0xf441, 0xcf47, 0x90c0, 0x98c0, 0xea3f, 0x32e4, 0x37e6, 0x8001, 0xfa43 }, 16, 0x000a54a0, 1},
++	{{0x0026, 0x332c, 0x8009, 0x32e4, 0x3c4e, 0x8001, 0x96c0, 0x6460, 0x2100, 0x83e8, 0x34d0, 0x0026, 0x3324, 0x8009, 0x32e4, 0x3c4e }, 16, 0x000a54c0, 1},
++	{{0x8001, 0x6460, 0x98c0, 0x2000, 0x83e8, 0x7650, 0xc18a, 0x2c7d, 0x32a4, 0x3540, 0x800b, 0x7454, 0x98c0, 0x3e10, 0x800a, 0xf042 }, 16, 0x000a54e0, 1},
++	{{0xc844, 0x98c0, 0xcf40, 0x3721, 0x2f26, 0x8009, 0xf741, 0x98c0, 0xe83f, 0x32e4, 0x37e6, 0x8001, 0xf843, 0x0326, 0x3328, 0x8009 }, 16, 0x000a5500, 1},
++	{{0x36cd, 0x8782, 0x98c0, 0xf542, 0x3521, 0x31f1, 0x8009, 0x32e4, 0x37e6, 0x8001, 0xf541, 0x3421, 0x3230, 0x8009, 0x32e4, 0x37e6 }, 16, 0x000a5520, 1},
++	{{0x8001, 0xf441, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5540, 1},
++	{{0x98c0, 0xe748, 0x31a1, 0x33c6, 0x8009, 0x32e4, 0x37e6, 0x8001, 0xf141, 0xe768, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5560, 1},
++	{{0x98c0, 0x3021, 0x2778, 0x8009, 0x9f70, 0x0022, 0x28b0, 0x8009, 0x3004, 0x34a0, 0x800b, 0x6c10, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5580, 1},
++	{{0x3c80, 0xa105, 0x7456, 0x6e10, 0x74d7, 0xe9ef, 0xe8ee, 0x98c0, 0x3fe8, 0x3c00, 0xbfff, 0xce87, 0x98c0, 0x0dc6, 0x38d0, 0x8008 }, 16, 0x000a55a0, 1},
++	{{0xe748, 0x1697, 0x3a00, 0x2048, 0x8008, 0x9ac0, 0x2d0b, 0x8002, 0x90c0, 0x3d28, 0x9f00, 0x13d3, 0x17d2, 0xdc38, 0x9ac0, 0x371d }, 16, 0x000a55c0, 1},
++	{{0x8001, 0x646e, 0x371e, 0x8002, 0x9ac0, 0x3f5f, 0x8000, 0xcf40, 0x2b0a, 0x809e, 0x90c0, 0xef61, 0x94c0, 0xee8f, 0xff42, 0x90c0 }, 16, 0x000a55e0, 1},
++	{{0x92c2, 0xcf4a, 0x94c2, 0x0902, 0xa400, 0x98c6, 0x66e9, 0xf242, 0x25a0, 0x9fff, 0xf3c2, 0x98c7, 0x0903, 0xa200, 0x90c0, 0xc481 }, 16, 0x000a5600, 1},
++	{{0x94c3, 0x0913, 0xa010, 0x96c7, 0x6769, 0x0913, 0xa001, 0x92c3, 0x7a41, 0x96c3, 0x7e52, 0x0913, 0xa020, 0x96c7, 0x67e9, 0xdd9c }, 16, 0x000a5620, 1},
++	{{0x57d2, 0x98c0, 0x0943, 0xb800, 0xde87, 0x8025, 0x96c0, 0x4512, 0x24a0, 0x9fff, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0c, 0x80a2 }, 16, 0x000a5640, 1},
++	{{0x55d4, 0xde05, 0x4414, 0x3c40, 0xa000, 0x6f90, 0x0ac6, 0x38d0, 0x8008, 0xe768, 0x3420, 0xa000, 0xeee8, 0x3620, 0xa000, 0x2a0b }, 16, 0x000a5660, 1},
++	{{0x80a0, 0x56db, 0x9ac0, 0x3ccd, 0x804e, 0x52d3, 0x3cce, 0x804f, 0x9cc0, 0x34cc, 0x804f, 0x7f58, 0x34c9, 0x804e, 0x7ed9, 0x3e5a }, 16, 0x000a5680, 1},
++	{{0x3cdb, 0xdd9e, 0xdd9d, 0xdd9c, 0xdd99, 0x4398, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0a, 0x80a2, 0x56ca, 0x9ac0, 0x3cc9, 0x8082 }, 16, 0x000a56a0, 1},
++	{{0x54d2, 0x3d18, 0x8003, 0x9cc0, 0x3919, 0x8003, 0xda91, 0x38ca, 0x8082, 0x7c54, 0x9ac0, 0x7ccc, 0x7d48, 0xde98, 0x3cc8, 0x8084 }, 16, 0x000a56c0, 1},
++	{{0x9cc0, 0x3cc9, 0x8086, 0x7c46, 0x38cb, 0x8084, 0xde99, 0x9ac0, 0xde9a, 0x7cc4, 0x7dc2, 0x38ce, 0x8086, 0xde98, 0xde99, 0xde9b }, 16, 0x000a56e0, 1},
++	{{0xde9e, 0x4590, 0x98c0, 0x0ac6, 0x38d0, 0x8008, 0xe845, 0xefe8, 0x94c0, 0xea50, 0xef61, 0x94c0, 0x51d2, 0x979f, 0x331e, 0x80ff }, 16, 0x000a5700, 1},
++	{{0x9698, 0x98c0, 0x0ac6, 0x38d0, 0x8008, 0xe842, 0xebe8, 0x94c0, 0xea52, 0xeb61, 0x3800, 0xa800, 0x77d1, 0x56d2, 0x979b, 0x3800 }, 16, 0x000a5720, 1},
++	{{0xa200, 0x3d1c, 0x80ff, 0x7750, 0x9498, 0x98c0, 0x0bc6, 0x38d0, 0x8008, 0xe842, 0xeae8, 0x96c0, 0xea61, 0x2b0b, 0x8038, 0x51d3 }, 16, 0x000a5740, 1},
++	{{0x3319, 0x80ff, 0x9198, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xe842, 0x90c0, 0x290b, 0x8038, 0x50d3, 0x7c68, 0x909a, 0x0fc6, 0x38d0 }, 16, 0x000a5760, 1},
++	{{0x8008, 0x90c0, 0x3820, 0xa000, 0xefe9, 0x2f09, 0x803a, 0x51d1, 0x331b, 0x80ff, 0x9388, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0c }, 16, 0x000a5780, 1},
++	{{0x803a, 0x54d4, 0x94c0, 0x7e68, 0x9f70, 0x9498, 0x90c0, 0x90c0, 0x3ce8, 0x3c00, 0xbfff, 0x2460, 0x00e0, 0x306a, 0x8008, 0x34d0 }, 16, 0x000a57a0, 1},
++	{{0x5494, 0x3928, 0x9f00, 0x98c0, 0xdc38, 0x32e4, 0x3c4e, 0x8001, 0x3e10, 0x8018, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xca40, 0x90c0 }, 16, 0x000a57c0, 1},
++	{{0x96c0, 0xea61, 0x2909, 0x80b0, 0x13d1, 0xca48, 0x371a, 0x800f, 0x7d48, 0x94c0, 0xdc1a, 0x9f70, 0x6460, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a57e0, 1},
++	{{0x3e00, 0xa10c, 0x7456, 0x74d7, 0x0dc6, 0x38d0, 0x8008, 0xeaef, 0x3519, 0x27fd, 0xbfff, 0x3680, 0xa000, 0x2d08, 0x8064, 0x3680 }, 16, 0x000a5800, 1},
++	{{0xa100, 0x51d0, 0xe864, 0x3c00, 0xa100, 0xdb11, 0x52d0, 0x3419, 0x27ff, 0xbfff, 0x96c0, 0xdf1a, 0x3599, 0x8000, 0x24e9, 0xdf05 }, 16, 0x000a5820, 1},
++	{{0x0906, 0xa200, 0x94c3, 0x0906, 0xa002, 0x4698, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0a, 0x8062, 0x56d2, 0x4610, 0x98c0, 0x0fc6 }, 16, 0x000a5840, 1},
++	{{0x38d0, 0x8008, 0xe844, 0x90c0, 0x2f0f, 0x8068, 0x51d7, 0x4118, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0c, 0x806a, 0x53d4, 0x4318 }, 16, 0x000a5860, 1},
++	{{0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0b, 0x806c, 0x50d3, 0x4018, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0a, 0x806e, 0x55d2, 0x4518 }, 16, 0x000a5880, 1},
++	{{0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0a, 0x803c, 0x56d2, 0x4618, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b, 0x803e, 0x52d3, 0x4218 }, 16, 0x000a58a0, 1},
++	{{0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0a, 0x8040, 0x56d2, 0x4618, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0f, 0x8042, 0x56d7, 0x4618 }, 16, 0x000a58c0, 1},
++	{{0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed54, 0x53d5, 0x4318, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea56, 0x51d2, 0x4118, 0x0dc6, 0x38d0 }, 16, 0x000a58e0, 1},
++	{{0x8008, 0x90c0, 0xed58, 0x57d5, 0x4718, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea5a, 0x51d2, 0x4110, 0x0fc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000a5900, 1},
++	{{0x2f0b, 0x807c, 0x15d3, 0xeb64, 0x13d3, 0xdb95, 0x96c0, 0xdf9b, 0x379e, 0x8000, 0x3800, 0xa200, 0x6769, 0xdf84, 0x7750, 0x0907 }, 16, 0x000a5920, 1},
++	{{0xa200, 0x94c3, 0x0907, 0xa002, 0x4799, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x807a, 0x54d5, 0x4411, 0x98c0, 0x0dc6, 0x38d0 }, 16, 0x000a5940, 1},
++	{{0x8008, 0xe944, 0x90c0, 0x2d0c, 0x8080, 0x53d4, 0x4319, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b, 0x8082, 0x52d3, 0x4219, 0x0cc6 }, 16, 0x000a5960, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2c0b, 0x8084, 0x53d3, 0x4319, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0c, 0x8086, 0x51d4, 0x4119, 0x0ac6 }, 16, 0x000a5980, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2a0f, 0x8044, 0x3640, 0xa000, 0x52d7, 0xefea, 0x4219, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0a, 0x8046 }, 16, 0x000a59a0, 1},
++	{{0x50d2, 0x4019, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0b, 0x8048, 0x57d3, 0x4719, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0b, 0x804a }, 16, 0x000a59c0, 1},
++	{{0x54d3, 0x4419, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed5c, 0x57d5, 0x4719, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed5e, 0x52d5, 0x4219 }, 16, 0x000a59e0, 1},
++	{{0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0c, 0x8020, 0x57d4, 0x3600, 0xa800, 0x77d1, 0x4719, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b }, 16, 0x000a5a00, 1},
++	{{0x8022, 0x94c0, 0x54d3, 0x9f70, 0x4411, 0x90c0, 0x90c0, 0x90c0, 0x3be8, 0x3c0c, 0xbfff, 0x32f9, 0x3ccc, 0xbf59, 0x0293, 0x3ba8 }, 16, 0x000a5a20, 1},
++	{{0x3c00, 0xbfff, 0x98c0, 0x3201, 0x2020, 0x8020, 0x9f70, 0x4293, 0x39a8, 0x3c20, 0xbfff, 0x90c0, 0x5191, 0x0122, 0x333c, 0x8009 }, 16, 0x000a5a40, 1},
++	{{0x9f7d, 0x2c90, 0x04e6, 0x3064, 0x8008, 0x6669, 0x90c0, 0x96c3, 0x38c8, 0x3000, 0xbfff, 0x90c0, 0x92c3, 0x4490, 0x05e6, 0x305c }, 16, 0x000a5a60, 1},
++	{{0x8008, 0x66e9, 0x90c0, 0x96c3, 0x38c8, 0x3400, 0xbfff, 0x90c0, 0x92c3, 0x4590, 0x04e6, 0x35c8, 0x8008, 0x6669, 0x90c0, 0x96c3 }, 16, 0x000a5a80, 1},
++	{{0x3dc8, 0x2400, 0xbfff, 0x90c0, 0x92c3, 0x4495, 0x01e2, 0x305c, 0x8008, 0x01e2, 0x3064, 0x8008, 0x01e2, 0x35c8, 0x8008, 0x9f7c }, 16, 0x000a5aa0, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x9720, 0x0826, 0x3308, 0x8009, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000a5ac0, 1},
++	{{0x98c0, 0x3fa8, 0x3c20, 0xbfff, 0xe841, 0x98c0, 0x0325, 0x3369, 0x8009, 0xe748, 0x37e3, 0x1097, 0x0822, 0x3308, 0x8009, 0x27e9 }, 16, 0x000a5ae0, 1},
++	{{0x0022, 0x3344, 0x8009, 0x803f, 0x27ed, 0xc081, 0x8438, 0x0721, 0x3369, 0x8009, 0x33e4, 0x394e, 0x8001, 0x98c0, 0x3541, 0x3a50 }, 16, 0x000a5b00, 1},
++	{{0x800a, 0xc184, 0x32e4, 0x395a, 0x8001, 0x94c0, 0xf541, 0xc081, 0x98c0, 0xc081, 0x31e1, 0x2664, 0x8000, 0x3204, 0x3190, 0x800b }, 16, 0x000a5b20, 1},
++	{{0x007c, 0x9fff, 0x3304, 0x2f90, 0x800a, 0x33c4, 0x38e0, 0x800a, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0d, 0x8026, 0x15d5, 0xed62 }, 16, 0x000a5b40, 1},
++	{{0x26e9, 0x55d5, 0x8427, 0x26e9, 0x2c10, 0x3c80, 0x29a0, 0x8009, 0x841b, 0x2704, 0x8060, 0x3d80, 0x2b20, 0x8009, 0x90c0, 0x94c8 }, 16, 0x000a5b60, 1},
++	{{0x401d, 0x401c, 0x3144, 0x3b90, 0x800a, 0x33a4, 0x37e0, 0x800a, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a5b80, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9f7d, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0xe946, 0x5511, 0x3b1c, 0x8001, 0x6669 }, 16, 0x000a5ba0, 1},
++	{{0x8017, 0x33a4, 0x2930, 0x800a, 0x6469, 0x800d, 0x9f78, 0x9f7c, 0x3144, 0x3d7c, 0x800a, 0x9f7c, 0x98c0, 0x0526, 0x3358, 0x8009 }, 16, 0x000a5bc0, 1},
++	{{0xc281, 0x98c0, 0xd6c2, 0x3ba8, 0x3c24, 0xbfff, 0x0522, 0x3358, 0x8009, 0x3ea8, 0x3c20, 0xbfff, 0x5893, 0x5396, 0x5493, 0xcd44 }, 16, 0x000a5be0, 1},
++	{{0x90c0, 0xeda8, 0x85f5, 0x98c0, 0x0026, 0x3360, 0x8009, 0xc7a0, 0x9cc0, 0x6469, 0xd617, 0x0026, 0x3340, 0x8009, 0xc782, 0x98c0 }, 16, 0x000a5c00, 1},
++	{{0xd5c4, 0x3c20, 0x32fc, 0x8009, 0x96c2, 0x3ec8, 0x3c00, 0xbfff, 0x90c0, 0x92c2, 0x5896, 0x90c0, 0x92c2, 0xe842, 0x9cc6, 0x7c42 }, 16, 0x000a5c20, 1},
++	{{0x90c0, 0x707f, 0x0822, 0x3360, 0x8009, 0x96c0, 0xcb40, 0x2518, 0x8124, 0x2f10, 0x0126, 0x32b4, 0x8009, 0x9ac0, 0x64e0, 0xeb1c }, 16, 0x000a5c40, 1},
++	{{0x39c8, 0x3c00, 0xbfff, 0x9ac0, 0xd881, 0x5d93, 0x0426, 0x3334, 0x8009, 0x2660, 0x0a26, 0x3360, 0x8009, 0x9d61, 0x0222, 0x3340 }, 16, 0x000a5c60, 1},
++	{{0x8009, 0x3044, 0x3d6e, 0x800a, 0x0622, 0x3348, 0x8009, 0x9f7d, 0x9ac0, 0x65e0, 0x0726, 0x32b4, 0x8009, 0xc281, 0x27e0, 0x3453 }, 16, 0x000a5c80, 1},
++	{{0x0426, 0x3334, 0x8009, 0x2660, 0xdb07, 0x98c0, 0xd742, 0x0226, 0x3348, 0x8009, 0x3941, 0xd446, 0x96c0, 0x6460, 0x3612, 0x8032 }, 16, 0x000a5ca0, 1},
++	{{0x2c7d, 0x0222, 0x3348, 0x8009, 0x84a6, 0x0422, 0x3334, 0x8009, 0x9f7c, 0x98c0, 0xc082, 0x3044, 0x3d6e, 0x800a, 0x0022, 0x3340 }, 16, 0x000a5cc0, 1},
++	{{0x8009, 0x25e0, 0x1d91, 0xc681, 0x9ac0, 0x7553, 0xd4c6, 0x0626, 0x3320, 0x8009, 0x9cc0, 0xd541, 0x6760, 0xedaa, 0x3141, 0x2d90 }, 16, 0x000a5ce0, 1},
++	{{0x8004, 0x6560, 0x3452, 0x6e7d, 0x2c7d, 0x0622, 0x3320, 0x8009, 0x845e, 0x0422, 0x3334, 0x8009, 0x9ac0, 0x3aa0, 0x8004, 0x90c0 }, 16, 0x000a5d00, 1},
++	{{0x36a2, 0x8004, 0x38a0, 0x8004, 0xd810, 0x98c0, 0xd442, 0x32e4, 0x3c4e, 0x8001, 0x6460, 0x98c0, 0x2800, 0x83e8, 0x6e10, 0xce40 }, 16, 0x000a5d20, 1},
++	{{0x3d00, 0x20d0, 0x8008, 0x98c0, 0x3fc8, 0x3c00, 0xbfff, 0xe83e, 0x0815, 0x36e9, 0x3fff, 0xbfff, 0x1897, 0x0622, 0x3320, 0x8009 }, 16, 0x000a5d40, 1},
++	{{0x0422, 0x3358, 0x8009, 0xe842, 0x0822, 0x3360, 0x8009, 0x2e10, 0x0322, 0x32b4, 0x8009, 0x0422, 0x32b0, 0x8009, 0x94c0, 0x9e21 }, 16, 0x000a5d60, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x20e0, 0x9fa6, 0x7650, 0xc586, 0x9ac0, 0x6c7c, 0xc286 }, 16, 0x000a5d80, 1},
++	{{0x3c60, 0x2624, 0x8008, 0x74e4, 0x6d7d, 0x7665, 0x6e28, 0x7e41, 0xc944, 0x90c0, 0x94c0, 0xe91c, 0x9f70, 0x50d1, 0x90c0, 0x90c0 }, 16, 0x000a5da0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0xe844, 0x1490, 0xe858, 0x98c0, 0x399e, 0x8000, 0x9620, 0x9720 }, 16, 0x000a5dc0, 1},
++	{{0x2769, 0x1010, 0xc68f, 0x841e, 0x98c0, 0x30ca, 0x8104, 0x9e20, 0x9f20, 0x2561, 0xc081, 0x6e0a, 0xd414, 0x2461, 0x3044, 0x3e14 }, 16, 0x000a5de0, 1},
++	{{0x800a, 0x6464, 0x98c0, 0x30cb, 0x8108, 0xc28f, 0xc081, 0x65e1, 0x6cbd, 0xd411, 0x9ac0, 0x280f, 0x823e, 0x6461, 0x2160, 0x9fff }, 16, 0x000a5e00, 1},
++	{{0x1217, 0x3284, 0x20f0, 0x800a, 0xd442, 0x98c0, 0x2c00, 0x823e, 0x7650, 0xeaef, 0x94c0, 0xc38f, 0xc081, 0x96c0, 0xea3c, 0x2f0e }, 16, 0x000a5e20, 1},
++	{{0x8024, 0x1612, 0xcca6, 0x9ac0, 0x3d1d, 0x800f, 0xedee, 0x2120, 0x8000, 0x2fad, 0xed3c, 0x94c0, 0xd417, 0xecee, 0x2461, 0xec62 }, 16, 0x000a5e40, 1},
++	{{0x6c7c, 0x2ea0, 0x4417, 0x96c0, 0x3b65, 0x9fff, 0x5316, 0x9ac0, 0x3480, 0x8003, 0x6d7c, 0x3686, 0x8003, 0x3080, 0x8003, 0xd810 }, 16, 0x000a5e60, 1},
++	{{0xd446, 0x30cc, 0x944f, 0x4416, 0x0515, 0xee64, 0x5616, 0xd916, 0x3440, 0x8005, 0x7c6f, 0x4014, 0x4016, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a5e80, 1},
++	{{0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0 }, 16, 0x000a5ea0, 1},
++	{{0xe748, 0x2000, 0x82c0, 0x98c0, 0xc94e, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf041, 0xeee8, 0x3a80, 0xa000, 0x6d10, 0xc946, 0x2e0d }, 16, 0x000a5ec0, 1},
++	{{0x800c, 0x9ac0, 0x2102, 0x8150, 0x90c0, 0x2402, 0x80f8, 0x90c0, 0x96c0, 0x57d9, 0x2202, 0x8268, 0x3880, 0xa000, 0x471d, 0x2600 }, 16, 0x000a5ee0, 1},
++	{{0x8200, 0x96c0, 0x57d9, 0x2b00, 0x8184, 0x3880, 0xa000, 0x471d, 0x2800, 0x8210, 0x96c0, 0x5519, 0x2702, 0x8296, 0x3880, 0xa000 }, 16, 0x000a5f00, 1},
++	{{0x451d, 0x2f00, 0x8294, 0x96c0, 0x5119, 0x2d00, 0x8298, 0x3880, 0xa000, 0x411d, 0x2540, 0x8000, 0x96c0, 0x5719, 0x2420, 0x8000 }, 16, 0x000a5f20, 1},
++	{{0x3880, 0xa000, 0x471d, 0x2100, 0x9000, 0x1711, 0xe948, 0x3880, 0xa000, 0x471d, 0x2002, 0x81dc, 0x3880, 0xa000, 0x421d, 0x2602 }, 16, 0x000a5f40, 1},
++	{{0x8250, 0x3480, 0xa000, 0x421d, 0x3840, 0xa000, 0x5319, 0x2d0a, 0x8242, 0x3880, 0xa000, 0x4315, 0x2a0c, 0x804a, 0x96c0, 0x50d9 }, 16, 0x000a5f60, 1},
++	{{0x2502, 0x813c, 0x4012, 0x5319, 0x431c, 0x1211, 0xe944, 0x021c, 0xc288, 0x5019, 0x96c0, 0x401c, 0x20e0, 0x8000, 0x1311, 0xe944 }, 16, 0x000a5f80, 1},
++	{{0x431c, 0x5319, 0x4314, 0x1799, 0xec44, 0x479c, 0x1711, 0xeaec, 0x3620, 0xa000, 0xea3c, 0x4714, 0x3600, 0xa100, 0x4692, 0xecec }, 16, 0x000a5fa0, 1},
++	{{0x3600, 0xa100, 0xeaec, 0xec3b, 0x3600, 0xa100, 0xea38, 0x4694, 0x0692, 0xebec, 0x3600, 0xa100, 0xeaec, 0xecec, 0x94c0, 0xea3d }, 16, 0x000a5fc0, 1},
++	{{0xeb3f, 0x36a0, 0xa000, 0xec3f, 0x4512, 0x3600, 0xa100, 0x4413, 0x4114, 0x98c0, 0x0fc6, 0x2100, 0x8009, 0xe8ec, 0x94c0, 0xedec }, 16, 0x000a5fe0, 1},
++	{{0xe96e, 0x3820, 0xa100, 0xe838, 0x2f0f, 0x80d4, 0x3680, 0xa000, 0x55df, 0xebec, 0x36c0, 0xa000, 0x57d7, 0xed3a, 0x9ac0, 0x2202 }, 16, 0x000a6000, 1},
++	{{0x8254, 0xdb97, 0x2f00, 0x8138, 0x3a40, 0xa000, 0x2002, 0x81c8, 0xdf9d, 0xeb39, 0x3600, 0xa100, 0x4796, 0xefec, 0x3600, 0xa100 }, 16, 0x000a6020, 1},
++	{{0x5711, 0xebec, 0x96c0, 0x4710, 0x2800, 0x81c4, 0x3680, 0xa000, 0xe9ec, 0xeeec, 0x0713, 0xeaec, 0x0715, 0xea3f, 0x3a00, 0xa100 }, 16, 0x000a6040, 1},
++	{{0x0220, 0x3540, 0x8009, 0xef38, 0x36e0, 0xa000, 0xe93e, 0xee3d, 0x36e0, 0xa000, 0xeb38, 0xec3a, 0x3600, 0xa100, 0x4692, 0x4697 }, 16, 0x000a6060, 1},
++	{{0x3680, 0xa000, 0x4691, 0x4016, 0x32c4, 0x3330, 0x800a, 0x3680, 0xa000, 0x4013, 0x4014, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000a6080, 1},
++	{{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x9f20, 0x2100, 0x8078, 0x280f, 0x82b8, 0x1417, 0x3284 }, 16, 0x000a60a0, 1},
++	{{0x20f0, 0x800a, 0x3918, 0x807f, 0x98c0, 0x311c, 0x8007, 0x5117, 0x9f21, 0x3e41, 0x3d20, 0x3544, 0x8009, 0x9ac0, 0x331b, 0x8008 }, 16, 0x000a60c0, 1},
++	{{0xca44, 0x3318, 0x807f, 0x9ac0, 0x30cd, 0x80c4, 0x65e9, 0x32ca, 0x80c7, 0xea1d, 0x96c7, 0x53d2, 0x2000, 0x85a6, 0x94c3, 0x3601 }, 16, 0x000a60e0, 1},
++	{{0x8003, 0x94c3, 0x32cb, 0x958a, 0xd595, 0x65e1, 0xd59a, 0x3700, 0x8008, 0x94c0, 0x7c64, 0x9f70, 0x7470, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6100, 1},
++	{{0x6466, 0x30f0, 0x2d31, 0x7cc1, 0x92c2, 0x7d69, 0xd541, 0x94c0, 0x75c2, 0x9f70, 0x7473, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6120, 1},
++	{{0x96c0, 0x6f10, 0x9620, 0x9720, 0xe958, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xefe8, 0x3284, 0x20b0, 0x800a, 0x1091, 0xc94f, 0x37d0 }, 16, 0x000a6140, 1},
++	{{0xc947, 0x90c0, 0x290e, 0x8058, 0x3284, 0x20b0, 0x800a, 0x5096, 0x9ac0, 0x6f83, 0xee44, 0x3284, 0x20b0, 0x800a, 0x5096, 0x96c0 }, 16, 0x000a6160, 1},
++	{{0x6760, 0x2f09, 0x82a8, 0x1311, 0xe942, 0x31f0, 0x5311, 0x801f, 0x71f7, 0x90c0, 0x94c7, 0xd7af, 0xc681, 0x90c0, 0x92c2, 0xee52 }, 16, 0x000a6180, 1},
++	{{0x92c2, 0x5516, 0x92c2, 0x7ac1, 0x92c2, 0x4516, 0x96c0, 0x7456, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a61a0, 1},
++	{{0xe848, 0x96c0, 0x5490, 0x280a, 0x8018, 0x98c0, 0x395c, 0x8000, 0x9620, 0x9720, 0x96c0, 0x6669, 0x9e20, 0x9f20, 0x94c0, 0x5092 }, 16, 0x000a61c0, 1},
++	{{0x84a9, 0x3284, 0x20b0, 0x800a, 0x94c0, 0xc84f, 0xeeea, 0x3750, 0xebee, 0x98c0, 0xeb68, 0x3284, 0x20b0, 0x800a, 0x5093, 0x96c0 }, 16, 0x000a61e0, 1},
++	{{0x6f02, 0xeaee, 0xc847, 0x35d6, 0xea5a, 0x98c0, 0x7dc1, 0xe9ea, 0x2a0f, 0x800c, 0x25e1, 0xe972, 0x6f4e, 0x3d01, 0x8004, 0x7ce3 }, 16, 0x000a6200, 1},
++	{{0x4112, 0x1017, 0x5711, 0x9ac0, 0x3610, 0x81ff, 0x7841, 0x3f1c, 0x80ff, 0x96c0, 0x3ecd, 0x9608, 0x801d, 0x001f, 0x3284, 0x2120 }, 16, 0x000a6220, 1},
++	{{0x800a, 0x1012, 0x5117, 0x0017, 0x3164, 0x2284, 0x800a, 0x9ac0, 0x2f09, 0x8002, 0x90c0, 0x2f0b, 0x8006, 0x1111, 0x5013, 0x32f1 }, 16, 0x000a6240, 1},
++	{{0x7841, 0x94c0, 0x76f0, 0x801d, 0x3275, 0x2c90, 0x0013, 0xc2df, 0x800f, 0x4113, 0x5690, 0x0946, 0xa000, 0xdd06, 0x4290, 0x6f10 }, 16, 0x000a6260, 1},
++	{{0x4611, 0x4617, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6280, 1},
++	{{0xe848, 0x94c0, 0x9620, 0x9720, 0x5690, 0x98c0, 0x3d1c, 0x8010, 0x9e20, 0x9f20, 0x96c0, 0x6669, 0x280f, 0x8038, 0x94c0, 0x5097 }, 16, 0x000a62a0, 1},
++	{{0x807b, 0x3384, 0x20b0, 0x800a, 0x96c0, 0x77d0, 0xcca0, 0xebef, 0x90c0, 0x98c0, 0xeb3c, 0x3284, 0x20b0, 0x800a, 0x5093, 0x96c0 }, 16, 0x000a62c0, 1},
++	{{0x6e83, 0xeeef, 0xe8ef, 0x96c0, 0x77d5, 0xee68, 0xe862, 0x3fc1, 0xebef, 0x96c0, 0x67e1, 0xeb64, 0xef44, 0x6edb, 0x96c0, 0x3b07 }, 16, 0x000a62e0, 1},
++	{{0x8004, 0x6e90, 0x7fe3, 0x4716, 0x1410, 0x5013, 0x3a41, 0x1617, 0xd7c0, 0x9ac0, 0x7574, 0x3ccb, 0x9704, 0x4713, 0x4410, 0x98c0 }, 16, 0x000a6300, 1},
++	{{0x3612, 0x80ff, 0x6c8e, 0x5013, 0x94c0, 0x7c64, 0x840f, 0x2ed1, 0x0513, 0x4510, 0x4517, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a6320, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3e00, 0xa004, 0x311f, 0x800f, 0xf9c3, 0x30c8, 0x8104, 0xc3a0 }, 16, 0x000a6340, 1},
++	{{0x9cc0, 0x6461, 0x2160, 0x9ff0, 0x7551, 0x2580, 0x8010, 0x3820, 0xa000, 0x6d93, 0x7651, 0x5591, 0x3400, 0xa804, 0x7755, 0x3600 }, 16, 0x000a6360, 1},
++	{{0xa80c, 0xd71f, 0x7bc1, 0x3c00, 0xa066, 0x34c1, 0x8003, 0x90c0, 0x36c0, 0x8003, 0x3400, 0xa804, 0xda11, 0x3400, 0xa804, 0xd640 }, 16, 0x000a6380, 1},
++	{{0x3600, 0xa804, 0x38cb, 0x96c5, 0x3400, 0xa844, 0x6d0d, 0x3400, 0xa044, 0x6f5c, 0x3640, 0xa840, 0x6d1a, 0x4691, 0x3400, 0xa004 }, 16, 0x000a63a0, 1},
++	{{0x76d2, 0x3400, 0xa804, 0xd69f, 0x3c00, 0xa064, 0x34a0, 0x8003, 0x90c0, 0x36a3, 0x8003, 0x3400, 0xa804, 0xdb90, 0x3400, 0xa004 }, 16, 0x000a63c0, 1},
++	{{0xd7c3, 0x3600, 0xa804, 0x3ec9, 0x96c5, 0x3400, 0xa040, 0x6c18, 0x6c7d, 0x74d4, 0x94c0, 0x6d7c, 0x9f70, 0x7455, 0x90c0, 0x90c0 }, 16, 0x000a63e0, 1},
++	{{0x3284, 0x20f0, 0x800a, 0x2160, 0x9fff, 0x3084, 0x2120, 0x800a, 0x2180, 0x8001, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6400, 1},
++	{{0x96c0, 0x5011, 0x280c, 0x826c, 0x0014, 0xfdc3, 0xec50, 0x0014, 0xe8ec, 0x1215, 0xe86e, 0x0210, 0xec42, 0x9f70, 0x4214, 0x90c0 }, 16, 0x000a6420, 1},
++	{{0x96c0, 0xcda2, 0x2808, 0x827c, 0x96c0, 0x5410, 0x280a, 0x8024, 0x0411, 0xecea, 0x94c0, 0xec3d, 0xfbc3, 0x5114, 0x94c0, 0x4112 }, 16, 0x000a6440, 1},
++	{{0x9f70, 0x4113, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x38a0, 0x3070, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6460, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20c0, 0x800a, 0xe748, 0x1e90, 0x33a4, 0x34b0, 0x800b, 0x9ac0, 0x6c90 }, 16, 0x000a6480, 1},
++	{{0xefe8, 0x0cc6, 0x2100, 0x8009, 0x1396, 0xe8ee, 0x9ac0, 0x2300, 0x82c0, 0x90c0, 0x371f, 0x8001, 0x96c0, 0x67e9, 0x2c0c, 0x80a8 }, 16, 0x000a64a0, 1},
++	{{0x96c0, 0xcc4e, 0x2518, 0x8284, 0x32e4, 0x3c8a, 0x8001, 0xf341, 0x3a80, 0xa000, 0x6f90, 0xcc46, 0x2e0a, 0x800c, 0x9ac0, 0x2402 }, 16, 0x000a64c0, 1},
++	{{0x8268, 0x90c0, 0x2302, 0x8150, 0x90c0, 0x96c0, 0x52dc, 0x2502, 0x8294, 0x3880, 0xa000, 0x421a, 0x2702, 0x80f8, 0x96c0, 0x51dc }, 16, 0x000a64e0, 1},
++	{{0x2600, 0x8200, 0x3880, 0xa000, 0x411a, 0x2900, 0x8210, 0x96c0, 0x551c, 0x2800, 0x8184, 0x3880, 0xa000, 0x451a, 0x2602, 0x8296 }, 16, 0x000a6500, 1},
++	{{0x96c0, 0x501c, 0x2a00, 0x8298, 0x3880, 0xa000, 0x401a, 0x2540, 0x8000, 0x96c0, 0x531c, 0x2200, 0x9000, 0x3880, 0xa000, 0x431a }, 16, 0x000a6520, 1},
++	{{0x2420, 0x8000, 0x1114, 0xec48, 0x3880, 0xa000, 0x411a, 0x2002, 0x81dc, 0x3880, 0xa000, 0x471a, 0x23e0, 0x8000, 0x3480, 0xa000 }, 16, 0x000a6540, 1},
++	{{0x471a, 0x3840, 0xa000, 0x511c, 0x2a0b, 0x8242, 0x3880, 0xa000, 0x4112, 0x2b0d, 0x804a, 0x96c0, 0x50dc, 0x2202, 0x8138, 0x4013 }, 16, 0x000a6560, 1},
++	{{0x511c, 0x411d, 0x1014, 0xec44, 0x001d, 0xc088, 0x511c, 0x411d, 0x1714, 0xec44, 0x471d, 0x511c, 0x4115, 0x179c, 0xed44, 0x479d }, 16, 0x000a6580, 1},
++	{{0x1714, 0xebed, 0x3620, 0xa000, 0xeb3f, 0x4715, 0x3600, 0xa100, 0x4693, 0xefed, 0x3600, 0xa100, 0xebed, 0xef38, 0x3600, 0xa100 }, 16, 0x000a65a0, 1},
++	{{0xeb39, 0x4697, 0x0693, 0xe9ed, 0x3600, 0xa100, 0xebed, 0xefed, 0x3660, 0xa100, 0xe93d, 0xef3e, 0x0411, 0xeb3a, 0x3600, 0xa100 }, 16, 0x000a65c0, 1},
++	{{0x4513, 0x4217, 0x3a20, 0xa000, 0x0dc6, 0x2100, 0x8009, 0xeaed, 0x94c0, 0xe8ed, 0xec6e, 0x3840, 0xa100, 0xe9ed, 0x2d0e, 0x80d4 }, 16, 0x000a65e0, 1},
++	{{0x36c0, 0xa000, 0x52de, 0xe83b, 0x36c0, 0xa000, 0x57d6, 0xea3c, 0x3820, 0xa100, 0xda97, 0xeded, 0xe938, 0x9ac0, 0x2402, 0x8254 }, 16, 0x000a6600, 1},
++	{{0xde9a, 0x2002, 0x81c8, 0x96c0, 0x4596, 0x2302, 0x813c, 0x3640, 0xa100, 0x5714, 0xed3a, 0x96c0, 0x4712, 0x2a00, 0x8250, 0x96c0 }, 16, 0x000a6620, 1},
++	{{0x4710, 0x2800, 0x81c4, 0x3680, 0xa000, 0xeeed, 0xeced, 0x3680, 0xa100, 0xe9ed, 0xeaed, 0x3600, 0xa100, 0x4711, 0xee38, 0x3a00 }, 16, 0x000a6640, 1},
++	{{0xa100, 0x0020, 0x3540, 0x8009, 0xea3a, 0x3660, 0xa100, 0xec3b, 0xe938, 0x3620, 0xa100, 0xed3c, 0x4695, 0x3680, 0xa100, 0x4696 }, 16, 0x000a6660, 1},
++	{{0x4692, 0x3600, 0xa100, 0x4314, 0x4311, 0x32c4, 0x3330, 0x800a, 0x4315, 0x98c0, 0x09c6, 0x2100, 0x8009, 0xe8ef, 0x32a4, 0x32d0 }, 16, 0x000a6680, 1},
++	{{0x800b, 0xe948, 0x2f90, 0xc683, 0x3457, 0x0cc6, 0x2100, 0x8009, 0x3264, 0x3890, 0x800a, 0x2c09, 0x8038, 0x3457, 0x0fc6, 0x2100 }, 16, 0x000a66a0, 1},
++	{{0x8009, 0x3264, 0x3c90, 0x800a, 0x2f09, 0x8044, 0x3224, 0x3ef0, 0x800c, 0x7457, 0x3457, 0x08c6, 0x2100, 0x8009, 0x3264, 0x3400 }, 16, 0x000a66c0, 1},
++	{{0x800a, 0x2809, 0x8030, 0x3457, 0x09c6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2909, 0x80dc, 0x3b61, 0x7bc1, 0x676a, 0x81ab }, 16, 0x000a66e0, 1},
++	{{0x3224, 0x3ef0, 0x800c, 0xc083, 0x98c0, 0x0fc6, 0x2100, 0x8009, 0xc083, 0x3264, 0x3400, 0x800a, 0x2f09, 0x8028, 0x98c0, 0x0fc6 }, 16, 0x000a6700, 1},
++	{{0x2100, 0x8009, 0xc2fe, 0x94c0, 0xc3fe, 0xc081, 0x2f0d, 0x80d4, 0x56d5, 0xdd06, 0x4215, 0x5596, 0x98c0, 0xdd85, 0x3064, 0x2746 }, 16, 0x000a6720, 1},
++	{{0x800a, 0x4396, 0x6c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6740, 1},
++	{{0x94c0, 0x5390, 0x9e20, 0x96c0, 0x370b, 0x8010, 0xe844, 0x98c0, 0x65e9, 0x5390, 0x280e, 0x82a0, 0x96c0, 0x379d, 0x8000, 0x804f }, 16, 0x000a6760, 1},
++	{{0x98c0, 0x66e9, 0x5096, 0x2e0b, 0x8008, 0x96c0, 0x7861, 0x5213, 0x8017, 0x3284, 0x2110, 0x800a, 0x6c90, 0x3164, 0x27a6, 0x800a }, 16, 0x000a6780, 1},
++	{{0x3518, 0x8fff, 0x7c4a, 0x2469, 0x0096, 0xcbb2, 0x94c0, 0xee48, 0x841b, 0x1216, 0xe8ee, 0x3d6c, 0xe83b, 0x1510, 0xcbb0, 0xd69a }, 16, 0x000a67a0, 1},
++	{{0x0510, 0xee3b, 0x4516, 0x9e21, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xf38f }, 16, 0x000a67c0, 1},
++	{{0xf790, 0x96c0, 0x6aaf, 0xf4c7, 0xf3c7, 0x94c0, 0xd618, 0xd699, 0x2fac, 0xde15, 0x2668, 0xd7c5, 0x94c0, 0x7657, 0x840d, 0xde13 }, 16, 0x000a67e0, 1},
++	{{0x6668, 0xd3db, 0x3457, 0x3284, 0x20b0, 0x800a, 0x6466, 0x94c0, 0xcf40, 0xf0c9, 0x3284, 0x20b0, 0x800a, 0xeffc, 0x3284, 0x2110 }, 16, 0x000a6800, 1},
++	{{0x800a, 0x2100, 0x807d, 0x94c0, 0xcd40, 0xf0ca, 0x3284, 0x20b0, 0x800a, 0xef3d, 0x3284, 0x2110, 0x800a, 0x2100, 0x807d, 0x96c0 }, 16, 0x000a6820, 1},
++	{{0x7457, 0xc940, 0xcf4c, 0x94c0, 0xc94e, 0xfdcb, 0x96c0, 0x6cb6, 0x25e0, 0x9faa, 0x96c0, 0x6d7c, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a6840, 1},
++	{{0x9721, 0x9f70, 0x4515, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x77d1, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0 }, 16, 0x000a6860, 1},
++	{{0xeee8, 0x270d, 0x8060, 0x32c4, 0x20c0, 0x800a, 0xe7ed, 0x94c0, 0xee4e, 0xc39a, 0x96c0, 0xce49, 0x2000, 0x808c, 0x96c0, 0xd5c1 }, 16, 0x000a6880, 1},
++	{{0x5116, 0xca47, 0x9ac0, 0x33fc, 0x9000, 0x74d3, 0x280c, 0x8058, 0x9cc0, 0x6883, 0x7e6c, 0xeafe, 0x0224, 0x3540, 0x8009, 0x94c0 }, 16, 0x000a68a0, 1},
++	{{0xc841, 0xea1c, 0x90c0, 0x96c0, 0x5892, 0x280b, 0x8020, 0x96c0, 0x5593, 0x2b0a, 0x804a, 0x3600, 0xa004, 0x7655, 0x5112, 0x3600 }, 16, 0x000a68c0, 1},
++	{{0xa008, 0x68f4, 0xd61c, 0x3600, 0xa080, 0xd49a, 0x6d15, 0x3600, 0xa004, 0xde11, 0xd541, 0x3600, 0xa004, 0x6668, 0x74d2, 0x94c0 }, 16, 0x000a68e0, 1},
++	{{0xdc95, 0x840b, 0x64e8, 0xd15d, 0x0293, 0xe84e, 0x3a20, 0xa000, 0x0526, 0x3534, 0x8009, 0x5510, 0x3e00, 0xa804, 0x3b1f, 0x8001 }, 16, 0x000a6900, 1},
++	{{0xc9ba, 0x3ac9, 0x810c, 0x5512, 0x3a40, 0xa004, 0x67e9, 0x6af6, 0xecea, 0x5512, 0x3c00, 0xa42e, 0xd052, 0xd15a, 0x7ee6, 0x68f6 }, 16, 0x000a6920, 1},
++	{{0xec39, 0x3a01, 0xa009, 0xe9ec, 0xd519, 0x6464, 0xe9ec, 0x3a01, 0xa089, 0xe96c, 0x6dbc, 0xd419, 0xe96c, 0x3646, 0xa044, 0x6dd2 }, 16, 0x000a6940, 1},
++	{{0x5691, 0x3600, 0xb040, 0x6c4d, 0x74d6, 0x4094, 0x3a20, 0xa000, 0x5410, 0x0524, 0x3540, 0x8009, 0x3800, 0xa805, 0x38cf, 0x810c }, 16, 0x000a6960, 1},
++	{{0xd49d, 0x3400, 0xa800, 0xd49f, 0x3600, 0xb800, 0x6e86, 0xdc91, 0x3600, 0xb000, 0x64e8, 0xd6c1, 0x94c0, 0x7555, 0x8415, 0x3400 }, 16, 0x000a6980, 1},
++	{{0xa800, 0xdd16, 0x6568, 0x3400, 0xa800, 0xd2de, 0x96c0, 0x4591, 0x2a0e, 0x8006, 0x1296, 0x5512, 0x3c20, 0xa000, 0x74d2, 0x6af6 }, 16, 0x000a69a0, 1},
++	{{0x0424, 0x3540, 0x8009, 0x3600, 0xb000, 0xd49c, 0xd69c, 0x3600, 0xa004, 0x6d98, 0xdc95, 0x3600, 0xa008, 0x64e8, 0xd5c5, 0x3600 }, 16, 0x000a69c0, 1},
++	{{0xa800, 0x74d3, 0x8413, 0xdc92, 0x64e8, 0x3400, 0xa004, 0xd1da, 0x3640, 0xa000, 0xc153, 0x4396, 0x0324, 0x3540, 0x8009, 0x3620 }, 16, 0x000a69e0, 1},
++	{{0xa000, 0x290e, 0x8264, 0x1196, 0xedee, 0x36d1, 0xed7c, 0x1215, 0xd69c, 0x3600, 0xa004, 0x68bc, 0x6d25, 0x3400, 0xa004, 0xd49b }, 16, 0x000a6a00, 1},
++	{{0x3600, 0xb800, 0xde91, 0xd541, 0x26e8, 0x76d2, 0x94c0, 0xde91, 0x840b, 0x66e8, 0xd159, 0x94c0, 0xcfaa, 0xedea, 0x3840, 0xa100 }, 16, 0x000a6a20, 1},
++	{{0x4296, 0x290d, 0x8252, 0x3680, 0xa000, 0x5215, 0xed3f, 0x293c, 0x1395, 0x0124, 0x3540, 0x8009, 0x34d3, 0xd519, 0xd49c, 0x2e99 }, 16, 0x000a6a40, 1},
++	{{0xdc92, 0x24e8, 0xd6c2, 0x94c0, 0x7555, 0x840d, 0xdd13, 0x6568, 0xd2db, 0x3880, 0xa100, 0xebeb, 0x2a08, 0x8002, 0x3680, 0xa000 }, 16, 0x000a6a60, 1},
++	{{0xeb68, 0x4595, 0x3680, 0xa100, 0x5110, 0x5293, 0x36d2, 0x29f4, 0x0124, 0x3540, 0x8009, 0x94c0, 0xd69c, 0xd599, 0x2ca9, 0xde93 }, 16, 0x000a6a80, 1},
++	{{0x26e8, 0xd4c3, 0x94c0, 0x76d1, 0x840d, 0xde92, 0x66e8, 0xd0da, 0x3680, 0xa000, 0x4193, 0xcfbe, 0x1510, 0x0326, 0x3534, 0x8009 }, 16, 0x000a6aa0, 1},
++	{{0x3ea0, 0xa100, 0x371b, 0x8001, 0x5510, 0x3acd, 0x810c, 0xe9ea, 0x3ac0, 0xb180, 0x65e9, 0x6976, 0xe93f, 0x5510, 0x3ca0, 0xa42a }, 16, 0x000a6ac0, 1},
++	{{0xd1d1, 0xd059, 0x7d66, 0x69f6, 0xeee9, 0x3a81, 0xa108, 0xee70, 0xd41d, 0x65e4, 0xee70, 0x3ae1, 0xa188, 0x5296, 0x6f11, 0xd59d }, 16, 0x000a6ae0, 1},
++	{{0x5296, 0x3606, 0xb004, 0x6f59, 0x74d2, 0x3400, 0xa804, 0x6e4a, 0x34a0, 0xa000, 0x4491, 0x3a20, 0xa000, 0x5110, 0x0524, 0x3540 }, 16, 0x000a6b00, 1},
++	{{0x8009, 0x3800, 0xa805, 0x32cf, 0x810c, 0xd59d, 0x3400, 0xa800, 0xd49f, 0x3600, 0xb800, 0x6d98, 0xdc93, 0x3600, 0xb000, 0x64e8 }, 16, 0x000a6b20, 1},
++	{{0xd5c3, 0x94c0, 0x7553, 0x8415, 0x3400, 0xa800, 0xdd12, 0x6568, 0x3400, 0xa800, 0xd1da, 0x3680, 0xa100, 0xeaea, 0x4396, 0x3a80 }, 16, 0x000a6b40, 1},
++	{{0xa000, 0xea7a, 0x0224, 0x3540, 0x8009, 0x38c0, 0xa000, 0x5192, 0x2a0e, 0x801e, 0x36d1, 0x5316, 0x29f5, 0xd69c, 0x2d25, 0xd59a }, 16, 0x000a6b60, 1},
++	{{0x94c0, 0xde93, 0xd543, 0x26e8, 0x75d2, 0x94c0, 0xdd91, 0x840b, 0x65e8, 0xd159, 0x3680, 0xa100, 0x4292, 0xecea, 0x3600, 0xa100 }, 16, 0x000a6b80, 1},
++	{{0x5510, 0xec76, 0x3a00, 0xa100, 0x3aca, 0x810c, 0x5116, 0x5594, 0x3c20, 0xa000, 0x69f4, 0x74d5, 0x0124, 0x3540, 0x8009, 0x3600 }, 16, 0x000a6ba0, 1},
++	{{0xb000, 0xd49a, 0xd599, 0x2d05, 0xdc93, 0x24e8, 0xd543, 0x94c0, 0x74d2, 0x840d, 0xdc95, 0x64e8, 0xd15d, 0x96c0, 0x5116, 0x2a0f }, 16, 0x000a6bc0, 1},
++	{{0x800a, 0x3880, 0xa000, 0x6af4, 0x5397, 0x4294, 0x34d3, 0x0224, 0x3540, 0x8009, 0x94c0, 0xd69a, 0xd49c, 0x2c19, 0xdc95, 0x24e8 }, 16, 0x000a6be0, 1},
++	{{0xd445, 0x94c0, 0x76d0, 0x840d, 0xde93, 0x66e8, 0xd05b, 0x3600, 0xa100, 0x4097, 0xefea, 0x3600, 0xa100, 0x5310, 0xef6e, 0x3a80 }, 16, 0x000a6c00, 1},
++	{{0xa000, 0x36cd, 0x810c, 0x5197, 0x5616, 0x3880, 0xa100, 0x7475, 0x5296, 0x5310, 0x38c0, 0xa000, 0x5594, 0x2f0f, 0x800a, 0x94c0 }, 16, 0x000a6c20, 1},
++	{{0xf603, 0xf141, 0x94c0, 0xf243, 0xff45, 0x94c0, 0xf544, 0xf304, 0x98c0, 0x0124, 0x3540, 0x8009, 0xf847, 0x94c0, 0xf448, 0xfb49 }, 16, 0x000a6c40, 1},
++	{{0x94c0, 0xfa4a, 0xf94b, 0x3640, 0xa000, 0xfd4c, 0xfd4d, 0x3660, 0xa000, 0xfb4e, 0xf84f, 0x3660, 0xa000, 0xf950, 0xfe51, 0x98c0 }, 16, 0x000a6c60, 1},
++	{{0xcc4e, 0x3264, 0x27d0, 0x800a, 0x3660, 0xa000, 0xfa52, 0xff53, 0x3660, 0xa000, 0xffd3, 0xccb2, 0x94c0, 0xcc46, 0xf8c7, 0x36c0 }, 16, 0x000a6c80, 1},
++	{{0xa000, 0x4097, 0xf8cf, 0x3a80, 0xa000, 0xefef, 0x0626, 0x3534, 0x8009, 0x3aa0, 0xa000, 0x3d1b, 0x8001, 0xef3c, 0xfaca, 0x3840 }, 16, 0x000a6ca0, 1},
++	{{0xa100, 0x65e9, 0x5697, 0x5010, 0x3e80, 0xac0e, 0xd0d6, 0x30cb, 0x810c, 0xd15e, 0x5210, 0x5112, 0x3a46, 0xa003, 0x90c0, 0xf9d0 }, 16, 0x000a6cc0, 1},
++	{{0x64e4, 0x6ab8, 0x3e61, 0xb20f, 0xccbc, 0xd51b, 0xd49b, 0x7ee6, 0x7ee6, 0xccbc, 0x3a81, 0xb399, 0x5591, 0x6e0a, 0x6e46, 0x5591 }, 16, 0x000a6ce0, 1},
++	{{0x3820, 0xa840, 0x6c55, 0x5294, 0xff55, 0x3a20, 0xa000, 0xef3c, 0x3284, 0x20b0, 0x800a, 0x98c0, 0x6466, 0x7752, 0xf054, 0xf556 }, 16, 0x000a6d00, 1},
++	{{0x94c0, 0xcc40, 0xf5d6, 0x7455, 0x98c0, 0xecfc, 0x3284, 0x20b0, 0x800a, 0xfc57, 0x96c0, 0x7456, 0xfcd7, 0xc150, 0x90c0, 0x3a20 }, 16, 0x000a6d20, 1},
++	{{0xa000, 0xec39, 0x3284, 0x20b0, 0x800a, 0xfc57, 0x94c0, 0xc150, 0xfcd7, 0x3640, 0xa000, 0xfaca, 0xffd5, 0x94c0, 0xf8c7, 0xf0d4 }, 16, 0x000a6d40, 1},
++	{{0x3620, 0xa000, 0xec39, 0xf9cb, 0x3660, 0xa000, 0xfed1, 0xf8cf, 0x3680, 0xa000, 0xecea, 0x4c17, 0x3680, 0xa100, 0x4097, 0xec6a }, 16, 0x000a6d60, 1},
++	{{0x3600, 0xa100, 0x5210, 0x5196, 0x3a00, 0xa104, 0x34c8, 0x810c, 0x5691, 0x5394, 0x3800, 0xa900, 0x7470, 0x5210, 0x5512, 0x3840 }, 16, 0x000a6d80, 1},
++	{{0xa000, 0xf143, 0x2c0f, 0x8008, 0x94c0, 0xf644, 0xff45, 0x94c0, 0xf204, 0xf503, 0x98c0, 0xc45e, 0x3264, 0x27d0, 0x800a, 0x98c0 }, 16, 0x000a6da0, 1},
++	{{0xf341, 0x0124, 0x3540, 0x8009, 0x3820, 0xa000, 0x7750, 0xc456, 0xf8cf, 0x3640, 0xa000, 0xfdcc, 0xfdcd, 0x3620, 0xa000, 0xfbce }, 16, 0x000a6dc0, 1},
++	{{0xe8ef, 0x3680, 0xa000, 0x4694, 0xecef, 0x3600, 0xa100, 0xe870, 0x5110, 0x1695, 0x5390, 0x3680, 0xa100, 0x5515, 0x5293, 0x94c0 }, 16, 0x000a6de0, 1},
++	{{0xf4c8, 0xec64, 0x96c0, 0x7454, 0xf644, 0xf104, 0x94c0, 0xf503, 0xf341, 0x94c0, 0xfc45, 0xf243, 0x3264, 0x27d0, 0x800a, 0x98c0 }, 16, 0x000a6e00, 1},
++	{{0x0124, 0x3540, 0x8009, 0xc84e, 0x96c0, 0x76d0, 0xfbc9, 0xfaca, 0x3620, 0xa000, 0xfad2, 0xc846, 0x1616, 0xef54, 0x0590, 0xeeef }, 16, 0x000a6e20, 1},
++	{{0x1112, 0xf4c8, 0x3454, 0x1397, 0x5293, 0x3680, 0xa000, 0x5592, 0xee64, 0x94c0, 0xf104, 0xf544, 0x94c0, 0xfe45, 0xf243, 0x94c0 }, 16, 0x000a6e40, 1},
++	{{0xf603, 0xf341, 0x3264, 0x27d0, 0x800a, 0x0124, 0x3540, 0x8009, 0x98c0, 0x3421, 0x3554, 0x8009, 0xc394, 0x2a0f, 0x0097, 0xfaca }, 16, 0x000a6e60, 1},
++	{{0x94c0, 0xc944, 0xf4bd, 0x9ac0, 0x6a34, 0x0124, 0x3540, 0x8009, 0xea56, 0x96c0, 0xd619, 0xe942, 0x5792, 0x3757, 0x5251, 0x6569 }, 16, 0x000a6e80, 1},
++	{{0x94c1, 0xd092, 0x6d10, 0x92c3, 0x74f1, 0x94c3, 0x3302, 0x800e, 0xd71a, 0x2d1f, 0xdf14, 0x2768, 0xd544, 0x94c0, 0x7752, 0x840d }, 16, 0x000a6ea0, 1},
++	{{0xdf17, 0x6768, 0xd15f, 0x4292, 0x27ea, 0x9fa0, 0xe7ea, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a6ec0, 1},
++	{{0x96c0, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xce40, 0x3722, 0x359c, 0x8009, 0x98c0, 0x3622, 0x3590, 0x8009 }, 16, 0x000a6ee0, 1},
++	{{0xc494, 0x96c0, 0xeefe, 0x270f, 0x8028, 0x3680, 0xa000, 0xef1e, 0xe7ef, 0x36c0, 0xa000, 0x5297, 0xee1e, 0x94c0, 0xf241, 0xf942 }, 16, 0x000a6f00, 1},
++	{{0x1e96, 0x3721, 0x3554, 0x8009, 0x2b80, 0x33c4, 0x20c0, 0x800a, 0x96c0, 0x6d10, 0xcf47, 0xf9c2, 0xc184, 0x96c0, 0xef50, 0x290a }, 16, 0x000a6f20, 1},
++	{{0x8002, 0x0897, 0xca4f, 0x3284, 0x2120, 0x800a, 0x0211, 0x5012, 0x94c0, 0xca47, 0xe8ef, 0x94c0, 0xe86e, 0xecef, 0x0010, 0xea54 }, 16, 0x000a6f40, 1},
++	{{0x1512, 0xf9c2, 0x94c0, 0xec66, 0xedef, 0x0514, 0xebea, 0x3620, 0xa000, 0x5211, 0xed68, 0x3620, 0xa000, 0x4215, 0x5410, 0x3800 }, 16, 0x000a6f60, 1},
++	{{0xa140, 0x6cc8, 0xebef, 0xeb62, 0x3820, 0xa100, 0x78e1, 0xeb64, 0x5313, 0x3680, 0xa000, 0xedea, 0xedea, 0x3640, 0xa100, 0xecea }, 16, 0x000a6f80, 1},
++	{{0x4313, 0x3680, 0xa100, 0xeaea, 0xed66, 0x94c0, 0xec6a, 0xed6e, 0x1515, 0x3322, 0x35a8, 0x8009, 0x96c0, 0xdb95, 0xf143, 0x5114 }, 16, 0x000a6fa0, 1},
++	{{0x3840, 0xa104, 0xda91, 0x5115, 0xe8ea, 0x3c80, 0xb900, 0xd991, 0x3bed, 0x9fff, 0xecea, 0xea72, 0x3ea0, 0xa000, 0x37e9, 0x9fff }, 16, 0x000a6fc0, 1},
++	{{0x5712, 0x3feb, 0x9fff, 0xebea, 0x3880, 0xa804, 0xd817, 0xe864, 0xec70, 0x3a00, 0xa800, 0x31ea, 0x9fff, 0xc156, 0x5610, 0x3aa0 }, 16, 0x000a6fe0, 1},
++	{{0xa100, 0x3dfc, 0x9fff, 0x5214, 0xe8ea, 0x3c80, 0xa804, 0x35fa, 0x9fff, 0xde19, 0xeb68, 0xe86c, 0x3860, 0xa004, 0xdd1a, 0x5013 }, 16, 0x000a7000, 1},
++	{{0x54d1, 0x3ae0, 0xa800, 0x31fe, 0x9fff, 0x5710, 0x50d2, 0x3c60, 0xa900, 0x3fff, 0x9fff, 0xdf1d, 0xeb19, 0xf948, 0x3880, 0xa000 }, 16, 0x000a7020, 1},
++	{{0xdf9b, 0xf444, 0x90bb, 0x3660, 0xa000, 0xf045, 0xf446, 0x32e4, 0x39e4, 0x8001, 0x3420, 0xa000, 0xf247, 0x3a20, 0xa000, 0xf9c8 }, 16, 0x000a7040, 1},
++	{{0x3b20, 0x35ab, 0x8009, 0x90c0, 0x3a80, 0xa000, 0xe91b, 0x32e4, 0x3a68, 0x8001, 0x36c0, 0xa000, 0x90b9, 0xf948, 0x3840, 0xa004 }, 16, 0x000a7060, 1},
++	{{0x6d90, 0xf4c6, 0xf1c3, 0x3c00, 0xa402, 0x7679, 0x2e0d, 0x8004, 0xda94, 0xf2c1, 0x3e00, 0xa800, 0xde1d, 0x76d2, 0xe8ed, 0x3bc8 }, 16, 0x000a7080, 1},
++	{{0x3820, 0xbfff, 0x0495, 0xe862, 0x3660, 0xa000, 0x4316, 0xf9c8, 0x3a20, 0xa000, 0x4310, 0x3cc8, 0x3820, 0xbfff, 0x3420, 0xa000 }, 16, 0x000a70a0, 1},
++	{{0x5493, 0x3400, 0xa004, 0xde02, 0x3400, 0xa004, 0xd220, 0x840b, 0x5194, 0xdc85, 0x64e9, 0x81fb, 0x98c0, 0xce44, 0x32e4, 0x3a68 }, 16, 0x000a70c0, 1},
++	{{0x8001, 0x3680, 0xa000, 0x90b9, 0xfd49, 0x3800, 0xa004, 0x6f10, 0xfdc9, 0xce4c, 0x3660, 0xa000, 0xf4c6, 0xf0c5, 0x3800, 0xa804 }, 16, 0x000a70e0, 1},
++	{{0xd890, 0x449d, 0xf4c4, 0x3660, 0xa000, 0x4495, 0xf2c7, 0x94c0, 0xed54, 0xe8ef, 0x96c0, 0x449d, 0x27eb, 0x9fd8, 0x069d, 0xef61 }, 16, 0x000a7100, 1},
++	{{0x079d, 0xe7eb, 0x3640, 0xa000, 0xeaed, 0x4295, 0x94c0, 0xea7c, 0xed44, 0x3620, 0xa000, 0x4192, 0xe862, 0x3640, 0xa000, 0x6e10 }, 16, 0x000a7120, 1},
++	{{0xc481, 0x449d, 0x449d, 0x449d, 0x4495, 0x3660, 0xa000, 0x969f, 0x9498, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000a7140, 1},
++	{{0x3e00, 0xa004, 0x02fc, 0x9ff4, 0x6e10, 0x75d1, 0x7456, 0xc594, 0x3e00, 0xa108, 0x6566, 0x74d7, 0x3121, 0x3554, 0x8009, 0xe8ee }, 16, 0x000a7160, 1},
++	{{0x9ec0, 0x311a, 0x8003, 0x6f90, 0x0cf2, 0xbfff, 0x6881, 0xc68b, 0x9ac0, 0x7d42, 0x3c20, 0x3590, 0x8009, 0xce41, 0x96c7, 0xc942 }, 16, 0x000a7180, 1},
++	{{0x02fc, 0x9ff4, 0x9cc1, 0x6566, 0x2e0b, 0x8006, 0x6c90, 0x2e0b, 0x8006, 0x94c7, 0xe91c, 0xd81a, 0x94c7, 0x5213, 0xd010, 0x96c7 }, 16, 0x000a71a0, 1},
++	{{0xc58e, 0x3101, 0x801e, 0x2c86, 0x0084, 0x2ca2, 0x8009, 0x98c0, 0x7471, 0x3119, 0x8010, 0x5991, 0x2c7c, 0x64e9, 0x98c7, 0x6c88 }, 16, 0x000a71c0, 1},
++	{{0x6f10, 0x2908, 0x8014, 0x2d7d, 0xede8, 0x26e4, 0xed62, 0x34f5, 0x4513, 0x94c7, 0x6e18, 0x4616, 0x3e48, 0x4390, 0x98c0, 0x391c }, 16, 0x000a71e0, 1},
++	{{0x9f00, 0x5313, 0xe844, 0x96c0, 0x3718, 0x801f, 0xeb46, 0xdc1c, 0x4011, 0x3640, 0xa000, 0x5616, 0xeee8, 0x3600, 0xa800, 0x7750 }, 16, 0x000a7200, 1},
++	{{0x4615, 0xf185, 0x4190, 0x131b, 0xe876, 0x371c, 0x800f, 0x94c0, 0x4410, 0x9f70, 0x3600, 0xa800, 0x77d1, 0x979b, 0x90c0, 0x90c0 }, 16, 0x000a7220, 1},
++	{{0x96c0, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0xe748, 0x32c4, 0x20c0, 0x800a, 0xf941, 0x9cc0, 0x7456, 0x6d10, 0x3321 }, 16, 0x000a7240, 1},
++	{{0x3554, 0x8009, 0xc794, 0x9ac0, 0x699f, 0x3d1d, 0x8003, 0x5e90, 0xc681, 0x9ac0, 0x7ec2, 0xcd43, 0x3a20, 0x3590, 0x8009, 0xc845 }, 16, 0x000a7260, 1},
++	{{0xed4f, 0x94c0, 0x95bd, 0xe81a, 0x26e9, 0x5c90, 0x2518, 0x80fe, 0x94c0, 0xed61, 0xca40, 0x98c0, 0x95bd, 0x38c8, 0x3820, 0xbfff }, 16, 0x000a7280, 1},
++	{{0x94c0, 0xd2a1, 0xeafe, 0x94c6, 0x802c, 0x6d90, 0x92c2, 0x939d, 0x1790, 0x3d20, 0x359c, 0x8009, 0x90c0, 0xea1d, 0x1392, 0x3ac8 }, 16, 0x000a72a0, 1},
++	{{0x3820, 0xbfff, 0xdf83, 0xd3a0, 0x840b, 0x5692, 0xdf03, 0x6769, 0x81fb, 0x98c0, 0xcd40, 0x3f20, 0x35ab, 0x8009, 0xcc4e, 0x98c0 }, 16, 0x000a72c0, 1},
++	{{0xed1f, 0x32e4, 0x3a68, 0x8001, 0x90bd, 0x94c0, 0xf9c1, 0xcc46, 0x90c0, 0x9ac0, 0x2908, 0x804a, 0x90c0, 0x2900, 0x805e, 0x96c0 }, 16, 0x000a72e0, 1},
++	{{0x5210, 0x280b, 0x8020, 0x96c0, 0xefeb, 0x2c0c, 0x8040, 0x0213, 0xef39, 0x96c0, 0x4217, 0x2c09, 0x8004, 0x5694, 0x5791, 0x3f20 }, 16, 0x000a7300, 1},
++	{{0x8000, 0xdf90, 0x3f8d, 0x8000, 0x66e9, 0x800f, 0x6468, 0x90c0, 0x96c3, 0x30e8, 0x3fff, 0xbfff, 0x98c0, 0xcb4f, 0x3264, 0x2400 }, 16, 0x000a7320, 1},
++	{{0x800a, 0x96c0, 0x7c6e, 0xfc42, 0xc84e, 0x94c0, 0xcb47, 0xc846, 0x90c0, 0x1110, 0xeb44, 0x3264, 0x2400, 0x800a, 0x2c31, 0x4013 }, 16, 0x000a7340, 1},
++	{{0x2464, 0xfcc2, 0x7570, 0x96c0, 0x35f9, 0x9fff, 0xec74, 0x5394, 0x37ef, 0x9fff, 0xdc9f, 0x4194, 0x5696, 0x3d1d, 0x8010, 0x66e9 }, 16, 0x000a7360, 1},
++	{{0x840d, 0x0017, 0x3164, 0x338c, 0x800a, 0x969d, 0x3452, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000a7380, 1},
++	{{0x96c0, 0x7651, 0xc386, 0xc297, 0x2c7c, 0x0024, 0x3540, 0x8009, 0x2669, 0x6c13, 0x94c1, 0xd094, 0x6d90, 0x94c3, 0x3303, 0x801e }, 16, 0x000a73a0, 1},
++	{{0x65e8, 0x90c0, 0x92c3, 0xc39f, 0x6ebd, 0x2c41, 0x3084, 0x2100, 0x800a, 0x6c90, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a73c0, 1},
++	{{0x98c0, 0x3121, 0x3554, 0x8009, 0xc394, 0x6893, 0x94c0, 0xc841, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a73e0, 1},
++	{{0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xc2b8, 0x3721, 0x35b0, 0x8009, 0x96c0, 0x6b92, 0xe748, 0xc94e }, 16, 0x000a7400, 1},
++	{{0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf241, 0xc847, 0x9cc0, 0x6e90, 0x6f90, 0x6c90, 0x6c10, 0xc847, 0xc946, 0x94c0, 0x6f10, 0x9746 }, 16, 0x000a7420, 1},
++	{{0x96c0, 0xc010, 0x280d, 0x8010, 0x94c0, 0xeced, 0x959d, 0x94c0, 0xed42, 0xec68, 0x0715, 0xc014, 0x96c0, 0x5319, 0x2d0d, 0x8002 }, 16, 0x000a7440, 1},
++	{{0x96c0, 0x4315, 0x2d08, 0x8004, 0x0310, 0xeae8, 0x1111, 0xea62, 0x0112, 0xe944, 0x96c0, 0x5709, 0x280c, 0x8002, 0x96c0, 0x4714 }, 16, 0x000a7460, 1},
++	{{0x2c0e, 0x8002, 0x96c0, 0x5111, 0x2e0b, 0x8002, 0x96c0, 0x4116, 0x2b09, 0x800c, 0x92d0, 0x461b, 0x4619, 0xe768, 0x94c0, 0x9e21 }, 16, 0x000a7480, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x7751, 0x9620, 0x9720, 0x96c0, 0x7f62, 0x9e20, 0x9f20 }, 16, 0x000a74a0, 1},
++	{{0x96c0, 0xe750, 0x2809, 0x801e, 0x98c0, 0x7f4f, 0xf643, 0x290d, 0x800c, 0x151d, 0xf642, 0x1019, 0xf6c2, 0x98c0, 0x2b03, 0x800c }, 16, 0x000a74c0, 1},
++	{{0x6b41, 0x9345, 0x76d6, 0x141d, 0xf542, 0x94d0, 0xf6c2, 0x5519, 0x6b55, 0x76d6, 0x96c0, 0x7f6f, 0xf542, 0xc110, 0x7676, 0x69b4 }, 16, 0x000a74e0, 1},
++	{{0x25e8, 0x65e1, 0x92c2, 0x6e90, 0x94c7, 0xd4c3, 0xc5ff, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd445, 0xc581, 0xf6c3, 0x98c6, 0x6abe }, 16, 0x000a7500, 1},
++	{{0xd445, 0x280f, 0x8008, 0x26e8, 0x26e1, 0xc010, 0x94c6, 0xc117, 0x6d10, 0x94c7, 0xd4c5, 0xc2ff, 0x1505, 0xa001, 0x90c0, 0x96c6 }, 16, 0x000a7520, 1},
++	{{0xd442, 0xc581, 0xf2cb, 0x96c6, 0x6569, 0xd445, 0xc695, 0x90c0, 0x98c1, 0xd392, 0xc595, 0xc595, 0x6d10, 0x96c7, 0xc38f, 0x3f02 }, 16, 0x000a7540, 1},
++	{{0x801e, 0x98c0, 0x2f0b, 0x8016, 0x6e7d, 0xc017, 0x98c0, 0x2b0e, 0x800c, 0x6fba, 0x561b, 0x96c0, 0x6f7d, 0xeaee, 0x9345, 0x98c0 }, 16, 0x000a7560, 1},
++	{{0xd617, 0x551a, 0x2b03, 0x801c, 0x2661, 0x7ecf, 0x7e48, 0x6665, 0x7e48, 0x765c, 0xd91c, 0x6a8a, 0x7eef, 0x051e, 0x551a, 0x94d0 }, 16, 0x000a7580, 1},
++	{{0x7ecf, 0x571b, 0x6a8b, 0x7eef, 0x96c0, 0x4516, 0x2f0a, 0x800a, 0x1412, 0xc84f, 0x3a41, 0xeeea, 0x3774, 0x2e10, 0x4412, 0x94c0 }, 16, 0x000a75a0, 1},
++	{{0xd72f, 0xc684, 0x96c0, 0x75d6, 0x2718, 0x814a, 0x2768, 0x4412, 0x94c6, 0xc110, 0x6d10, 0x32e4, 0x3d86, 0x8001, 0x94c7, 0x64e0 }, 16, 0x000a75c0, 1},
++	{{0xc2ff, 0x2768, 0x35d6, 0xc847, 0x92c2, 0x6d10, 0x94c7, 0xc010, 0xc2ff, 0x98c0, 0xc117, 0x32e4, 0x3d86, 0x8001, 0x64e0, 0x9ac0 }, 16, 0x000a75e0, 1},
++	{{0x7451, 0xc017, 0x3284, 0x20b0, 0x800a, 0x6461, 0x3750, 0xc847, 0x90c0, 0xc110, 0x3451, 0x3284, 0x20b0, 0x800a, 0x6461, 0x98c0 }, 16, 0x000a7600, 1},
++	{{0x2e0b, 0x800a, 0x6c02, 0xc847, 0x1513, 0xeaee, 0x32f6, 0xe9eb, 0x94c0, 0xe962, 0x8075, 0x1311, 0xe9ea, 0x31f0, 0xe962, 0x94c0 }, 16, 0x000a7620, 1},
++	{{0x93b9, 0x8067, 0x25e9, 0xedeb, 0x94c0, 0xed68, 0x8431, 0x1215, 0xc781, 0x3961, 0xeb66, 0x36f2, 0x4215, 0x66e8, 0x80ab, 0x9799 }, 16, 0x000a7640, 1},
++	{{0x5413, 0x4415, 0x0426, 0x3690, 0x8009, 0x3a41, 0x3064, 0x3706, 0x800a, 0x0422, 0x3690, 0x8009, 0xeb68, 0x96c0, 0x5313, 0x2b09 }, 16, 0x000a7660, 1},
++	{{0x8002, 0x3284, 0x20f0, 0x800a, 0x98c0, 0x3700, 0x8008, 0x5111, 0xcb4e, 0x94c0, 0xcb46, 0xc847, 0x98c0, 0xeaee, 0x3064, 0x3706 }, 16, 0x000a7680, 1},
++	{{0x800a, 0x4013, 0xe9ea, 0xe962, 0x90b9, 0xd021, 0x96c0, 0x8451, 0x157c, 0x9fd3, 0x66e9, 0x94c0, 0xf6cd, 0x8025, 0x96c0, 0x3d18 }, 16, 0x000a76a0, 1},
++	{{0x8010, 0xedeb, 0x2469, 0xed68, 0x94c0, 0x5515, 0x8413, 0xd6a2, 0x90c0, 0x92c2, 0xc682, 0x92c2, 0x4615, 0x2f90, 0xeceb, 0x94c0 }, 16, 0x000a76c0, 1},
++	{{0xec68, 0xeb64, 0x5214, 0x7961, 0x34f2, 0x4214, 0x64e8, 0x8019, 0x9799, 0x1413, 0x3064, 0x3706, 0x800a, 0x4414, 0xeb68, 0x2b09 }, 16, 0x000a76e0, 1},
++	{{0x8004, 0x5711, 0x4713, 0x2c10, 0x6c90, 0xc010, 0xc017, 0x9745, 0x9ac0, 0x2a0d, 0x800c, 0x90c0, 0x280f, 0x8028, 0x280c, 0x8026 }, 16, 0x000a7700, 1},
++	{{0x92d0, 0x560c, 0x460f, 0x94c0, 0xf6c3, 0xea62, 0x4615, 0x94c0, 0xe770, 0x90ba, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000a7720, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0 }, 16, 0x000a7740, 1},
++	{{0xe750, 0xc3b8, 0x98c0, 0x3721, 0x35b0, 0x8009, 0xeee9, 0x2b93, 0x33c4, 0x20c0, 0x800a, 0x96c0, 0xf5ce, 0x147c, 0x9fcf, 0x94c0 }, 16, 0x000a7760, 1},
++	{{0xf3cc, 0xc281, 0x1f90, 0xf208, 0x96c0, 0xf543, 0x047c, 0x9ffb, 0x94c0, 0xf341, 0xf195, 0x3264, 0x34b0, 0x800a, 0xc847, 0x9ac0 }, 16, 0x000a7780, 1},
++	{{0x6469, 0xe9ee, 0x3300, 0x2000, 0x8008, 0x94c0, 0x5791, 0x8043, 0xdd9f, 0x4391, 0x5597, 0x3b09, 0x8004, 0x64e9, 0x90c0, 0x94c3 }, 16, 0x000a77a0, 1},
++	{{0x0917, 0xa00c, 0x92c3, 0x4791, 0x1797, 0x5291, 0x3f3c, 0x8000, 0x6669, 0x90c0, 0x94c6, 0x8038, 0xf4cf, 0x92c2, 0xde1a, 0xf4cf }, 16, 0x000a77c0, 1},
++	{{0x98c0, 0xda04, 0x3064, 0x380c, 0x800a, 0xde02, 0x1491, 0x30f8, 0x3fff, 0xbff7, 0x9ac0, 0xdc04, 0x32f8, 0x3fff, 0xbff3, 0xf5cf }, 16, 0x000a77e0, 1},
++	{{0x96c0, 0xdd04, 0xda05, 0x4091, 0x0291, 0xde02, 0x96c0, 0xd323, 0x4491, 0xc0a8, 0x94c0, 0xcf4a, 0x8019, 0x96c0, 0xd442, 0x2300 }, 16, 0x000a7800, 1},
++	{{0x808c, 0x680e, 0xcc40, 0x90c0, 0x5714, 0xf708, 0x98c0, 0x3200, 0x2002, 0x8008, 0xf188, 0x96c0, 0xdd04, 0xef44, 0xe770, 0x9ac0 }, 16, 0x000a7820, 1},
++	{{0x3440, 0x8001, 0x5397, 0x3645, 0x8001, 0x3040, 0x8001, 0xd910, 0xd545, 0xdd1b, 0x4297, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a7840, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3321, 0x35b0, 0x8009, 0xc4b8, 0x6980, 0x94c0, 0xc843 }, 16, 0x000a7860, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9f20, 0xc39c, 0x98c0 }, 16, 0x000a7880, 1},
++	{{0x3721, 0x3704, 0x8009, 0xe748, 0x96c0, 0x6b93, 0xf341, 0xc94e, 0x32e4, 0x3c8a, 0x8001, 0xc847, 0x94c0, 0xc946, 0xca47, 0x94c0 }, 16, 0x000a78a0, 1},
++	{{0xc485, 0xc3fb, 0x96c0, 0x5219, 0x2a0d, 0x8002, 0x98c0, 0x2d08, 0x8008, 0x6564, 0x4415, 0x0212, 0xc081, 0x96c0, 0x4310, 0x280a }, 16, 0x000a78c0, 1},
++	{{0x8002, 0x0012, 0xedea, 0x10d9, 0xed66, 0x96c0, 0x4015, 0x2a0f, 0x8008, 0x13d1, 0x32c4, 0x20c0, 0x800a, 0x4317, 0x94c0, 0xef44 }, 16, 0x000a78e0, 1},
++	{{0xe768, 0x4897, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x98c0, 0x3621, 0x3704, 0x8009, 0xc79c }, 16, 0x000a7900, 1},
++	{{0x96c0, 0x6b03, 0x9e20, 0x9f20, 0x96c0, 0xcb46, 0x2709, 0x8028, 0x94c0, 0xe7e9, 0xc4a8, 0x9ac0, 0x2b0a, 0x8018, 0x90c0, 0x2500 }, 16, 0x000a7920, 1},
++	{{0x808c, 0x1e92, 0x31f8, 0x3fbf, 0xbfbf, 0x3378, 0x3fff, 0xbfff, 0x96c0, 0x5896, 0x2e0c, 0x8024, 0x1f94, 0xc84a, 0xd642, 0x3754 }, 16, 0x000a7940, 1},
++	{{0xcc44, 0x6b01, 0x96c0, 0xc846, 0x2c0e, 0x8292, 0x90c0, 0xe848, 0x3420, 0xa000, 0x5390, 0x3800, 0xaa04, 0x371d, 0x9000, 0xdc83 }, 16, 0x000a7960, 1},
++	{{0x3600, 0xa004, 0x66e9, 0x4190, 0x995a, 0x94c3, 0x0901, 0xa040, 0x94c3, 0x4190, 0xe96a, 0x3423, 0xa000, 0x5411, 0x3403, 0xa004 }, 16, 0x000a7980, 1},
++	{{0x7a41, 0x3423, 0xa000, 0x4411, 0x3820, 0xa000, 0x5090, 0x2809, 0x8070, 0x3600, 0xa804, 0x310a, 0x8020, 0x3400, 0xa004, 0x6569 }, 16, 0x000a79a0, 1},
++	{{0x9d5a, 0x3623, 0xa000, 0x0910, 0xa040, 0x3623, 0xa000, 0x4090, 0xed66, 0x3423, 0xa000, 0x5715, 0x3403, 0xa004, 0x7bc1, 0x3423 }, 16, 0x000a79c0, 1},
++	{{0xa000, 0x4715, 0x5790, 0xdd87, 0x4390, 0x1416, 0x5513, 0x96c0, 0x3614, 0x81ff, 0x5611, 0x801f, 0x7375, 0x9b5a, 0x94c3, 0x0983 }, 16, 0x000a79e0, 1},
++	{{0xa000, 0x94c3, 0x4390, 0xeb68, 0x92c3, 0x5013, 0x92c3, 0x7841, 0x92c3, 0x4013, 0x94c0, 0xcba4, 0xe9ec, 0xc183, 0xe93b, 0x1091 }, 16, 0x000a7a00, 1},
++	{{0xe9ea, 0x96c0, 0x3138, 0x8000, 0xe970, 0x2469, 0x1011, 0xc94e, 0x94c0, 0x7841, 0x8023, 0x94c0, 0xfa43, 0xf844, 0x3284, 0x2100 }, 16, 0x000a7a20, 1},
++	{{0x800a, 0xfc45, 0x94c0, 0xc946, 0xfac3, 0x94c0, 0xf8c4, 0xfcc5, 0x4011, 0x96c0, 0xebea, 0x2f09, 0x84aa, 0x11d1, 0xeb6c, 0x1313 }, 16, 0x000a7a40, 1},
++	{{0xfb46, 0x98c0, 0x79c1, 0xefea, 0x2400, 0x80cc, 0x3473, 0x0313, 0x0bc6, 0x2100, 0x8009, 0x96c0, 0x7071, 0xef70, 0xedea, 0x96c0 }, 16, 0x000a7a60, 1},
++	{{0x5317, 0x2718, 0x81dc, 0x98c0, 0x2b0b, 0x8090, 0x65e9, 0xed74, 0x96c0, 0x53d3, 0x290b, 0x806a, 0x94c7, 0xf342, 0xee6c, 0x92c3 }, 16, 0x000a7a80, 1},
++	{{0x5516, 0x92c3, 0xd59d, 0x92c3, 0xf342, 0xf0c2, 0x6c7c, 0x4413, 0x1715, 0x5217, 0x67e9, 0x841d, 0x6569, 0x94c0, 0x9e5a, 0x9b5a }, 16, 0x000a7aa0, 1},
++	{{0x92c3, 0x6e10, 0x94c3, 0xee6a, 0xeb66, 0x92c3, 0x4416, 0x92c3, 0x4413, 0x1415, 0xfa43, 0x96c0, 0x7a61, 0xf844, 0xfc45, 0x2c90 }, 16, 0x000a7ac0, 1},
++	{{0x3474, 0x0415, 0xf947, 0x3284, 0x2120, 0x800a, 0xfd48, 0x94c0, 0xfac3, 0xfdc8, 0xf9c7, 0x0015, 0xebea, 0x3600, 0xa100, 0xeb6e }, 16, 0x000a7ae0, 1},
++	{{0xe9ea, 0x3600, 0xa100, 0x5513, 0xe964, 0x3880, 0xa000, 0x7ae1, 0xeeea, 0xefea, 0x0513, 0xee66, 0x3680, 0xa000, 0x54d1, 0x5716 }, 16, 0x000a7b00, 1},
++	{{0x3a00, 0xa100, 0x3919, 0x80ff, 0x52d1, 0xeaea, 0x3880, 0xa100, 0x69a7, 0xef72, 0xea6a, 0x3820, 0xa100, 0x7173, 0xedea, 0xfa49 }, 16, 0x000a7b20, 1},
++	{{0x3607, 0xa100, 0x7e6c, 0xed76, 0x92c3, 0x7a43, 0x92c3, 0x4415, 0x3680, 0xa100, 0x56d7, 0x5712, 0x3d1d, 0x80ff, 0x2b3b, 0xc55f }, 16, 0x000a7b40, 1},
++	{{0x3176, 0xcb4e, 0x90c0, 0x92c3, 0x5113, 0x94c3, 0x3302, 0x8002, 0x92c3, 0x4213, 0x36a0, 0xa000, 0x5915, 0x5013, 0xc15b, 0x3dc1 }, 16, 0x000a7b60, 1},
++	{{0x3284, 0x20f0, 0x800a, 0x74f3, 0x96c0, 0x7650, 0xf8c4, 0xc557, 0x98c0, 0xcb46, 0x31f8, 0x3fff, 0xb7ff, 0x3600, 0xa100, 0x5390 }, 16, 0x000a7b80, 1},
++	{{0x5015, 0x9cc0, 0x375f, 0x8000, 0x6464, 0xdc83, 0xfdc8, 0xf9c7, 0x98c0, 0x67e9, 0x6c7c, 0xfac3, 0xfcc5, 0x90c0, 0x92c2, 0xc4fc }, 16, 0x000a7ba0, 1},
++	{{0x4413, 0x4190, 0x1413, 0xebea, 0x2668, 0xeb68, 0x90c0, 0x94c2, 0x0911, 0xa800, 0x92c2, 0x4190, 0x5490, 0x0914, 0xa001, 0x4490 }, 16, 0x000a7bc0, 1},
++	{{0x5115, 0x64e9, 0x90c0, 0x96c3, 0x31f8, 0x3fff, 0xbffe, 0x94c7, 0x8426, 0xdc84, 0x92c3, 0x4190, 0x1313, 0x50d1, 0x3705, 0x8005 }, 16, 0x000a7be0, 1},
++	{{0x7075, 0x90c0, 0x96c3, 0x30f8, 0x3fff, 0xbffe, 0x92c3, 0xdc04, 0x92c3, 0x4090, 0xcba0, 0x90c0, 0xec3b, 0x5794, 0x3f09, 0x8004 }, 16, 0x000a7c00, 1},
++	{{0x64e9, 0x90c0, 0x92c3, 0x5190, 0x94c3, 0x0911, 0xa001, 0x92c3, 0x4190, 0x5017, 0x3861, 0x3284, 0x2120, 0x800a, 0x6c90, 0x3820 }, 16, 0x000a7c20, 1},
++	{{0xa000, 0x6d10, 0xfac3, 0xfac9, 0x0017, 0xfbc6, 0xea68, 0x4213, 0x4212, 0x3480, 0xa000, 0x4212, 0x4216, 0x27e9, 0x9fd8, 0xe7e9 }, 16, 0x000a7c40, 1},
++	{{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x98c0, 0x3421, 0x3704, 0x8009, 0xc19c, 0x6a11, 0x94c0, 0xc844 }, 16, 0x000a7c60, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0 }, 16, 0x000a7c80, 1},
++	{{0xc5a4, 0x3721, 0x3758, 0x8009, 0x96c0, 0x6b81, 0xe748, 0xc94e, 0x98c0, 0xce40, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf541, 0xc847 }, 16, 0x000a7ca0, 1},
++	{{0x33c4, 0x20c0, 0x800a, 0x94c0, 0xcf47, 0xce48, 0x2469, 0xc946, 0x2f0b, 0x8020, 0x94c6, 0x4893, 0xc2a8, 0x94c6, 0x8019, 0x5190 }, 16, 0x000a7cc0, 1},
++	{{0x1190, 0xd021, 0x90c0, 0x9ac1, 0x2200, 0x8140, 0x90c0, 0x2200, 0x80b4, 0x98c0, 0xd541, 0x6f90, 0xeaeb, 0xedeb, 0x94c0, 0xea64 }, 16, 0x000a7ce0, 1},
++	{{0xed7e, 0x0292, 0xeceb, 0x1119, 0xec7a, 0x0117, 0xeeeb, 0x1611, 0xe944, 0x0615, 0xe8e9, 0x11d1, 0xe862, 0x0114, 0xee7c, 0x1410 }, 16, 0x000a7d00, 1},
++	{{0xedeb, 0x0416, 0xe942, 0x1619, 0xed76, 0x0615, 0xe8eb, 0x1319, 0xedeb, 0x94c0, 0xe874, 0xeeeb, 0x0310, 0xed70, 0x0715, 0xee6e }, 16, 0x000a7d20, 1},
++	{{0x0716, 0xeceb, 0x1519, 0xec72, 0x0514, 0xeeeb, 0x1511, 0xedeb, 0x94c0, 0xee68, 0xe768, 0x0516, 0xed6a, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a7d40, 1},
++	{{0x0715, 0xeb66, 0x4713, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x3e00, 0xa00c, 0x74d6, 0x7557, 0xc6a4, 0x3421, 0x3758, 0x8009 }, 16, 0x000a7d60, 1},
++	{{0x3a80, 0xa100, 0x6a02, 0x64e6, 0xe8ee, 0xcf48, 0x98c0, 0xcd44, 0x36d8, 0x33ff, 0xbfef, 0xc8a0, 0x2d0c, 0x8020, 0x1a94, 0xeeec }, 16, 0x000a7d80, 1},
++	{{0x94c0, 0xee64, 0xe9ec, 0x1f96, 0x5e92, 0x94c0, 0xe97a, 0xeaec, 0x94c0, 0xef48, 0xea6c, 0x96c0, 0x5397, 0x2f0b, 0x8042, 0x3880 }, 16, 0x000a7da0, 1},
++	{{0xa100, 0xdf03, 0xe9eb, 0xefec, 0x3600, 0xa100, 0x4697, 0xe938, 0x1713, 0x53d1, 0x3a00, 0xa100, 0x67e6, 0x371c, 0x800f, 0xef6e }, 16, 0x000a7dc0, 1},
++	{{0x3677, 0x998f, 0x90c0, 0x94c2, 0x0916, 0xa010, 0x92c2, 0x4697, 0x5315, 0x71f1, 0x90c0, 0x92c3, 0x5597, 0x94c3, 0x0925, 0xa000 }, 16, 0x000a7de0, 1},
++	{{0x92c3, 0x4597, 0x3600, 0xa100, 0x5312, 0x5111, 0x30f3, 0x1697, 0xeaec, 0x96c0, 0x841f, 0x0916, 0xa002, 0x0697, 0xea72, 0x5712 }, 16, 0x000a7e00, 1},
++	{{0x3f19, 0x8fff, 0x3a80, 0xa000, 0x4117, 0x3164, 0x3e56, 0x800a, 0xeaec, 0xea6e, 0x5212, 0x3961, 0xd520, 0x94c7, 0x4212, 0x6d90 }, 16, 0x000a7e20, 1},
++	{{0x98c3, 0x4312, 0x32f8, 0x3fff, 0xbffd, 0x92c3, 0x5697, 0x92c3, 0xdd06, 0x92c3, 0x4297, 0x3600, 0xa100, 0xeb5e, 0xefec, 0x3600 }, 16, 0x000a7e40, 1},
++	{{0xa100, 0xeaeb, 0xef7e, 0x1613, 0xea62, 0x3600, 0xa100, 0x5512, 0x5317, 0x3880, 0xa000, 0x6c9a, 0x5597, 0xeaec, 0x3880, 0xa100 }, 16, 0x000a7e60, 1},
++	{{0x71f1, 0xea72, 0xedec, 0x96c0, 0x8027, 0x0905, 0xb000, 0x3600, 0xa100, 0x4597, 0xed70, 0x3480, 0xa000, 0x5112, 0x3319, 0x8fff }, 16, 0x000a7e80, 1},
++	{{0x3a80, 0xa000, 0x4115, 0x3164, 0x3ee0, 0x800a, 0x3480, 0xa000, 0xecec, 0x3480, 0xa000, 0xec70, 0x3480, 0xa000, 0x5514, 0x3ae1 }, 16, 0x000a7ea0, 1},
++	{{0xd6a0, 0x3607, 0xa100, 0x6c90, 0x4514, 0x3883, 0xa000, 0x4114, 0x23e0, 0x8fff, 0x92c3, 0x5297, 0x92c3, 0xdd82, 0x92c3, 0x4397 }, 16, 0x000a7ec0, 1},
++	{{0x3680, 0xa000, 0xecec, 0x5213, 0x3680, 0xa000, 0xec68, 0x5712, 0x3880, 0xa100, 0x6f2b, 0x5314, 0xecec, 0x3880, 0xa000, 0x71f6 }, 16, 0x000a7ee0, 1},
++	{{0x5697, 0xec72, 0x96c0, 0x8029, 0x0916, 0xa020, 0x3600, 0xa100, 0x4697, 0xeeec, 0x3680, 0xa100, 0x5514, 0xee6a, 0x3b1e, 0x8fff }, 16, 0x000a7f00, 1},
++	{{0x3a80, 0xa000, 0x4616, 0x3164, 0x3f62, 0x800a, 0x3480, 0xa000, 0xebec, 0x3480, 0xa000, 0xeb6a, 0x3480, 0xa000, 0x5313, 0x39e1 }, 16, 0x000a7f20, 1},
++	{{0xd5a0, 0x3607, 0xa100, 0x6c90, 0x4313, 0x3a83, 0xa000, 0x4113, 0x32f8, 0x3fff, 0xbfdf, 0x92c3, 0x5397, 0x92c3, 0xdd03, 0x92c3 }, 16, 0x000a7f40, 1},
++	{{0x4297, 0x3680, 0xa000, 0xe9ec, 0x5312, 0x3600, 0xa100, 0x5613, 0xe97c, 0x3600, 0xa100, 0x6d8e, 0x5511, 0x72f3, 0x90c0, 0x92c3 }, 16, 0x000a7f60, 1},
++	{{0x5397, 0x94c3, 0x0903, 0xa800, 0x92c3, 0x4397, 0x1397, 0x51d1, 0x9ac0, 0x371e, 0x9000, 0x7ce4, 0x370d, 0x8010, 0x6769, 0x8427 }, 16, 0x000a7f80, 1},
++	{{0x26e9, 0xeaec, 0x94c0, 0xea78, 0x8421, 0x5112, 0x3751, 0x78e1, 0x676c, 0x96c0, 0x8425, 0x0903, 0xa400, 0x0112, 0x3064, 0x3fd6 }, 16, 0x000a7fa0, 1},
++	{{0x800a, 0x4397, 0x9ac0, 0x331a, 0x8fff, 0xeaec, 0x0903, 0xa400, 0xea78, 0x4212, 0x4397, 0x1296, 0xee44, 0x96c0, 0x3509, 0x8002 }, 16, 0x000a7fc0, 1},
++	{{0x5796, 0x96c0, 0x64e9, 0x3f1a, 0x8004, 0x848b, 0x96c0, 0x6569, 0x3f1d, 0x8008, 0x8481, 0x26e9, 0xee44, 0x94c0, 0x5296, 0x847b }, 16, 0x000a7fe0, 1},
++	{{0x96c0, 0x351d, 0x8002, 0x5397, 0x96c0, 0x66e9, 0x371f, 0x8002, 0x8465, 0x98c0, 0x67e9, 0x375a, 0x8000, 0xebec, 0x94c0, 0xeb76 }, 16, 0x000a8000, 1},
++	{{0x8459, 0x2569, 0x5e13, 0xce4a, 0x94c0, 0x7d41, 0x804e, 0x3578, 0x9e00, 0x371a, 0x8800, 0x96c0, 0x6569, 0x379a, 0x8000, 0x842f }, 16, 0x000a8020, 1},
++	{{0x98c0, 0x6569, 0x371f, 0x8400, 0xd41c, 0x8423, 0x67e9, 0x90c0, 0x92c3, 0xec74, 0x92c3, 0x5114, 0x92c3, 0x68b1, 0x92c3, 0x7cef }, 16, 0x000a8040, 1},
++	{{0x98c0, 0xd059, 0x3084, 0x2076, 0x800a, 0x7470, 0x2c10, 0x3184, 0x2076, 0x800a, 0x6c10, 0x3ac0, 0xb800, 0x77d2, 0x7751, 0xcf40 }, 16, 0x000a8060, 1},
++	{{0xeee8, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3321, 0x3758, 0x8009, 0xc4a4, 0x6980, 0x94c0, 0xc843 }, 16, 0x000a8080, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x2468, 0x74d0, 0x842e, 0x92c3, 0xc0ff, 0x96c0, 0x64e9, 0xd211 }, 16, 0x000a80a0, 1},
++	{{0xc283, 0x96c6, 0x7a61, 0x6c10, 0x8021, 0xd011, 0x3105, 0x801e, 0x2d89, 0x7ec3, 0x7473, 0x6c7c, 0xd49c, 0x64e5, 0x3318, 0x8007 }, 16, 0x000a80c0, 1},
++	{{0xdc1d, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x7651, 0x94c0, 0x6c7d, 0x9f70, 0x7454, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a80e0, 1},
++	{{0x7071, 0x94c0, 0xd0d8, 0x9f70, 0x7471, 0x90c0, 0x90c0, 0x90c0, 0x76d0, 0x94c0, 0x6d7c, 0x9f70, 0x7455, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8100, 1},
++	{{0x7071, 0x94c0, 0xd059, 0x9f70, 0x7470, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6d10, 0x6c10, 0xc48f, 0xc3ff, 0x0222, 0x37c4, 0x8009 }, 16, 0x000a8120, 1},
++	{{0x0422, 0x37d0, 0x8009, 0x98c0, 0x0322, 0x37cc, 0x8009, 0x9f70, 0x0022, 0x37c8, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8140, 1},
++	{{0x3a00, 0xa008, 0x7751, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xc281, 0xe748, 0x3c40, 0xa000, 0x6e7c, 0xf641 }, 16, 0x000a8160, 1},
++	{{0x3284, 0x20b0, 0x800a, 0x7456, 0x35d0, 0x2f90, 0x2e90, 0x3656, 0x3f60, 0x2a30, 0x8008, 0x3640, 0xa000, 0x7de3, 0xf6c1, 0x3600 }, 16, 0x000a8180, 1},
++	{{0xb000, 0x79ee, 0x7456, 0x96c0, 0x3701, 0x800b, 0x6f7c, 0x2d7c, 0xd71f, 0x6cbb, 0xd619, 0xd61f, 0x7a61, 0x7e41, 0xce44, 0x90c0 }, 16, 0x000a81a0, 1},
++	{{0xee1f, 0x1416, 0xce41, 0x69b6, 0x65e6, 0xd599, 0x65e4, 0x9ac0, 0x377d, 0x9fff, 0x90c0, 0x379b, 0x8000, 0x25e9, 0x6935, 0x94c7 }, 16, 0x000a81c0, 1},
++	{{0x6566, 0x7e4f, 0x92c3, 0xd544, 0x3542, 0x8000, 0x7d6f, 0x75f2, 0x6b2e, 0x6766, 0xd719, 0x6764, 0x3d7c, 0x9fff, 0x96c0, 0x3d9c }, 16, 0x000a81e0, 1},
++	{{0x8000, 0x6b28, 0x2669, 0x6766, 0x92c3, 0x7d4f, 0x92c3, 0xd742, 0x3d46, 0x8000, 0x3284, 0x20b0, 0x800a, 0x7f6f, 0x3a20, 0xa000 }, 16, 0x000a8200, 1},
++	{{0x7650, 0x6c10, 0xf6c1, 0xf391, 0x3e63, 0xce49, 0x7a6e, 0x6c7c, 0x3600, 0xa004, 0xd71c, 0x6664, 0x3800, 0xa200, 0x3900, 0x800f }, 16, 0x000a8220, 1},
++	{{0x7576, 0x2f33, 0x682a, 0x6768, 0x94c6, 0xd741, 0xd41e, 0x94c6, 0x8024, 0xd419, 0x92c2, 0xd41f, 0x6768, 0x96c6, 0xd747, 0xd41e }, 16, 0x000a8240, 1},
++	{{0x8018, 0x92c2, 0xd41f, 0x6768, 0x94c1, 0x6764, 0xd41e, 0x92c3, 0xd416, 0x2461, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a8260, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x1099, 0xe748 }, 16, 0x000a8280, 1},
++	{{0x98c0, 0xefe8, 0x32a4, 0x2970, 0x800a, 0x94c0, 0xc18d, 0xeee9, 0x96c0, 0x77d0, 0xe9ee, 0xc18d, 0x3fc8, 0x5099, 0x27e5, 0xeee9 }, 16, 0x000a82a0, 1},
++	{{0x3fc8, 0x32a4, 0x2970, 0x800a, 0x77df, 0x98c0, 0x7c48, 0xd99f, 0xe8ef, 0xe9ee, 0x98c0, 0x6465, 0x6975, 0x2600, 0x807f, 0x3c48 }, 16, 0x000a82c0, 1},
++	{{0x4298, 0x7458, 0xd998, 0x6875, 0xf041, 0x1099, 0xc18d, 0x32a4, 0x2970, 0x800a, 0x94c0, 0xeee9, 0xefe8, 0x96c0, 0x77d0, 0xe9ee }, 16, 0x000a82e0, 1},
++	{{0xc18d, 0x3fc8, 0x5099, 0x27e5, 0xeee9, 0x3fc8, 0x32a4, 0x2970, 0x800a, 0x77df, 0x9ac0, 0x7c48, 0xda1f, 0x7b61, 0xe8ef, 0xe9ee }, 16, 0x000a8300, 1},
++	{{0x2465, 0x2ab4, 0x676a, 0x7c48, 0x7458, 0xdb98, 0x69f7, 0x94c0, 0x6ccd, 0x81bc, 0x4198, 0x94c0, 0xf0c1, 0xe768, 0x94c0, 0x9e21 }, 16, 0x000a8320, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4090, 0x90c0, 0x90c0, 0x3a00, 0xa008, 0x7556, 0x7457, 0x5090, 0x5151, 0x98c0, 0x6374 }, 16, 0x000a8340, 1},
++	{{0x9342, 0x2b03, 0x8020, 0x3880, 0xa100, 0x6f74, 0xe8ee, 0xe9ef, 0x4698, 0x3480, 0xa000, 0xeee8, 0xe844, 0xebe8, 0x109b, 0x5151 }, 16, 0x000a8360, 1},
++	{{0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x9346, 0x2b03, 0x800a, 0xe942, 0x1151, 0x5090, 0x63f4, 0x6ff4, 0x4798, 0x1151, 0x5090 }, 16, 0x000a8380, 1},
++	{{0x6374, 0x6f74, 0x4698, 0x1151, 0x5090, 0x62f4, 0x6ef4, 0x4598, 0x1090, 0x5159, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x9346 }, 16, 0x000a83a0, 1},
++	{{0x2b03, 0x800a, 0xeae8, 0x109a, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x9346, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xeae8 }, 16, 0x000a83c0, 1},
++	{{0x109a, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x9346, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xebe8, 0x109b, 0x5151, 0x92d0 }, 16, 0x000a83e0, 1},
++	{{0x61f4, 0x6df4, 0x4398, 0x96c0, 0x9348, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xede8, 0x109d, 0x5151, 0x92d0, 0x62f4, 0x6ef4, 0x4598 }, 16, 0x000a8400, 1},
++	{{0x96c0, 0x9348, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xefe8, 0x90c0, 0x109f, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x934a }, 16, 0x000a8420, 1},
++	{{0x2b03, 0x800e, 0x94c0, 0xe942, 0xede8, 0x109d, 0x5151, 0x92d0, 0x61f4, 0x6df4, 0x4398, 0x96c0, 0x934c, 0x2b03, 0x800e, 0x94c0 }, 16, 0x000a8440, 1},
++	{{0xe942, 0xece8, 0x109c, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x934e, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xefe8, 0x90c0 }, 16, 0x000a8460, 1},
++	{{0x109f, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x934e, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xebe8, 0x109b, 0x5151, 0x92d0 }, 16, 0x000a8480, 1},
++	{{0x6374, 0x6f74, 0x4698, 0x96c0, 0x9350, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xece8, 0x109c, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498 }, 16, 0x000a84a0, 1},
++	{{0x96c0, 0x9352, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xede8, 0x90c0, 0x109d, 0x5151, 0x92d0, 0x62f4, 0x6ef4, 0x4598, 0x96c0, 0x9356 }, 16, 0x000a84c0, 1},
++	{{0x2b03, 0x800e, 0x94c0, 0xe942, 0xece8, 0x109c, 0x5151, 0x92d0, 0x62f4, 0x6ef4, 0x4598, 0x96c0, 0x9358, 0x2b03, 0x800e, 0x94c0 }, 16, 0x000a84e0, 1},
++	{{0xe942, 0xeee8, 0x109e, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x935e, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xede8, 0x90c0 }, 16, 0x000a8500, 1},
++	{{0x109d, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x9362, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xeee8, 0x109e, 0x5151, 0x92d0 }, 16, 0x000a8520, 1},
++	{{0x6274, 0x6e74, 0x4498, 0x3800, 0xa100, 0x7752, 0x5096, 0x5151, 0x3860, 0xa000, 0x63f4, 0xefe9, 0xeee8, 0x94c0, 0x6ff4, 0x9f70 }, 16, 0x000a8540, 1},
++	{{0x3600, 0xa900, 0x77d0, 0x4796, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0xc56b, 0x1005, 0xa004, 0x90c0, 0x3c20, 0xa000, 0x6c10, 0x3a20 }, 16, 0x000a8560, 1},
++	{{0x37d4, 0x8009, 0x5298, 0x96c0, 0x9354, 0x2b03, 0x803e, 0x559a, 0x3c00, 0xa060, 0x3a41, 0x8005, 0x90c0, 0x3644, 0x8005, 0x3a20 }, 16, 0x000a8580, 1},
++	{{0xa040, 0x3841, 0x8005, 0x5298, 0x559a, 0x3800, 0xa080, 0xd911, 0x3a41, 0x8005, 0x3c00, 0xa060, 0x3644, 0x8005, 0xd544, 0x3841 }, 16, 0x000a85a0, 1},
++	{{0x8005, 0x6561, 0x3a30, 0xa000, 0x74d2, 0xd911, 0x5698, 0x559a, 0x3e00, 0xa060, 0x3ac1, 0x8005, 0xd544, 0x36c4, 0x8005, 0x6c51 }, 16, 0x000a85c0, 1},
++	{{0x3800, 0xa040, 0x38c1, 0x8005, 0x6561, 0x36d2, 0xd911, 0x2c41, 0xd544, 0x6561, 0x6c52, 0x6465, 0xc563, 0x90c0, 0x90c0, 0x9f71 }, 16, 0x000a85e0, 1},
++	{{0x3600, 0xa00c, 0x75d7, 0x7456, 0x3420, 0xa000, 0xc56a, 0x1005, 0xa004, 0x90c0, 0x96c0, 0x9347, 0x2b03, 0x800a, 0xc781, 0x5198 }, 16, 0x000a8600, 1},
++	{{0x5298, 0x6cd8, 0x92d0, 0xd49f, 0x64e5, 0x4199, 0x96c0, 0x9243, 0x2a03, 0x8012, 0x3660, 0xa000, 0xc682, 0xc184, 0xc185, 0x5698 }, 16, 0x000a8620, 1},
++	{{0x5098, 0x2ec2, 0x5298, 0x6c49, 0x3750, 0x36d0, 0x7550, 0x3800, 0xb800, 0xd71e, 0xd699, 0xd519, 0x6f22, 0x6e9a, 0x6e89, 0x92d0 }, 16, 0x000a8640, 1},
++	{{0xd69f, 0x66e5, 0x4599, 0x5698, 0x94c0, 0x5098, 0x9742, 0x2f42, 0x5298, 0x2d4a, 0x5398, 0x6e5d, 0x3400, 0xa800, 0xd61e, 0x6665 }, 16, 0x000a8660, 1},
++	{{0x4499, 0x5498, 0x5098, 0x2d40, 0x5398, 0x2c5d, 0x5698, 0x6ec2, 0x3400, 0xa800, 0xd69e, 0x66e5, 0x4599, 0x5298, 0x5098, 0x36d0 }, 16, 0x000a8680, 1},
++	{{0x5098, 0x96c8, 0x6d49, 0x76d0, 0x5098, 0x94c0, 0x6d49, 0x9743, 0x6d52, 0x3752, 0x3452, 0x7652, 0x3800, 0xb000, 0xd71f, 0xd419 }, 16, 0x000a86a0, 1},
++	{{0xd619, 0x6d2a, 0x6f12, 0x6e16, 0xd61f, 0x6665, 0x4499, 0x5098, 0x5698, 0x35d6, 0x5698, 0x96c8, 0x6c53, 0x75d6, 0x5698, 0x94c0 }, 16, 0x000a86c0, 1},
++	{{0x6c53, 0x9744, 0x6c42, 0x3750, 0x3550, 0x7650, 0x3800, 0xb800, 0xd71e, 0xd519, 0x7e66, 0x6c22, 0x6f32, 0x6e16, 0x3400, 0xa800 }, 16, 0x000a86e0, 1},
++	{{0xd61e, 0x6665, 0x4499, 0x5498, 0x5698, 0x36d6, 0x5698, 0x96c8, 0x6e55, 0x76d6, 0x5698, 0x94c0, 0x6e55, 0x9744, 0x2e56, 0xc683 }, 16, 0x000a8700, 1},
++	{{0x36d4, 0x35d4, 0x7454, 0x3800, 0xaa00, 0xd69e, 0x7de3, 0xd419, 0x6eb5, 0x6d8d, 0x6c13, 0x3400, 0xa800, 0xd41e, 0x6465, 0x4099 }, 16, 0x000a8720, 1},
++	{{0x5098, 0x5498, 0x36d4, 0x5498, 0x96c8, 0x6c41, 0x76d4, 0x5498, 0x94c0, 0x6c41, 0x9745, 0x6c40, 0x36d0, 0x3650, 0x75d0, 0x3800 }, 16, 0x000a8740, 1},
++	{{0xaa00, 0xd69e, 0xd61e, 0xd599, 0x6d21, 0x6c28, 0x6db3, 0x3400, 0xa800, 0xd59e, 0x65e5, 0x4399, 0x5098, 0x5598, 0x35d5, 0x5598 }, 16, 0x000a8760, 1},
++	{{0x96c8, 0x6c53, 0x75d5, 0x5598, 0x94c0, 0x6c53, 0x9746, 0x6c41, 0xd41e, 0x6465, 0x4099, 0x5498, 0x5398, 0x3553, 0x5398, 0x96c8 }, 16, 0x000a8780, 1},
++	{{0x6e48, 0x7553, 0x5398, 0x94c0, 0x6e48, 0x9748, 0x2e4c, 0xc287, 0x35d4, 0x36d4, 0x7454, 0x3800, 0xb000, 0xd59f, 0xd699, 0x7c67 }, 16, 0x000a87a0, 1},
++	{{0x6d8c, 0x6ead, 0x6c41, 0x3400, 0xa800, 0xd41e, 0x6465, 0x4099, 0x5498, 0x5398, 0x36d3, 0x5398, 0x96c8, 0x6e55, 0x76d3, 0x5398 }, 16, 0x000a87c0, 1},
++	{{0x94c0, 0x6e55, 0x9749, 0x6e4c, 0x7454, 0x3550, 0x35d0, 0xd41a, 0x94c0, 0xd51f, 0xd59e, 0x6d08, 0x6ebd, 0x6c01, 0x3400, 0xa800 }, 16, 0x000a87e0, 1},
++	{{0xd41e, 0x6465, 0x4099, 0x5498, 0x5298, 0x3452, 0x5298, 0x96c8, 0x6e40, 0x7452, 0x5298, 0x94c0, 0x6e40, 0x974c, 0x6e48, 0x35d4 }, 16, 0x000a8800, 1},
++	{{0x3554, 0x7454, 0x3800, 0xb800, 0xd59e, 0xd519, 0xd419, 0x6d8c, 0x6d9d, 0x6d93, 0xd59e, 0x65e5, 0x4399, 0x5498, 0x5098, 0x36d0 }, 16, 0x000a8820, 1},
++	{{0x5098, 0x96c8, 0x6e55, 0x76d0, 0x5098, 0x94c0, 0x6e55, 0x974e, 0x2e40, 0xc389, 0x3454, 0x3554, 0x76d4, 0x96c0, 0xd41f, 0xd519 }, 16, 0x000a8840, 1},
++	{{0x7ee9, 0x6e00, 0x6e48, 0x6ed5, 0xd69e, 0x66e5, 0x4599, 0x5498, 0x5098, 0x34d0, 0x5098, 0x96c8, 0x6e44, 0x74d0, 0x5098, 0x6e44 }, 16, 0x000a8860, 1},
++	{{0x6e40, 0x3554, 0x3454, 0x74d4, 0x3800, 0xa800, 0xd519, 0xd41b, 0x7cea, 0x6e88, 0x6f41, 0x6dc6, 0x3400, 0xa800, 0xd599, 0x65e5 }, 16, 0x000a8880, 1},
++	{{0x4391, 0x3420, 0xa000, 0xc562, 0x90c0, 0x90c0, 0x9f70, 0x3600, 0xb800, 0x7750, 0x77d3, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a88a0, 1},
++	{{0x3c00, 0xa108, 0x75d6, 0x7457, 0x5191, 0x2908, 0x8004, 0x96c0, 0x4190, 0x2304, 0x807f, 0x3c00, 0xa100, 0x2b03, 0x805a, 0x90c0 }, 16, 0x000a88c0, 1},
++	{{0x280f, 0x8400, 0x3680, 0xa100, 0x5190, 0xebef, 0x3880, 0xa000, 0xeaee, 0x280c, 0x8008, 0x9ac0, 0x280f, 0x8408, 0x90c0, 0x280d }, 16, 0x000a88e0, 1},
++	{{0x840c, 0x3680, 0xa000, 0x4197, 0xe84c, 0x3c00, 0xa100, 0x290a, 0x8008, 0x90c0, 0x2909, 0x800c, 0x9ac0, 0x290e, 0x87f8, 0x90c0 }, 16, 0x000a8900, 1},
++	{{0x290b, 0x87fc, 0x9ac0, 0x2ae2, 0x9ffe, 0x90c0, 0x2b02, 0x8002, 0x1496, 0x5292, 0x6f48, 0x76c6, 0x45bc, 0x11b6, 0x52ba, 0x6eb8 }, 16, 0x000a8920, 1},
++	{{0x7545, 0x42bd, 0x3680, 0xa000, 0x5791, 0x5593, 0x6f9b, 0x7447, 0x40b8, 0x3680, 0xa000, 0x57b9, 0x54b3, 0x92d0, 0x6fd7, 0x74c7 }, 16, 0x000a8940, 1},
++	{{0x41bf, 0x3a40, 0xa200, 0x2e00, 0x83fc, 0x77d0, 0xeaef, 0x38c0, 0xa000, 0xef44, 0x2809, 0x83fc, 0x1599, 0xea3e, 0x3640, 0xa000 }, 16, 0x000a8960, 1},
++	{{0x4592, 0xefeb, 0x3640, 0xa000, 0x5691, 0xeeea, 0x9f70, 0x3600, 0xa100, 0x7753, 0x4697, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8980, 1},
++	{{0x3e80, 0xa004, 0x74d7, 0x6f90, 0x6c90, 0xfcc3, 0x2808, 0x8004, 0x3c00, 0xa001, 0x2304, 0x807f, 0x7456, 0x2b03, 0x8070, 0x3800 }, 16, 0x000a89a0, 1},
++	{{0xa100, 0x5294, 0x2c0e, 0x8004, 0x3800, 0xa100, 0x4290, 0x290d, 0x8004, 0x3680, 0xa100, 0x4790, 0xeaef, 0x3680, 0xa100, 0x5396 }, 16, 0x000a89c0, 1},
++	{{0xe9ee, 0x96c0, 0x4391, 0x290e, 0x8008, 0x9ac0, 0x280d, 0x8008, 0x90c0, 0x2c0f, 0x8008, 0x9ac0, 0x2c0b, 0x87fc, 0x90c0, 0x2c0a }, 16, 0x000a89e0, 1},
++	{{0x800c, 0x3680, 0xa000, 0x4195, 0xe84c, 0x96c0, 0xe94c, 0x2c0c, 0x87f8, 0x9cc0, 0x2ae2, 0x9ffe, 0x90c0, 0x2b02, 0x8002, 0x90c0 }, 16, 0x000a8a00, 1},
++	{{0x1397, 0x5194, 0x6ed9, 0x75c5, 0x43bd, 0x16b4, 0x51bf, 0x6c06, 0x76c0, 0x45b9, 0x1493, 0x5092, 0x6e20, 0x7444, 0x40b8, 0x13ba }, 16, 0x000a8a20, 1},
++	{{0x52b3, 0x92d0, 0x6e5d, 0x7444, 0x40be, 0x3e60, 0xa000, 0x6d10, 0x2e09, 0x83fc, 0x6f10, 0x280a, 0x83fc, 0x3a20, 0xa800, 0x77d1 }, 16, 0x000a8a40, 1},
++	{{0x5599, 0x2d0d, 0x83fc, 0x3640, 0xa000, 0x459a, 0xefea, 0x3640, 0xa000, 0x4292, 0xeee9, 0x5091, 0x94c0, 0x409d, 0x9f70, 0x3600 }, 16, 0x000a8a60, 1},
++	{{0xa800, 0x7750, 0x4695, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3c00, 0xa10c, 0x74d7, 0x7456, 0x5791, 0x290b, 0x8400, 0x96c0 }, 16, 0x000a8a80, 1},
++	{{0x4790, 0x2304, 0x807f, 0x3c00, 0xa100, 0x2b03, 0x805a, 0x90c0, 0x2808, 0x8004, 0x3680, 0xa100, 0x5593, 0xeaef, 0x3880, 0xa000 }, 16, 0x000a8aa0, 1},
++	{{0xe9ee, 0x280b, 0x8008, 0x3c00, 0xa100, 0x280f, 0x87f8, 0x90c0, 0x280c, 0x87fc, 0x3880, 0xa000, 0x4590, 0x290c, 0x8008, 0x96c0 }, 16, 0x000a8ac0, 1},
++	{{0xe84c, 0x290d, 0x800c, 0x9ac0, 0x290e, 0x8408, 0x90c0, 0x290a, 0x840c, 0x9cc0, 0x2ae2, 0x9ffe, 0x90c0, 0x2b02, 0x8002, 0x90c0 }, 16, 0x000a8ae0, 1},
++	{{0x1096, 0x5695, 0x6e22, 0x3480, 0xa000, 0x44b4, 0x1394, 0x5492, 0x6ecc, 0x45b7, 0x13bc, 0x51ba, 0x6e99, 0x45bb, 0x94d0, 0x52be }, 16, 0x000a8b00, 1},
++	{{0x50bd, 0x6dd2, 0x43b8, 0x3c20, 0xac00, 0x7750, 0x2a00, 0x83fc, 0x77d1, 0xedeb, 0x38c0, 0xa000, 0xeb44, 0x280e, 0x83fc, 0x3640 }, 16, 0x000a8b20, 1},
++	{{0xa000, 0xed3a, 0xefea, 0x5195, 0x419e, 0x3480, 0xa000, 0x5493, 0x94c0, 0x4496, 0x9f70, 0x3420, 0xa000, 0xeee9, 0x90c0, 0x90c0 }, 16, 0x000a8b40, 1},
++	{{0x3550, 0x3451, 0x03fc, 0x9ff6, 0x9ac0, 0xda9b, 0x6275, 0x3181, 0x2000, 0x8000, 0x34f9, 0x6e75, 0x6ea5, 0xd895, 0x61f4, 0x94c0 }, 16, 0x000a8b60, 1},
++	{{0x6df4, 0x9f70, 0x6c4c, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x2809, 0x850c, 0x6e10, 0xcca0, 0x96c0, 0x5891, 0x290a }, 16, 0x000a8b80, 1},
++	{{0x8084, 0x98c0, 0x3b20, 0x383a, 0x8009, 0x9347, 0x96c0, 0x4198, 0x2b03, 0x8034, 0x98c0, 0xea88, 0x30e8, 0x3fff, 0xbfff, 0x985a }, 16, 0x000a8ba0, 1},
++	{{0x92c3, 0xcca0, 0x90c0, 0x92c3, 0xe83c, 0x4891, 0x1298, 0x534b, 0x20f5, 0xea88, 0x94c0, 0x6cf5, 0x985a, 0xd641, 0x92c3, 0xe83c }, 16, 0x000a8bc0, 1},
++	{{0x2c7d, 0x1298, 0x534b, 0x20f5, 0xea88, 0x94d0, 0x6cf5, 0x985a, 0xd641, 0x92c3, 0xe83c, 0x94c0, 0x6c7d, 0x9f70, 0x7454, 0x90c0 }, 16, 0x000a8be0, 1},
++	{{0x98c0, 0x2808, 0x850c, 0x6d10, 0x9748, 0x280c, 0x8064, 0x4c90, 0x92c8, 0x429c, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8c00, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe750, 0xc596, 0x9cc0, 0x3f60, 0x2ab8, 0x8008, 0xc782, 0x90c0, 0x90c0 }, 16, 0x000a8c20, 1},
++	{{0x96c0, 0x6f10, 0xc485, 0xf941, 0x96c0, 0xce44, 0xf542, 0x90c0, 0x3284, 0x2110, 0x800a, 0x2c90, 0x3457, 0xf843, 0x3284, 0x20f0 }, 16, 0x000a8c40, 1},
++	{{0x800a, 0xc195, 0x96c0, 0x7be1, 0xcc40, 0xf8c3, 0x111f, 0xce4b, 0x39e1, 0xecfc, 0x96c0, 0x65ea, 0xec18, 0xce43, 0x5214, 0x6a38 }, 16, 0x000a8c60, 1},
++	{{0x94c0, 0x7e6f, 0x81d0, 0xd744, 0x98c0, 0x7446, 0x7bc6, 0xf5c2, 0xf9c1, 0x3ae1, 0xef6a, 0x26ea, 0x4019, 0x81a7, 0xe770, 0x94c0 }, 16, 0x000a8c80, 1},
++	{{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x3880, 0xa100, 0xe8e8, 0x280a, 0x8590, 0x94c0, 0x9620, 0x9720 }, 16, 0x000a8ca0, 1},
++	{{0x3480, 0xa000, 0x56d2, 0x98c0, 0x3d1d, 0x8001, 0x9e20, 0x9f20, 0x96c0, 0x66e9, 0x270e, 0x8130, 0x96c0, 0xe7ee, 0x2518, 0x9bd6 }, 16, 0x000a8cc0, 1},
++	{{0x32c4, 0x20c0, 0x800a, 0x3660, 0xa000, 0xf845, 0xfa46, 0x3620, 0xa000, 0xfac6, 0xcf84, 0x3640, 0xa000, 0xff47, 0xf8c5, 0x36a0 }, 16, 0x000a8ce0, 1},
++	{{0xa000, 0x2a0e, 0x9e38, 0x3a80, 0xa000, 0x5cd6, 0x3e20, 0x3c48, 0x8009, 0x90c0, 0xec8f, 0x96c0, 0xecfe, 0x2518, 0x9b98, 0x98c0 }, 16, 0x000a8d00, 1},
++	{{0x6e90, 0xec1e, 0x2502, 0x9600, 0x3640, 0xa000, 0x5f94, 0xeeee, 0x3a20, 0xa000, 0xee3d, 0x31c1, 0x2000, 0x800c, 0x94c0, 0xedee }, 16, 0x000a8d20, 1},
++	{{0x9f61, 0x96c0, 0xffc7, 0x2304, 0x8080, 0x9ac0, 0x2b03, 0x8026, 0x90c0, 0x2000, 0x8080, 0x98c0, 0xef1e, 0x0142, 0x2e78, 0x8009 }, 16, 0x000a8d40, 1},
++	{{0x94c0, 0xff47, 0xc684, 0x98c0, 0x2b02, 0x8002, 0x90c0, 0x90c0, 0x9ac0, 0x7ad0, 0x0b46, 0x2e78, 0x8009, 0xca45, 0x3b50, 0xcc46 }, 16, 0x000a8d60, 1},
++	{{0xeb1a, 0x5493, 0x44bd, 0x0946, 0x2e78, 0x8009, 0x90c0, 0x92d0, 0xe91c, 0x5491, 0x44bf, 0x96c0, 0x9b40, 0x2b03, 0x802a, 0x3c60 }, 16, 0x000a8d80, 1},
++	{{0xa000, 0x280b, 0x91cc, 0x90c0, 0x280a, 0x91c8, 0x94c0, 0xc08c, 0xc288, 0x9cc0, 0x2b02, 0x8002, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8da0, 1},
++	{{0x9ac0, 0x7950, 0xc942, 0x0c46, 0x2e78, 0x8009, 0x3850, 0xc840, 0xec19, 0x5794, 0x47ba, 0x0946, 0x2e78, 0x8009, 0x90c0, 0x92d0 }, 16, 0x000a8dc0, 1},
++	{{0xe918, 0x5391, 0x43bb, 0x3820, 0xa000, 0xe8ee, 0x2d00, 0x9e00, 0x3640, 0xa000, 0xe9ee, 0xfe49, 0x98c0, 0xe83d, 0x3284, 0x28c0 }, 16, 0x000a8de0, 1},
++	{{0x800a, 0xf848, 0x98c0, 0xfe41, 0x3920, 0x3840, 0x8009, 0x3284, 0x29a0, 0x800a, 0x38e0, 0x3a00, 0x800b, 0x3a40, 0xa000, 0x3ae8 }, 16, 0x000a8e00, 1},
++	{{0x3c28, 0xbfff, 0xf8c5, 0x3a40, 0xa000, 0x33a1, 0x2000, 0x8000, 0xfec9, 0x347b, 0x1192, 0x3ce8, 0x3c28, 0xbfff, 0x33bb, 0x8000 }, 16, 0x000a8e20, 1},
++	{{0x7063, 0x800d, 0x5294, 0x35be, 0x8000, 0x7066, 0x85f9, 0x9ac0, 0x2304, 0x8080, 0x6f10, 0x2b03, 0x8032, 0x98c0, 0x31c1, 0x3000 }, 16, 0x000a8e40, 1},
++	{{0x800c, 0xffc7, 0x98c0, 0x0142, 0x2e78, 0x8009, 0xc784, 0x96c0, 0xe9ee, 0x2500, 0x8080, 0x98c0, 0x2b02, 0x8002, 0x90c0, 0x90c0 }, 16, 0x000a8e60, 1},
++	{{0x9ac0, 0x7b50, 0x0b46, 0x2e78, 0x8009, 0xcd46, 0x3bd0, 0xc847, 0xeb1d, 0x5493, 0x44b9, 0x0c46, 0x2e78, 0x8009, 0x90c0, 0x92d0 }, 16, 0x000a8e80, 1},
++	{{0xec18, 0x5494, 0x44bf, 0x96c0, 0x9b45, 0x2b03, 0x802a, 0x3c60, 0xa000, 0x2808, 0x91cc, 0x90c0, 0x280c, 0x91c8, 0x94c0, 0xc38c }, 16, 0x000a8ea0, 1},
++	{{0xc688, 0x9cc0, 0x2b02, 0x8002, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x7b50, 0xcf46, 0x0d46, 0x2e78, 0x8009, 0x39d0, 0xc943 }, 16, 0x000a8ec0, 1},
++	{{0xed1f, 0x5495, 0x44bc, 0x0f46, 0x2e78, 0x8009, 0x90c0, 0x92d0, 0xef19, 0x5197, 0x41b8, 0x3820, 0xa000, 0xe8ee, 0x2a00, 0x8e00 }, 16, 0x000a8ee0, 1},
++	{{0x98c0, 0xe9ee, 0x3284, 0x28c0, 0x800a, 0xe83a, 0x98c0, 0x33e2, 0x3e08, 0x800b, 0xfe41, 0x90c0, 0x3860, 0xa000, 0xe8eb, 0x2b0f }, 16, 0x000a8f00, 1},
++	{{0x8408, 0x3284, 0x29a0, 0x800a, 0xe9ef, 0x3a20, 0xa000, 0xf8c5, 0x3900, 0x2618, 0x800c, 0x3264, 0x2bd0, 0x800b, 0x3a20, 0xa000 }, 16, 0x000a8f20, 1},
++	{{0xf841, 0x38e0, 0x3a00, 0x800b, 0x3820, 0xa000, 0xfec9, 0x2702, 0x9dfc, 0x9ac0, 0x2304, 0x8080, 0x90c0, 0x2b03, 0x802e, 0x3a20 }, 16, 0x000a8f40, 1},
++	{{0xa000, 0xeaee, 0x3900, 0x2618, 0x800c, 0x3820, 0xa000, 0xea3f, 0x2b02, 0x8002, 0x98c0, 0x3b00, 0x261c, 0x800c, 0xfa4a, 0xf8c8 }, 16, 0x000a8f60, 1},
++	{{0x52b9, 0x92d0, 0x42b8, 0x57bb, 0x47ba, 0x98c0, 0x3502, 0x2a18, 0x800c, 0xfaca, 0xf9c8, 0x3480, 0xa000, 0x5095, 0x0092, 0x3284 }, 16, 0x000a8f80, 1},
++	{{0x2290, 0x800a, 0x0846, 0x2e74, 0x8009, 0x3820, 0xa000, 0xfec9, 0x2b00, 0x9a00, 0x3820, 0xa000, 0x0f46, 0x2e74, 0x8009, 0x3420 }, 16, 0x000a8fa0, 1},
++	{{0xa000, 0xe9ee, 0x3840, 0xa000, 0xe93b, 0x2f08, 0x8204, 0x3284, 0x2290, 0x800a, 0xf94b, 0x0946, 0x2e74, 0x8009, 0x32a4, 0x20e0 }, 16, 0x000a8fc0, 1},
++	{{0x800b, 0x3840, 0x3508, 0x8009, 0x0a46, 0x2e74, 0x8009, 0x3840, 0x2eb0, 0x8009, 0x32a4, 0x20e0, 0x800b, 0x2a09, 0x8204, 0x0846 }, 16, 0x000a8fe0, 1},
++	{{0x2e74, 0x8009, 0x3284, 0x2600, 0x800a, 0x2809, 0x8810, 0x0d46, 0x2e74, 0x8009, 0x90c0, 0x2d08, 0x8204, 0x3284, 0x2600, 0x800a }, 16, 0x000a9000, 1},
++	{{0x2809, 0x8664, 0x3820, 0xa000, 0xffcb, 0x2c00, 0x8510, 0x96c0, 0xc581, 0x2402, 0x8520, 0x3660, 0xa000, 0xe9ef, 0xfec9, 0x36c0 }, 16, 0x000a9020, 1},
++	{{0xa000, 0xef3c, 0xe93c, 0x3680, 0xa000, 0x5217, 0x54d1, 0x3a60, 0xa000, 0xd692, 0x6d10, 0xf8c5, 0xfac6, 0x98c0, 0x66e1, 0xf94c }, 16, 0x000a9040, 1},
++	{{0x2b00, 0x9e04, 0x3a40, 0xa000, 0x72f4, 0xedee, 0x2600, 0x83e8, 0x96c0, 0x8467, 0x2a00, 0x808c, 0x96c0, 0xed3b, 0x2b03, 0x802e }, 16, 0x000a9060, 1},
++	{{0x94c0, 0x4695, 0x9356, 0x3a40, 0xa000, 0x0b46, 0x2e74, 0x8009, 0xedea, 0x96c0, 0xed3a, 0x2560, 0x9fff, 0x3820, 0xa000, 0xeae8 }, 16, 0x000a9080, 1},
++	{{0x2b0b, 0x89a4, 0x4693, 0x3942, 0x1415, 0xcb42, 0x449a, 0x0846, 0x2e74, 0x8009, 0x90c0, 0x280f, 0x89d4, 0xef1b, 0x4517, 0x0f46 }, 16, 0x000a90a0, 1},
++	{{0x2e74, 0x8009, 0x90c0, 0x94d0, 0x2f0f, 0x8944, 0xef1b, 0x4517, 0x31a4, 0x22e4, 0x800a, 0x9ac0, 0x2a00, 0x808c, 0x7265, 0x2900 }, 16, 0x000a90c0, 1},
++	{{0x80d2, 0x3620, 0xa000, 0xedea, 0x8487, 0x3620, 0xa000, 0xecea, 0xed3a, 0x94c0, 0xec39, 0xc696, 0x3c60, 0xa000, 0x2809, 0x818c }, 16, 0x000a90e0, 1},
++	{{0x90c0, 0x280b, 0x80dc, 0x3860, 0xa000, 0xeae8, 0x2808, 0x823c, 0x3620, 0xa000, 0xff4d, 0xcd4f, 0x96c0, 0xfc4e, 0x90c0, 0x90c0 }, 16, 0x000a9100, 1},
++	{{0x96c0, 0x6c10, 0xcc47, 0xf851, 0x94c0, 0xfb4f, 0xf950, 0x1114, 0xfcce, 0x419a, 0x14d4, 0xfa52, 0x3284, 0x2b60, 0x800a, 0xf401 }, 16, 0x000a9120, 1},
++	{{0x96c0, 0x7b61, 0xf8d1, 0xf9d0, 0x96c0, 0x676a, 0xfbcf, 0xfad2, 0x4098, 0x94c0, 0x4099, 0x81ce, 0x409b, 0x3660, 0xa000, 0xf8c5 }, 16, 0x000a9140, 1},
++	{{0xfac6, 0x3420, 0xa000, 0xffcd, 0x9ac0, 0x6e10, 0x0b46, 0x2e74, 0x8009, 0x9356, 0x9ac0, 0x2b03, 0x801c, 0x90c0, 0x2101, 0x85d1 }, 16, 0x000a9160, 1},
++	{{0x9ac0, 0x2b09, 0x89a4, 0x90c0, 0x2d00, 0x8194, 0x92c0, 0x4491, 0x9ac0, 0x7a44, 0x0a46, 0x2e74, 0x8009, 0xcc44, 0x90c0, 0x2a0b }, 16, 0x000a9180, 1},
++	{{0x89a4, 0x1293, 0xe9eb, 0xe93d, 0xe91c, 0x5091, 0x62f4, 0x92d0, 0x6ef4, 0x6ec9, 0x4593, 0x9ac0, 0x6c10, 0x0b46, 0x2e74, 0x8009 }, 16, 0x000a91a0, 1},
++	{{0x9356, 0x3820, 0xa000, 0xe9e8, 0x2b03, 0x8010, 0x2b0b, 0x89a0, 0x4093, 0x1099, 0x0a46, 0x2e74, 0x8009, 0x6274, 0x96c0, 0x6e74 }, 16, 0x000a91c0, 1},
++	{{0x2a0a, 0x89a0, 0x92d0, 0x5292, 0x6ec8, 0x4592, 0x3a40, 0xa000, 0x2402, 0x84b4, 0x6f10, 0xebea, 0x3820, 0xa000, 0xe9ea, 0x2c00 }, 16, 0x000a91e0, 1},
++	{{0x80d2, 0x3660, 0xa000, 0xeb3c, 0xe8ea, 0x96c0, 0xe83c, 0x2402, 0x808c, 0x94c0, 0xc796, 0xfb53, 0x3660, 0xa000, 0xe93c, 0xff4d }, 16, 0x000a9200, 1},
++	{{0xf954, 0x98c0, 0x0c46, 0x2e74, 0x8009, 0xca46, 0x14d0, 0x5093, 0x96c0, 0xf401, 0x2c09, 0x8810, 0x94c0, 0xe91a, 0xfb55, 0x3284 }, 16, 0x000a9220, 1},
++	{{0x2b60, 0x800a, 0x1191, 0xf856, 0x9ac0, 0x7650, 0x7be1, 0x7b44, 0xfdd4, 0xfbd5, 0x27ea, 0xf8d6, 0x5015, 0x94c0, 0x6c7c, 0x81c8 }, 16, 0x000a9240, 1},
++	{{0x449b, 0x3a40, 0xa000, 0x6e90, 0xfac6, 0x2800, 0x845c, 0x3820, 0xa000, 0xf8c5, 0x2102, 0x80d0, 0x3620, 0xa000, 0xedea, 0xc396 }, 16, 0x000a9260, 1},
++	{{0x3640, 0xa000, 0xed38, 0xeaea, 0x3620, 0xa000, 0xece8, 0xebed, 0x94c0, 0xf357, 0xf558, 0x3640, 0xa000, 0xf9d3, 0xea39, 0xfd59 }, 16, 0x000a9280, 1},
++	{{0x3c20, 0xa000, 0x6c90, 0x0846, 0x2e74, 0x8009, 0xf9d8, 0x3620, 0xa000, 0x5c94, 0xfb5a, 0x96c0, 0xfa5b, 0x2808, 0x8810, 0x3620 }, 16, 0x000a92a0, 1},
++	{{0xa000, 0xe819, 0xf95c, 0x1890, 0xfc5d, 0x90c0, 0x3a20, 0xa000, 0xe83c, 0x3284, 0x2110, 0x800a, 0xc848, 0x96c0, 0x74d0, 0xfadb }, 16, 0x000a92c0, 1},
++	{{0xfbda, 0x90c0, 0x14d2, 0x5093, 0x3284, 0x2b60, 0x800a, 0xf401, 0x3a20, 0xa000, 0x0946, 0x2e74, 0x8009, 0xf8d8, 0x94c0, 0xf9dc }, 16, 0x000a92e0, 1},
++	{{0xfcdd, 0x3840, 0xa100, 0xc686, 0x290c, 0x88ec, 0x3680, 0xa000, 0xec18, 0xf601, 0x3680, 0xa000, 0x4094, 0xc84e, 0x1099, 0x5194 }, 16, 0x000a9300, 1},
++	{{0x3284, 0x2160, 0x800a, 0xf95c, 0x3c40, 0xa000, 0x7550, 0x0946, 0x2e74, 0x8009, 0xc846, 0x94c0, 0xfcdd, 0xc08f, 0x3840, 0xa100 }, 16, 0x000a9320, 1},
++	{{0xf001, 0x290c, 0x88ec, 0x3680, 0xa000, 0xec18, 0x539c, 0x3a80, 0xa000, 0x5094, 0x3680, 0x2000, 0x8000, 0x96c0, 0xd5c0, 0x6e7d }, 16, 0x000a9340, 1},
++	{{0xfc5d, 0x98c0, 0xf343, 0x3284, 0x2160, 0x800a, 0xf1c3, 0x35d0, 0x3780, 0x2000, 0x8000, 0x6f7d, 0x7677, 0x6836, 0x6466, 0x3c6f }, 16, 0x000a9360, 1},
++	{{0x3284, 0x2110, 0x800a, 0x6c90, 0x96c0, 0xd43f, 0xfbda, 0xfadb, 0x8040, 0x94c0, 0xf9dc, 0xfcdd, 0x3c41, 0x3860, 0x2d20, 0x8008 }, 16, 0x000a9380, 1},
++	{{0xc450, 0x90c0, 0x3480, 0xa000, 0xec18, 0x3480, 0xa000, 0x5314, 0x9ac0, 0x34e4, 0x8003, 0x90c0, 0x36e6, 0x8003, 0x30e4, 0x8003 }, 16, 0x000a93a0, 1},
++	{{0xd814, 0x98c0, 0xd446, 0x3084, 0x3410, 0x800a, 0x30cf, 0x950c, 0x96c0, 0x3610, 0x80ef, 0x7c64, 0x96c0, 0x3105, 0x801d, 0x8039 }, 16, 0x000a93c0, 1},
++	{{0x3ec1, 0x3860, 0x2d20, 0x8008, 0xc155, 0x90c0, 0x3480, 0xa000, 0xe918, 0x3480, 0xa000, 0x5511, 0x9ac0, 0x34e4, 0x8005, 0x90c0 }, 16, 0x000a93e0, 1},
++	{{0x36e6, 0x8005, 0x30e4, 0x8005, 0xda14, 0xd646, 0x38cf, 0x950c, 0x96c0, 0x67e6, 0xf0d7, 0xf3d8, 0x3861, 0x39c4, 0x479b, 0x96c0 }, 16, 0x000a9400, 1},
++	{{0x646a, 0xf358, 0xf057, 0x2dff, 0x9e7b, 0x3a40, 0xa000, 0x6f10, 0xfac6, 0x2a00, 0x8090, 0x3620, 0xa000, 0xf8c5, 0xfdd9, 0x3620 }, 16, 0x000a9420, 1},
++	{{0xa000, 0xecea, 0xc796, 0x3640, 0xa000, 0xec3a, 0xe8e8, 0x96c0, 0x51d4, 0x2a00, 0x807e, 0x3a40, 0xa000, 0x331c, 0x8002, 0xebed }, 16, 0x000a9440, 1},
++	{{0xe9ea, 0x2669, 0xe93a, 0x2518, 0x8226, 0x3284, 0x2c00, 0x800a, 0xfc5e, 0x3c20, 0xa000, 0x6c90, 0x0b46, 0x2e74, 0x8009, 0xf8c5 }, 16, 0x000a9460, 1},
++	{{0x90c0, 0x3880, 0xa000, 0x5990, 0x2b0a, 0x8810, 0x5b92, 0x90c0, 0x98c0, 0xeb39, 0x3284, 0x2110, 0x800a, 0xcb48, 0x3640, 0xa000 }, 16, 0x000a9480, 1},
++	{{0x74d0, 0xf8c5, 0x3284, 0x2b90, 0x800a, 0x3420, 0xa000, 0xe8e8, 0x3c40, 0xa000, 0x6c90, 0xfac6, 0x0b46, 0x2e74, 0x8009, 0x2900 }, 16, 0x000a94a0, 1},
++	{{0x858c, 0x3820, 0xa000, 0xeaea, 0x2b0b, 0x8814, 0x1b93, 0xea39, 0x5a92, 0x90c0, 0x98c0, 0xeb3a, 0x3284, 0x2110, 0x800a, 0xcb48 }, 16, 0x000a94c0, 1},
++	{{0x3640, 0xa000, 0x74d0, 0xf8c5, 0x3284, 0x2b90, 0x800a, 0x3420, 0xa000, 0xe8e8, 0x3c20, 0xa000, 0x6e10, 0x6f90, 0xfac6, 0x2a00 }, 16, 0x000a94e0, 1},
++	{{0x807e, 0x3620, 0xa000, 0xf8c5, 0xfdd9, 0x3620, 0xa000, 0xe9ea, 0xc388, 0x94c0, 0xe93a, 0xf460, 0x3640, 0xa100, 0xf35f, 0xece8 }, 16, 0x000a9500, 1},
++	{{0x3600, 0xa100, 0xc696, 0xe9ed, 0x98c0, 0x3b40, 0x2e80, 0x8009, 0xfe61, 0x3c40, 0xa000, 0xff62, 0x280a, 0x8008, 0x90c0, 0x90c0 }, 16, 0x000a9520, 1},
++	{{0x3e20, 0xa000, 0xd7b3, 0x6c90, 0x0e46, 0x2e74, 0x8009, 0x5f92, 0x94c0, 0xf8df, 0x8051, 0x3860, 0xa100, 0xf963, 0x2e0b, 0x8810 }, 16, 0x000a9540, 1},
++	{{0x3680, 0xa000, 0xeb18, 0xfb64, 0x3680, 0xa000, 0x5893, 0xfa65, 0xeee9, 0x98c0, 0xe83f, 0x3284, 0x2110, 0x800a, 0x3640, 0xa000 }, 16, 0x000a9560, 1},
++	{{0xc848, 0xefec, 0x3620, 0xa000, 0xf8c5, 0xe9ee, 0x36c0, 0xa000, 0xecef, 0xf9e3, 0x3084, 0x35a2, 0x800a, 0x94c0, 0xfbe4, 0xfae5 }, 16, 0x000a9580, 1},
++	{{0x6c10, 0x3860, 0xa000, 0x74d0, 0xe8e8, 0xf963, 0x94c0, 0xfb64, 0xfa65, 0x3284, 0x2b90, 0x800a, 0x3640, 0xa000, 0xeee9, 0xefec }, 16, 0x000a95a0, 1},
++	{{0x94c0, 0xfbe4, 0xfcde, 0x3680, 0xa000, 0xecef, 0xc289, 0x115b, 0x53d4, 0x3c00, 0xa100, 0x6274, 0x371b, 0x800f, 0x559c, 0xf201 }, 16, 0x000a95c0, 1},
++	{{0x3c20, 0xa000, 0x6e74, 0x7de2, 0x74d5, 0xfb64, 0xefec, 0xd613, 0x98c0, 0xf444, 0x32c4, 0x33c0, 0x800a, 0xf0c4, 0x3840, 0xa000 }, 16, 0x000a95e0, 1},
++	{{0x7c46, 0xf9e3, 0xe9ee, 0x5111, 0x3480, 0xa000, 0x5599, 0x3640, 0xa000, 0xd445, 0xf963, 0x2461, 0x3284, 0x2110, 0x800a, 0x6466 }, 16, 0x000a9600, 1},
++	{{0x3284, 0x2100, 0x800a, 0x2160, 0x9fff, 0x98c0, 0x7b61, 0x7bc1, 0xe9ee, 0xf4e0, 0x9cc0, 0x676a, 0x7a42, 0x0e46, 0x2e74, 0x8009 }, 16, 0x000a9620, 1},
++	{{0xc844, 0x94c0, 0xfae5, 0xf2df, 0x3a80, 0xa100, 0x2e0e, 0x8944, 0x7944, 0xecef, 0x3680, 0xa000, 0xee18, 0xfbe4, 0x3620, 0xa000 }, 16, 0x000a9640, 1},
++	{{0xf9e3, 0xea44, 0x3620, 0xa000, 0xf8c5, 0xf25f, 0x2cff, 0x9ed5, 0x3600, 0xa100, 0xf460, 0x4016, 0x3620, 0xa000, 0xfac6, 0xfee1 }, 16, 0x000a9660, 1},
++	{{0x3084, 0x36d4, 0x800a, 0x94c0, 0xffe2, 0xfdd9, 0x109b, 0x5111, 0x3284, 0x2110, 0x800a, 0x96c0, 0x6466, 0xf966, 0xfb67, 0x3284 }, 16, 0x000a9680, 1},
++	{{0x2100, 0x800a, 0x2160, 0x9fff, 0x9cc0, 0x7be1, 0x7b42, 0x0846, 0x2e74, 0x8009, 0xca46, 0x96c0, 0x67ea, 0xf9e6, 0xfbe7, 0x280c }, 16, 0x000a96a0, 1},
++	{{0x8944, 0x94c0, 0xec1a, 0x81ca, 0x4014, 0x3660, 0xa000, 0xf8c5, 0xfac6, 0xfdd9, 0x9ac0, 0x6f10, 0x6f90, 0x9356, 0x2b03, 0x8010 }, 16, 0x000a96c0, 1},
++	{{0x2a00, 0x8134, 0x9ac0, 0x7bc2, 0x0b46, 0x2e74, 0x8009, 0xc947, 0x3b44, 0xc846, 0x2b0c, 0x8944, 0xe91c, 0x1111, 0xec3a, 0x2a74 }, 16, 0x000a96e0, 1},
++	{{0xec18, 0x3e6f, 0x5094, 0xd894, 0x92d0, 0x62f4, 0x6ef4, 0x459d, 0x3820, 0xa000, 0xebea, 0x2a00, 0x80ec, 0x3c60, 0xa000, 0x280c }, 16, 0x000a9700, 1},
++	{{0x823c, 0x90c0, 0x280d, 0x818c, 0xeb3a, 0x14d3, 0xfb68, 0x6669, 0x94c0, 0xfbd3, 0x8425, 0x98c0, 0x9356, 0x2b03, 0x800a, 0x90c0 }, 16, 0x000a9720, 1},
++	{{0x1093, 0x5495, 0x6c7d, 0x92d0, 0x449c, 0x569b, 0x469d, 0x3184, 0x3782, 0x800a, 0x96c0, 0x9356, 0x2b03, 0x801c, 0x3840, 0xa000 }, 16, 0x000a9740, 1},
++	{{0xfdd3, 0x280c, 0x823c, 0x3820, 0xa000, 0x280b, 0x818c, 0x90c0, 0x1495, 0x5093, 0x6c7d, 0x449b, 0x94d0, 0x5094, 0x549d, 0x6c7d }, 16, 0x000a9760, 1},
++	{{0x449c, 0x9ac0, 0x2900, 0x82fc, 0x90c0, 0x2d00, 0x80ea, 0x3820, 0xa000, 0xebea, 0x2c00, 0x83ac, 0x36a0, 0xa000, 0xe9ea, 0xeb3d }, 16, 0x000a9780, 1},
++	{{0x3620, 0xa100, 0xeaea, 0xe939, 0x94c0, 0xfb69, 0xea3c, 0x94c0, 0xc796, 0xf8d3, 0x3a20, 0xa000, 0xf96a, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a97a0, 1},
++	{{0x3640, 0xa000, 0x5098, 0xf96b, 0x3284, 0x20b0, 0x800a, 0x94c0, 0xf86c, 0xca4e, 0x96c0, 0x7be1, 0xca46, 0xfce9, 0x3620, 0xa000 }, 16, 0x000a97c0, 1},
++	{{0xf9eb, 0xf8ec, 0x1492, 0x52d4, 0x2569, 0x6c7d, 0x90c0, 0x98c1, 0x7774, 0xedea, 0x90c0, 0x74f4, 0x3647, 0xa000, 0x4692, 0x9d59 }, 16, 0x000a97e0, 1},
++	{{0x3681, 0xa100, 0x4191, 0x5491, 0x94c7, 0xea44, 0x6c7d, 0x3880, 0xa000, 0xd05c, 0x67ea, 0xe944, 0x94c0, 0x76f0, 0x81a8, 0x4595 }, 16, 0x000a9800, 1},
++	{{0x3a40, 0xa000, 0x0b46, 0x2e74, 0x8009, 0xfec9, 0x3a40, 0xa000, 0x33e2, 0x3e08, 0x800b, 0xf8c5, 0x3820, 0xa000, 0xe9ee, 0x2102 }, 16, 0x000a9820, 1},
++	{{0x9e0c, 0x2b0b, 0x89a4, 0x3640, 0xa000, 0x5493, 0xe939, 0x4499, 0x0b46, 0x2e74, 0x8009, 0x90c0, 0x2b0b, 0x89a0, 0x1393, 0x3ba0 }, 16, 0x000a9840, 1},
++	{{0x3074, 0x8009, 0x4391, 0x1293, 0x03a6, 0x3070, 0x8009, 0x9ac0, 0x370b, 0x8020, 0x90c0, 0x350a, 0x8001, 0x65e9, 0x8407, 0x6569 }, 16, 0x000a9860, 1},
++	{{0x8415, 0x3ba0, 0x3074, 0x8009, 0x37f8, 0x3fff, 0xbbff, 0x5593, 0xdf85, 0x4793, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0b, 0x81c0 }, 16, 0x000a9880, 1},
++	{{0x96c0, 0x5213, 0x2b09, 0x8100, 0x98c0, 0x355b, 0x8000, 0xcb82, 0x5911, 0x65e9, 0x96c0, 0xe961, 0x2718, 0x8106, 0xe98b, 0x96c0 }, 16, 0x000a98a0, 1},
++	{{0xe9fe, 0x2518, 0x80fc, 0x98c0, 0x3b20, 0x3c5c, 0x8009, 0xe8ef, 0x90c0, 0xe91b, 0x1b91, 0x0946, 0x2e74, 0x8009, 0x90c0, 0x96c0 }, 16, 0x000a98c0, 1},
++	{{0x9b61, 0x2909, 0x8944, 0x2f0b, 0x8004, 0x3800, 0xa100, 0xcb4e, 0x2b09, 0x83fc, 0x3a80, 0xa000, 0x5791, 0x3284, 0x2350, 0x800a }, 16, 0x000a98e0, 1},
++	{{0x0793, 0xc15f, 0x96c0, 0x6c90, 0xcb46, 0xc157, 0x33e2, 0x3e08, 0x800b, 0x1393, 0x4193, 0x3480, 0xa000, 0x4399, 0x3480, 0xa000 }, 16, 0x000a9900, 1},
++	{{0x4191, 0x3820, 0xa000, 0xe8eb, 0x2b00, 0x8404, 0x0946, 0x2e74, 0x8009, 0xef3b, 0x9ac0, 0x2f0b, 0x83fc, 0x90c0, 0x2909, 0x8944 }, 16, 0x000a9920, 1},
++	{{0x1493, 0xcb4e, 0x3284, 0x2350, 0x800a, 0x4497, 0x2c10, 0x1697, 0xcb46, 0x9ac0, 0x2900, 0x840c, 0x90c0, 0x2402, 0x8808, 0x069b }, 16, 0x000a9940, 1},
++	{{0x4097, 0x3ac0, 0xa000, 0xebeb, 0x0946, 0x2e74, 0x8009, 0x3680, 0xa000, 0xeb39, 0xefeb, 0x36c0, 0xa000, 0x5293, 0xef3c, 0x3840 }, 16, 0x000a9960, 1},
++	{{0xa000, 0x4093, 0x2909, 0x8944, 0x0297, 0x38e0, 0x3a00, 0x800b, 0x3284, 0x2350, 0x800a, 0x94c0, 0xcb4e, 0xc35f, 0x96c0, 0x6c10 }, 16, 0x000a9980, 1},
++	{{0xcb46, 0xc357, 0x96c0, 0x5497, 0x2900, 0x8408, 0x3620, 0xa100, 0xf8c5, 0x4493, 0x0097, 0xeb39, 0x4093, 0x3c40, 0xa000, 0x6f90 }, 16, 0x000a99a0, 1},
++	{{0xf842, 0x3900, 0x2618, 0x800c, 0x3264, 0x2b60, 0x800b, 0x98c0, 0xf741, 0x38e0, 0x3a00, 0x800b, 0x9ac0, 0x2304, 0x8080, 0x90c0 }, 16, 0x000a99c0, 1},
++	{{0x2b03, 0x8036, 0x3a40, 0xa000, 0x3b00, 0x2618, 0x800c, 0xf8c5, 0x3660, 0xa000, 0xfac6, 0xfec9, 0x3a40, 0xa000, 0x3502, 0x2a18 }, 16, 0x000a99e0, 1},
++	{{0x800c, 0xffcd, 0x96c0, 0xffca, 0x2b02, 0x8002, 0xf9c8, 0x559b, 0x92d0, 0x45b9, 0x559b, 0x45bf, 0x3600, 0xa100, 0xfaca, 0x5695 }, 16, 0x000a9a00, 1},
++	{{0x94c0, 0xf9cc, 0xc081, 0x3840, 0xa000, 0x4692, 0x280d, 0x839c, 0x3680, 0xa000, 0x5717, 0x51d1, 0x3c60, 0xa000, 0x280a, 0x83f4 }, 16, 0x000a9a20, 1},
++	{{0xd417, 0x280b, 0x82ec, 0x3840, 0xa000, 0x6461, 0x2809, 0x844c, 0x30f0, 0x6c90, 0x8015, 0x96c0, 0x9356, 0x2b03, 0x8008, 0x4199 }, 16, 0x000a9a40, 1},
++	{{0x92d0, 0x419b, 0x419d, 0x419a, 0x3e00, 0xa006, 0x6c10, 0x2d00, 0x80c8, 0x6f10, 0x2502, 0x9e04, 0x9ac0, 0x2702, 0x9e36, 0x90c0 }, 16, 0x000a9a60, 1},
++	{{0x2a00, 0x80d6, 0x36e0, 0xa000, 0xecea, 0xefee, 0x3880, 0xa000, 0xec3d, 0x2800, 0x80ce, 0x3660, 0xa000, 0xef3d, 0xebea, 0x38a0 }, 16, 0x000a9a80, 1},
++	{{0xa000, 0xedea, 0x2d00, 0x8144, 0x3600, 0xa100, 0xeb3a, 0xed38, 0x3820, 0xa000, 0xeaea, 0x2800, 0x80c6, 0x3640, 0xa000, 0xea3d }, 16, 0x000a9aa0, 1},
++	{{0xecea, 0x3820, 0xa000, 0xe9ee, 0x2d00, 0x80cc, 0x3660, 0xa100, 0xe93f, 0xe9ea, 0x96c0, 0xec38, 0x2702, 0x80e4, 0x3680, 0xa000 }, 16, 0x000a9ac0, 1},
++	{{0xe93d, 0xfc6f, 0x3820, 0xa000, 0xfc6e, 0x2402, 0x80b0, 0x13d1, 0xc4ef, 0x3840, 0xa000, 0xde03, 0xecea, 0xedef, 0x3660, 0xa000 }, 16, 0x000a9ae0, 1},
++	{{0xec3f, 0xed3c, 0x3660, 0xa000, 0xf970, 0xfd6d, 0x3860, 0xa100, 0xc396, 0x280b, 0x82ec, 0x3640, 0xa000, 0x4411, 0xffd3, 0x3ce0 }, 16, 0x000a9b00, 1},
++	{{0xa100, 0x280d, 0x8344, 0x90c0, 0x280c, 0x83f4, 0x3840, 0xa100, 0xfe61, 0x2809, 0x839c, 0xff71, 0x3600, 0xa100, 0xffed, 0xce40 }, 16, 0x000a9b20, 1},
++	{{0x3680, 0xa000, 0x5093, 0xf972, 0x11d7, 0x0f46, 0x2e74, 0x8009, 0x3640, 0xa000, 0xf101, 0xf373, 0x96c0, 0xfb74, 0x2f0f, 0x8868 }, 16, 0x000a9b40, 1},
++	{{0x94c0, 0xef1e, 0xfa75, 0x1197, 0xfc76, 0x3640, 0xa000, 0xfd77, 0xf678, 0x3660, 0xa000, 0xf079, 0xfd7a, 0x3660, 0xa000, 0xff7b }, 16, 0x000a9b60, 1},
++	{{0xfc7c, 0x3284, 0x2b60, 0x800a, 0x3660, 0xa000, 0xf97d, 0xfb7e, 0xfbf4, 0x3284, 0x2110, 0x800a, 0x5113, 0x3a40, 0xa000, 0x31e8 }, 16, 0x000a9b80, 1},
++	{{0x3fff, 0xbfff, 0xfbfe, 0x3860, 0xa000, 0x7651, 0xf9fd, 0xfcfc, 0x96c0, 0x6c7d, 0xffee, 0xf9f2, 0x3800, 0xa100, 0x74d4, 0x4493 }, 16, 0x000a9ba0, 1},
++	{{0xfaf5, 0x3680, 0xa000, 0x5591, 0xfbf4, 0x96c0, 0x6d7d, 0xc688, 0xc18f, 0x3480, 0xa000, 0x4591, 0x3680, 0xa100, 0x5494, 0x5093 }, 16, 0x000a9bc0, 1},
++	{{0x6c7d, 0x3480, 0xa000, 0x4494, 0x3600, 0xa100, 0x50d7, 0x5393, 0x12d1, 0xd610, 0x327b, 0xdf1a, 0x8055, 0x0611, 0x0902, 0xa018 }, 16, 0x000a9be0, 1},
++	{{0x0211, 0xf101, 0x3a00, 0xa100, 0x0f46, 0x2e74, 0x8009, 0x5193, 0x90c0, 0x2f0f, 0x88ec, 0x98c0, 0xef1e, 0x3284, 0x2160, 0x800a }, 16, 0x000a9c00, 1},
++	{{0x5097, 0x96c0, 0x74d0, 0xffef, 0xfaf5, 0x90c0, 0x13d7, 0x5092, 0x3284, 0x2b60, 0x800a, 0xf301, 0x94c0, 0xfaf5, 0xfbf4, 0x3a20 }, 16, 0x000a9c20, 1},
++	{{0xa000, 0xfbfe, 0x3084, 0x3c52, 0x800a, 0x4092, 0xc6f7, 0xdf02, 0x4611, 0x3880, 0xa000, 0x6f10, 0x5792, 0x5493, 0x27e9, 0x5113 }, 16, 0x000a9c40, 1},
++	{{0x92c2, 0x6d10, 0x94c7, 0x559a, 0x5092, 0x96c7, 0x66e0, 0xd190, 0xfa75, 0x94c3, 0x3702, 0x801e, 0x796e, 0x6e7c, 0xd68e, 0xda95 }, 16, 0x000a9c60, 1},
++	{{0x2076, 0x3284, 0x2110, 0x800a, 0x6c76, 0x9ac0, 0x7650, 0xf9f2, 0x0f46, 0x2e74, 0x8009, 0x3c40, 0xa000, 0xd616, 0xfffb, 0x30e8 }, 16, 0x000a9c80, 1},
++	{{0x3fff, 0xbfff, 0x2661, 0x17d1, 0xc586, 0x9cc0, 0x2f0f, 0x899c, 0x6666, 0x3f1a, 0x8008, 0xf501, 0x2569, 0x6c7d, 0x92c2, 0x6e10 }, 16, 0x000a9ca0, 1},
++	{{0x4497, 0x3a00, 0xa100, 0x0f46, 0x2e74, 0x8009, 0x509f, 0x3420, 0xa000, 0xff7b, 0x2f0f, 0x899c, 0x3284, 0x2160, 0x800a, 0x5197 }, 16, 0x000a9cc0, 1},
++	{{0x3e20, 0xa000, 0x7550, 0x6c90, 0x0a46, 0x2e74, 0x8009, 0xefee, 0x3880, 0xa000, 0xeeee, 0x2002, 0x8058, 0x36a0, 0xa000, 0x2a0a }, 16, 0x000a9ce0, 1},
++	{{0x8868, 0x3a20, 0xa000, 0xef1a, 0x3680, 0x2000, 0x8000, 0x3640, 0xa100, 0x6e7d, 0xea38, 0x3480, 0xa000, 0xea1e, 0x3480, 0xa000 }, 16, 0x000a9d00, 1},
++	{{0x5392, 0x4397, 0x0f46, 0x2e74, 0x8009, 0x90c0, 0x2f0f, 0x8868, 0x3480, 0xa000, 0xee1f, 0x38a0, 0xa000, 0x5a96, 0x2f0f, 0x8134 }, 16, 0x000a9d20, 1},
++	{{0x5f97, 0x90c0, 0x3a80, 0xa000, 0xea3f, 0x3284, 0x2110, 0x800a, 0xc258, 0x3820, 0xa000, 0x74d0, 0xfff0, 0xfdfa, 0x90c0, 0x3600 }, 16, 0x000a9d40, 1},
++	{{0xa100, 0x53d7, 0x5095, 0x3284, 0x2b60, 0x800a, 0xf301, 0xfbf4, 0x3284, 0x2110, 0x800a, 0x5113, 0x98c0, 0x0f46, 0x2e74, 0x8009 }, 16, 0x000a9d60, 1},
++	{{0xc48f, 0xf401, 0x2f0f, 0x899c, 0x5597, 0xd6c0, 0x98c0, 0xf543, 0x3284, 0x2160, 0x800a, 0xf1c3, 0x37d0, 0x3380, 0x2000, 0x8000 }, 16, 0x000a9d80, 1},
++	{{0x6f7d, 0x7477, 0x6822, 0x6466, 0x3c6f, 0x3284, 0x2110, 0x800a, 0x6c90, 0x98c0, 0xd43f, 0x3f60, 0x2d20, 0x8008, 0x94c7, 0x8037 }, 16, 0x000a9da0, 1},
++	{{0x7c41, 0xc250, 0x90c0, 0x3480, 0xa000, 0xea1f, 0x3480, 0xa000, 0x5612, 0x9ac0, 0x34e4, 0x8006, 0x90c0, 0x36e5, 0x8006, 0x30e4 }, 16, 0x000a9dc0, 1},
++	{{0x8006, 0xda14, 0x98c0, 0xd645, 0x3084, 0x3e32, 0x800a, 0x38cf, 0x950c, 0x96c0, 0x3610, 0x80ef, 0x7c64, 0x96c0, 0x3102, 0x801d }, 16, 0x000a9de0, 1},
++	{{0x8039, 0x3d41, 0x3f60, 0x2d20, 0x8008, 0xc252, 0x90c0, 0x3480, 0xa000, 0xea1f, 0x3480, 0xa000, 0x5312, 0x9ac0, 0x34e0, 0x8003 }, 16, 0x000a9e00, 1},
++	{{0x90c0, 0x36e6, 0x8003, 0x30e0, 0x8003, 0xd810, 0xd446, 0x30cf, 0x950c, 0x96c0, 0x67e6, 0x2160, 0x9fff, 0x3284, 0x20f0, 0x800a }, 16, 0x000a9e20, 1},
++	{{0x7457, 0x94c0, 0xfcf6, 0xfff1, 0x98c0, 0x34e8, 0x3fff, 0xbfff, 0xc18f, 0x0014, 0xf101, 0x1097, 0x0f46, 0x2e74, 0x8009, 0x7c41 }, 16, 0x000a9e40, 1},
++	{{0x96c0, 0x6461, 0x2f0f, 0x89a0, 0x2c7d, 0x1097, 0x32c4, 0x33c0, 0x800a, 0x74d4, 0x3284, 0x20f0, 0x800a, 0x2160, 0x9fff, 0xfdf7 }, 16, 0x000a9e60, 1},
++	{{0x3284, 0x2110, 0x800a, 0x5115, 0xfcf6, 0x3284, 0x2120, 0x800a, 0x5114, 0x3a60, 0xa000, 0x0a46, 0x2e74, 0x8009, 0xf6f8, 0x36c0 }, 16, 0x000a9e80, 1},
++	{{0xa000, 0xcf46, 0xfdfa, 0x3860, 0xa100, 0xf9fd, 0x2a08, 0x88c0, 0x36c0, 0xa000, 0xe81f, 0xfbfe, 0x36c0, 0xa000, 0x4010, 0xfcfc }, 16, 0x000a9ea0, 1},
++	{{0x3a20, 0xa000, 0x0e46, 0x2e74, 0x8009, 0xfaf5, 0x98c0, 0x38a0, 0x3074, 0x8009, 0xfbf4, 0x3860, 0xa100, 0xf3f3, 0x2e08, 0x88c0 }, 16, 0x000a9ec0, 1},
++	{{0x3680, 0xa000, 0xe81f, 0xfcf6, 0x3680, 0xa000, 0x5210, 0xfdf7, 0x3860, 0xa000, 0x683c, 0xf0f9, 0xfffb, 0x3c6f, 0xf9f2, 0x3600 }, 16, 0x000a9ee0, 1},
++	{{0xa100, 0xd890, 0x4095, 0x3820, 0xa000, 0x0e46, 0x2e74, 0x8009, 0x90c0, 0x36a0, 0xa000, 0x2e08, 0x8868, 0x3480, 0xa000, 0xe81e }, 16, 0x000a9f00, 1},
++	{{0x3680, 0xa000, 0x5090, 0xfee8, 0x6174, 0x6d74, 0x3480, 0xa000, 0x429d, 0x56d6, 0x6769, 0x90c0, 0x3682, 0xa100, 0x5491, 0x5093 }, 16, 0x000a9f20, 1},
++	{{0x92c2, 0x6c7d, 0x3482, 0xa000, 0x4494, 0x3482, 0xa000, 0x5593, 0x3482, 0xa000, 0x4591, 0x1290, 0x04a6, 0x3070, 0x8009, 0x9ac0 }, 16, 0x000a9f40, 1},
++	{{0x350a, 0x8400, 0x90c0, 0x394f, 0x8000, 0x6569, 0x8491, 0x3c40, 0xa000, 0x67e9, 0x0a46, 0x2e74, 0x8009, 0xeeef, 0x3680, 0xa000 }, 16, 0x000a9f60, 1},
++	{{0xeeef, 0x844f, 0x3ca0, 0xa000, 0x2a0a, 0x8944, 0x90c0, 0x2002, 0x8114, 0x3420, 0xa000, 0xee1a, 0x3840, 0xa100, 0x5016, 0x2a0a }, 16, 0x000a9f80, 1},
++	{{0x8090, 0x34a0, 0xa000, 0xee1a, 0x34a0, 0xa000, 0xea38, 0x3480, 0xa000, 0xea1f, 0x3480, 0xa000, 0x5112, 0x6a31, 0x3e6f, 0x3084 }, 16, 0x000a9fa0, 1},
++	{{0x3ffc, 0x800a, 0x3480, 0xa000, 0x4416, 0x3a20, 0xa000, 0x0e46, 0x2e74, 0x8009, 0xeeef, 0x2202, 0x8090, 0x36a0, 0xa000, 0x2e0e }, 16, 0x000a9fc0, 1},
++	{{0x89d4, 0x3420, 0xa000, 0xee1e, 0x34a0, 0xa000, 0xee3a, 0x3480, 0xa000, 0xee1f, 0x3480, 0xa000, 0x5216, 0x4216, 0x3c80, 0xa10d }, 16, 0x000a9fe0, 1},
++	{{0x79e1, 0x7844, 0x7b42, 0xec44, 0xeb44, 0x3600, 0xa104, 0x65ea, 0xe944, 0x2dff, 0x9b27, 0x3640, 0xa000, 0x50d1, 0xf8c5, 0x3a20 }, 16, 0x000aa000, 1},
++	{{0xa000, 0x311f, 0x8010, 0xfac6, 0xfee1, 0x98c0, 0x67e9, 0x6f90, 0xfff1, 0xc696, 0x38a0, 0xa000, 0xebea, 0x2718, 0x8104, 0x3c40 }, 16, 0x000aa020, 1},
++	{{0xa000, 0x2502, 0x8094, 0x90c0, 0x280d, 0x84cc, 0x3860, 0xa000, 0xffd3, 0x280c, 0x823c, 0x36e0, 0xa000, 0xeb3d, 0xeae8, 0x3840 }, 16, 0x000aa040, 1},
++	{{0xa100, 0xfd7f, 0x2809, 0x8058, 0x9ac0, 0x07fa, 0x9f00, 0x90c0, 0x0cf8, 0x9efc, 0x9ac0, 0x03fa, 0x9ef8, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000aa060, 1},
++	{{0x9ac0, 0x1df8, 0x9f00, 0x90c0, 0x18f8, 0x9efc, 0xfcff, 0x109d, 0x5498, 0x2c7d, 0x2460, 0x131c, 0x0df8, 0x9f00, 0x98c0, 0xd40b }, 16, 0x000aa080, 1},
++	{{0xfc7f, 0x08f8, 0x9efc, 0x9ac0, 0x6461, 0x0c46, 0x2e74, 0x8009, 0xc847, 0x3074, 0x5092, 0x96c0, 0x8053, 0x1df8, 0x9ef8, 0x9ac0 }, 16, 0x000aa0a0, 1},
++	{{0x2c0c, 0x8810, 0x90c0, 0x01fa, 0x9ef4, 0x15d5, 0xec18, 0x1194, 0xf501, 0x3284, 0x2b60, 0x800a, 0x0af8, 0x9ef0, 0xf8d4, 0x3284 }, 16, 0x000aa0c0, 1},
++	{{0x2110, 0x800a, 0x5110, 0x9ac0, 0x1af8, 0x9ef0, 0x90c0, 0x11fa, 0x9ef4, 0x34e8, 0x3fff, 0xbfff, 0x6c7d, 0x0492, 0x30a4, 0x2118 }, 16, 0x000aa0e0, 1},
++	{{0x800a, 0x3480, 0xa000, 0x4491, 0x0d26, 0x3c68, 0x8009, 0x90c0, 0xed41, 0x0d22, 0x3c68, 0x8009, 0x3a00, 0xa100, 0x7b61, 0x7bc4 }, 16, 0x000aa100, 1},
++	{{0xea44, 0xe944, 0x676a, 0x815b, 0x3640, 0xa000, 0xf9f2, 0xf8c5, 0x3420, 0xa000, 0xfac6, 0x90c0, 0x3640, 0xa100, 0x56d1, 0xecea }, 16, 0x000aa120, 1},
++	{{0x9ac0, 0x3d1f, 0x8010, 0xc696, 0x2102, 0x8098, 0x3ca0, 0xa000, 0x67e9, 0x6f90, 0xebea, 0x2702, 0x8094, 0x3c20, 0xa000, 0x280c }, 16, 0x000aa140, 1},
++	{{0x80b0, 0x90c0, 0x2718, 0x80e0, 0x38a0, 0xa000, 0xeb3f, 0x0cf8, 0x9eec, 0x38a0, 0xa000, 0xec39, 0x03fa, 0x9ee8, 0x3420, 0xa000 }, 16, 0x000aa160, 1},
++	{{0xfbea, 0x3640, 0xa000, 0xf8d3, 0xfb6a, 0x04fa, 0x9ee4, 0x1098, 0x3284, 0x20b0, 0x800a, 0xf853, 0x3820, 0xa000, 0xfbea, 0x14fa }, 16, 0x000aa180, 1},
++	{{0x9ee4, 0x98c0, 0x0d46, 0x2e74, 0x8009, 0xc847, 0x3680, 0xa100, 0x5314, 0x549b, 0x9ac0, 0x7dc3, 0x6c7d, 0xc581, 0x2d0d, 0x8810 }, 16, 0x000aa1a0, 1},
++	{{0x2cb3, 0xed18, 0x30f4, 0x5195, 0x96c0, 0x8055, 0x1af8, 0x9eec, 0x3820, 0xa000, 0xfb6a, 0x1cf8, 0x9ee8, 0x52d2, 0x14d4, 0xd692 }, 16, 0x000aa1c0, 1},
++	{{0x94c0, 0xf543, 0xf401, 0x3284, 0x2b60, 0x800a, 0xf0c3, 0xfdd4, 0x3284, 0x2110, 0x800a, 0x5115, 0x34e8, 0x3fff, 0xbfff, 0x2c7d }, 16, 0x000aa1e0, 1},
++	{{0x3284, 0x20b0, 0x800a, 0x7454, 0x3a40, 0xa000, 0x1af8, 0x9eec, 0x74f8, 0xfbea, 0x3ce3, 0x14fa, 0x9ee4, 0x4112, 0x3b61, 0x3bc4 }, 16, 0x000aa200, 1},
++	{{0x1af8, 0x9eec, 0x676a, 0x94c0, 0xea42, 0x815c, 0x0af8, 0x9eec, 0x3640, 0xa000, 0xf9f2, 0xfac6, 0x90c0, 0x14d1, 0x0946, 0x2e74 }, 16, 0x000aa220, 1},
++	{{0x8009, 0x3ca0, 0xa000, 0x3918, 0x8004, 0xebea, 0x2102, 0x808e, 0x2469, 0x5097, 0x96c0, 0x8439, 0x2909, 0x89a4, 0x36a0, 0xa000 }, 16, 0x000aa240, 1},
++	{{0xeb39, 0x5191, 0x3a80, 0xa000, 0x52d3, 0x3284, 0x2b60, 0x800a, 0xf201, 0xfbf4, 0x3284, 0x2110, 0x800a, 0x5113, 0x3a40, 0xa000 }, 16, 0x000aa260, 1},
++	{{0x34e8, 0x3fff, 0xbfff, 0xfac6, 0x6c7d, 0x4497, 0x96c0, 0xfbe8, 0x2502, 0x80dc, 0x38a0, 0xa000, 0xebea, 0x2f00, 0x80da, 0x3640 }, 16, 0x000aa280, 1},
++	{{0xa100, 0x53d3, 0xeb3d, 0x3640, 0xa100, 0x79c1, 0xe9ea, 0x3880, 0xa000, 0x76fb, 0x4313, 0xe93f, 0x3480, 0xa000, 0x5213, 0x7175 }, 16, 0x000aa2a0, 1},
++	{{0x92c3, 0x6e10, 0x94c7, 0xfbe9, 0x4413, 0x90c0, 0x50d3, 0x7841, 0x3478, 0x4013, 0x3480, 0xa000, 0x5111, 0x70f0, 0x92c3, 0x6c10 }, 16, 0x000aa2c0, 1},
++	{{0x92c3, 0x4013, 0x96c0, 0xf9cc, 0x2160, 0x9fff, 0x90c0, 0x10d1, 0x3284, 0x20f0, 0x800a, 0x7841, 0x3820, 0xa000, 0xfac6, 0x2b00 }, 16, 0x000aa2e0, 1},
++	{{0x804e, 0xf9cc, 0x3420, 0xa000, 0xe8ea, 0x0011, 0xe83b, 0x0b46, 0x2e74, 0x8009, 0x3284, 0x2c20, 0x800a, 0x2b09, 0x8970, 0x3c20 }, 16, 0x000aa300, 1},
++	{{0xa000, 0x6f90, 0x38a0, 0x3074, 0x8009, 0xf8c5, 0x3620, 0xa000, 0xfac6, 0xc696, 0x5490, 0x390c, 0x8400, 0x6669, 0x92c0, 0x8451 }, 16, 0x000aa320, 1},
++	{{0x98c0, 0x0b46, 0x2e74, 0x8009, 0xcf47, 0x2100, 0x8147, 0x2b0b, 0x8970, 0x98c0, 0xeb1f, 0x3284, 0x2110, 0x800a, 0x5013, 0x3b61 }, 16, 0x000aa340, 1},
++	{{0x3bc2, 0x0c46, 0x2e74, 0x8009, 0x676a, 0x2c0c, 0x89d4, 0xec1f, 0x5214, 0x68b2, 0x94c0, 0x7cef, 0x81cc, 0x4114, 0x3660, 0xa000 }, 16, 0x000aa360, 1},
++	{{0xf8c5, 0xfac6, 0x38a0, 0x3074, 0x8009, 0x90c0, 0x1290, 0x04a6, 0x3070, 0x8009, 0x9ac0, 0x3908, 0x8020, 0x90c0, 0x350a, 0x8001 }, 16, 0x000aa380, 1},
++	{{0x6469, 0x2718, 0x80f8, 0x3ca0, 0xa000, 0x6e10, 0x2b00, 0x8080, 0x6569, 0xe9ea, 0x96c0, 0xc696, 0x2518, 0x80e6, 0x3880, 0xa000 }, 16, 0x000aa3a0, 1},
++	{{0xe93b, 0x04f8, 0x9ee0, 0x38c0, 0xa000, 0x57d1, 0x280f, 0x80b0, 0x14df, 0xc381, 0x9ac0, 0xd594, 0xc48f, 0x3120, 0x2400, 0x8003 }, 16, 0x000aa3c0, 1},
++	{{0x94c0, 0xf343, 0xf401, 0x32c4, 0x33c0, 0x800a, 0xf0c3, 0x3284, 0x20f0, 0x800a, 0x2160, 0x9fff, 0x98c0, 0x7570, 0x67e0, 0x2160 }, 16, 0x000aa3e0, 1},
++	{{0x9fff, 0xda12, 0x3480, 0x8007, 0x3284, 0x20f0, 0x800a, 0x7c6b, 0x3b61, 0x27e0, 0x0b46, 0x2e74, 0x8009, 0x15f8, 0x9ee0, 0x98c0 }, 16, 0x000aa400, 1},
++	{{0x7ac2, 0xc945, 0x2b0b, 0x89d4, 0x05f8, 0x9ee0, 0xeb19, 0x5413, 0x7270, 0x90c0, 0x94c6, 0x676a, 0x4013, 0x8197, 0x3c20, 0xa000 }, 16, 0x000aa420, 1},
++	{{0x6e90, 0x38a0, 0x3074, 0x8009, 0xfec9, 0x96c0, 0xf9c8, 0x2302, 0x9df8, 0x1390, 0xfaca, 0x3820, 0xa000, 0xefee, 0x0913, 0xa400 }, 16, 0x000aa440, 1},
++	{{0x96c0, 0x4390, 0x2600, 0x80fe, 0x3640, 0xa000, 0x4591, 0xef3b, 0x4592, 0x04a6, 0x3070, 0x8009, 0x390b, 0x8040, 0x65e9, 0x94c7 }, 16, 0x000aa460, 1},
++	{{0x8414, 0x6c10, 0x92c3, 0x4097, 0x33a4, 0x3240, 0x800a, 0x7c48, 0x4097, 0x3b61, 0xef44, 0x676a, 0x81db, 0x3a20, 0xa000, 0x0b46 }, 16, 0x000aa480, 1},
++	{{0x2e74, 0x8009, 0xf8c8, 0x3284, 0x2350, 0x800a, 0x3620, 0xa000, 0x2b09, 0x89d4, 0x3820, 0xa000, 0xfac6, 0x2b00, 0x8090, 0x3660 }, 16, 0x000aa4a0, 1},
++	{{0xa000, 0xf8c5, 0xfec9, 0x38a0, 0xa000, 0xe9ea, 0x2000, 0x8040, 0x38c0, 0xa000, 0xe93b, 0x280f, 0x89c0, 0x38c0, 0xa000, 0x52d1 }, 16, 0x000aa4c0, 1},
++	{{0x280b, 0x89c4, 0x3c20, 0xa000, 0x280c, 0x85d0, 0x90c0, 0x351a, 0x8001, 0x9ac0, 0x2a02, 0x8002, 0x6569, 0x2be2, 0x9ffe, 0x94c0 }, 16, 0x000aa4e0, 1},
++	{{0xf9c8, 0x8481, 0x96c0, 0xfaca, 0x2304, 0x8040, 0x96c0, 0x5391, 0x2b03, 0x8012, 0x4392, 0x3620, 0xa000, 0x280a, 0x85d4, 0x52b4 }, 16, 0x000aa500, 1},
++	{{0x42bf, 0x92d0, 0x51b2, 0x64e4, 0x41bb, 0x96c0, 0xf9cb, 0x2102, 0x99fc, 0x3640, 0xa000, 0x9b40, 0xebee, 0x96c0, 0x5091, 0x2b03 }, 16, 0x000aa520, 1},
++	{{0x8038, 0x3820, 0xa000, 0xeb39, 0x2a02, 0x8002, 0x3840, 0xa000, 0x4093, 0x2808, 0x8dc0, 0x3c60, 0xa000, 0x2809, 0x8dc4, 0x90c0 }, 16, 0x000aa540, 1},
++	{{0x280a, 0x89d4, 0x3c20, 0xa000, 0x280c, 0x89d0, 0x90c0, 0x2be2, 0x9ffe, 0x56b4, 0x46b8, 0x92d0, 0x54b2, 0x6664, 0x44b9, 0x3284 }, 16, 0x000aa560, 1},
++	{{0x2a90, 0x800a, 0x94c0, 0xf9c8, 0xe8ee, 0x9ac0, 0x2304, 0x8100, 0x6d90, 0x2b03, 0x8026, 0x98c0, 0x37a1, 0x2000, 0x800c, 0xc684 }, 16, 0x000aa580, 1},
++	{{0x96c0, 0xffc7, 0x2b02, 0x8002, 0x96c0, 0x0742, 0x2e7c, 0x8009, 0x9ac0, 0x79c8, 0x0c46, 0x2e7c, 0x8009, 0xcd43, 0x3b48, 0x15be }, 16, 0x000aa5a0, 1},
++	{{0xca46, 0xec1d, 0x4594, 0x17bf, 0x0846, 0x2e7c, 0x8009, 0x90d0, 0xe81a, 0x4790, 0x98c0, 0x3be8, 0x3c0c, 0xbfff, 0xc0b2, 0x35e9 }, 16, 0x000aa5c0, 1},
++	{{0x3fff, 0xbfff, 0x1493, 0x3be8, 0x3c0c, 0xbfff, 0xde84, 0x0995, 0xa000, 0x32e4, 0x3a68, 0x8001, 0x4593, 0x98c0, 0x3ee8, 0x3c28 }, 16, 0x000aa5e0, 1},
++	{{0xbfff, 0xc1fd, 0x98c0, 0x3be8, 0x3c28, 0xbfff, 0xc5f7, 0x1096, 0x3ee8, 0x3c28, 0xbfff, 0x98c0, 0xdc80, 0xc0fb, 0x23e0, 0x9f0f }, 16, 0x000aa600, 1},
++	{{0x0196, 0x3ee8, 0x3c28, 0xbfff, 0x1293, 0x3be8, 0x3c28, 0xbfff, 0x3840, 0xa000, 0xde82, 0xfec9, 0xc683, 0x96c0, 0xc4fe, 0x0905 }, 16, 0x000aa620, 1},
++	{{0xa008, 0x0596, 0x3ee8, 0x3c28, 0xbfff, 0x3660, 0xa000, 0xfac6, 0xf8c5, 0x1596, 0x3ee8, 0x3c28, 0xbfff, 0xdc05, 0x0900, 0xa004 }, 16, 0x000aa640, 1},
++	{{0x4096, 0x5593, 0xdd85, 0x0903, 0xa080, 0x4396, 0x3480, 0xa000, 0x4616, 0x5396, 0xde03, 0x0904, 0xa001, 0x4493, 0x9f7d, 0x3480 }, 16, 0x000aa660, 1},
++	{{0xa000, 0x57d6, 0xd3a4, 0x9f7c, 0x2718, 0x8226, 0x3a40, 0xa000, 0x2e00, 0x9e00, 0x6f10, 0xebee, 0x9ac0, 0x2304, 0x8080, 0x90c0 }, 16, 0x000aa680, 1},
++	{{0x2b03, 0x8038, 0x98c0, 0xeb3e, 0x30c1, 0x2000, 0x800c, 0x96c0, 0xedeb, 0x2b0f, 0x8004, 0x98c0, 0x0042, 0x2e78, 0x8009, 0xeeef }, 16, 0x000aa6a0, 1},
++	{{0x96c0, 0xc484, 0x2500, 0x8080, 0x96c0, 0x2b02, 0x8002, 0x90c0, 0x9ac0, 0x7b50, 0x0946, 0x2e78, 0x8009, 0xcc46, 0x3a50, 0xca44 }, 16, 0x000aa6c0, 1},
++	{{0xe91c, 0x5391, 0x3701, 0x8080, 0x7ce8, 0x41bd, 0x0846, 0x2e78, 0x8009, 0x90c0, 0xe81a, 0x5790, 0x94d0, 0x3f00, 0x8080, 0x7c68 }, 16, 0x000aa6e0, 1},
++	{{0x40be, 0x96c0, 0x9b45, 0x2b03, 0x8020, 0x3c60, 0xa000, 0x280e, 0x89cc, 0x90c0, 0x2808, 0x89c8, 0x94c0, 0xc08c, 0xc188, 0x2b02 }, 16, 0x000aa700, 1},
++	{{0x8002, 0x9ac0, 0x78d0, 0x0a46, 0x2e78, 0x8009, 0xcd41, 0x3850, 0xc940, 0xea1d, 0x5292, 0x3503, 0x8080, 0x7de8, 0x43b8, 0x0c46 }, 16, 0x000aa720, 1},
++	{{0x2e78, 0x8009, 0x90c0, 0xec19, 0x5394, 0x94d0, 0x3707, 0x8080, 0x7fe8, 0x47be, 0x3820, 0xa000, 0xe9ee, 0x2e00, 0x9e24, 0x38a0 }, 16, 0x000aa740, 1},
++	{{0xa000, 0xe9ee, 0x2302, 0x8200, 0x96c0, 0xe93e, 0x2600, 0x8080, 0x3640, 0xa100, 0x53d1, 0xe93b, 0x3a40, 0xa000, 0x65e9, 0xfe49 }, 16, 0x000aa760, 1},
++	{{0x0bf8, 0x9edc, 0x01fa, 0x9ed8, 0x9ac1, 0x2e00, 0x9838, 0x90c0, 0x2e00, 0x9a38, 0x90c0, 0x3820, 0xa000, 0xee1a, 0x90c0, 0x90c0 }, 16, 0x000aa780, 1},
++	{{0x9ac0, 0x1bf8, 0x9ed8, 0x90c0, 0x1df8, 0x9edc, 0x5297, 0x101b, 0x5395, 0x2c53, 0x111b, 0x3284, 0x20f0, 0x800a, 0x9ac0, 0x0bf8 }, 16, 0x000aa7a0, 1},
++	{{0x9ed8, 0x6fd8, 0x2160, 0x9fff, 0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x3284, 0x20f0, 0x800a, 0x98c0, 0x77d0, 0x7457, 0x2160 }, 16, 0x000aa7c0, 1},
++	{{0x9fff, 0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x3b61, 0x071e, 0x1df8, 0x9edc, 0x276a, 0x001e, 0xef48, 0x94c0, 0xed48, 0x81a6 }, 16, 0x000aa7e0, 1},
++	{{0x0df8, 0x9edc, 0x3820, 0xa000, 0xfec9, 0x2e00, 0x8200, 0x3820, 0xa000, 0xf8c5, 0x2700, 0x8080, 0x3420, 0xa000, 0xebee, 0x3840 }, 16, 0x000aa800, 1},
++	{{0xa000, 0xeb3e, 0x280f, 0x89cc, 0x3c40, 0xa000, 0x0bf8, 0x9ed4, 0x90c0, 0x280e, 0x89c8, 0x1697, 0x3284, 0x20f0, 0x800a, 0x96c0 }, 16, 0x000aa820, 1},
++	{{0x5096, 0x2160, 0x9fff, 0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x3284, 0x20f0, 0x800a, 0x98c0, 0x7750, 0x7456, 0x2160, 0x9fff }, 16, 0x000aa840, 1},
++	{{0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x98c0, 0x18f8, 0x9ed4, 0x7be1, 0xee48, 0x27ea, 0xef48, 0x4618, 0x94c0, 0x4018, 0x81bc }, 16, 0x000aa860, 1},
++	{{0x08f8, 0x9ed4, 0x3660, 0xa000, 0xfac6, 0xfec9, 0x9f7d, 0x3680, 0xa000, 0x56d2, 0xc2fe, 0x0906, 0xa002, 0x767e, 0xdd04, 0x3480 }, 16, 0x000aa880, 1},
++	{{0xa000, 0x4212, 0x9f7c, 0x6c90, 0x3480, 0xa000, 0x4116, 0x27ee, 0x9ed0, 0xe7ee, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000aa8a0, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3284, 0x2cb0, 0x800a, 0x3880, 0x2ca4, 0x8009, 0x98c0, 0x3980 }, 16, 0x000aa8c0, 1},
++	{{0x3236, 0x8009, 0xc4fe, 0x2c00, 0x808a, 0x10d1, 0x3800, 0x2064, 0x8008, 0x96c0, 0x3119, 0x8001, 0xde00, 0x24e9, 0x3a00, 0x2064 }, 16, 0x000aa8e0, 1},
++	{{0x8008, 0x802b, 0x0411, 0x3de8, 0x2404, 0xbfff, 0x98c0, 0xe93c, 0x3be8, 0x2404, 0xbfff, 0x5c91, 0x90c0, 0xec41, 0x4c91, 0x51d0 }, 16, 0x000aa900, 1},
++	{{0x78c1, 0x4112, 0x5195, 0x0911, 0xa001, 0x4193, 0x9f71, 0x90c0, 0x33c4, 0x20c0, 0x800a, 0x2c10, 0x1a90, 0x39a0, 0x306c, 0x8009 }, 16, 0x000aa920, 1},
++	{{0x90c0, 0x1292, 0x54d1, 0x351d, 0x8020, 0x66e9, 0x8415, 0xd221, 0x800b, 0xd223, 0x8007, 0x6669, 0x840b, 0x94c0, 0xc081, 0x9f71 }, 16, 0x000aa940, 1},
++	{{0xc081, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3551, 0x24ea, 0xc481, 0x7961, 0xd612, 0x92c2, 0x6661, 0x94c6 }, 16, 0x000aa960, 1},
++	{{0x9f70, 0x6c40, 0x92c2, 0xd419, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6f10, 0x9620, 0x9720, 0x96c0, 0x6c90, 0x9e20, 0x9f20 }, 16, 0x000aa980, 1},
++	{{0x96c0, 0xe748, 0x2320, 0x83cc, 0x98c0, 0xf341, 0x0621, 0x3c6c, 0x8009, 0x98c0, 0x06c0, 0x210a, 0x8009, 0xefe8, 0x98c0, 0xc94e }, 16, 0x000aa9a0, 1},
++	{{0x33e4, 0x3c8a, 0x8001, 0x96c0, 0xc946, 0x2f08, 0x84b4, 0x96c0, 0xcdac, 0x280a, 0x8002, 0x96c0, 0x5211, 0x290e, 0x802e, 0x0210 }, 16, 0x000aa9c0, 1},
++	{{0xe9ee, 0x1716, 0xcbaa, 0x071a, 0xe93d, 0x1511, 0xecee, 0x051a, 0xc9a8, 0x94c0, 0xec3b, 0xedee, 0x1614, 0xed39, 0x3640, 0xa000 }, 16, 0x000aa9e0, 1},
++	{{0x461a, 0xcfa6, 0x1415, 0xebee, 0x041a, 0xc9a4, 0x3620, 0xa000, 0xeb3f, 0xecee, 0x1113, 0xcba2, 0x011a, 0xec39, 0x1114, 0xedee }, 16, 0x000aaa00, 1},
++	{{0x011a, 0xc9a0, 0x94c0, 0xed3b, 0xecee, 0x1015, 0xec39, 0x001a, 0xedee, 0x1114, 0xed7e, 0x011a, 0xebee, 0x1315, 0xeb7c, 0x031a }, 16, 0x000aaa20, 1},
++	{{0xe9ee, 0x1413, 0xe97a, 0x94c0, 0x441a, 0x9756, 0x5311, 0x0312, 0xebee, 0x96c0, 0xeb78, 0x2f09, 0x84cc, 0x92d0, 0x5613, 0x4619 }, 16, 0x000aaa40, 1},
++	{{0x98c0, 0x6f10, 0x6c10, 0xe9ee, 0xecee, 0x96c0, 0xe976, 0x2a0b, 0x802e, 0x1511, 0xec74, 0x051b, 0xe9ee, 0x1714, 0xe972, 0x071b }, 16, 0x000aaa60, 1},
++	{{0xedee, 0x1511, 0xed70, 0x051b, 0xecee, 0x1415, 0xec6e, 0x0413, 0xedee, 0x96c0, 0x5114, 0x2b09, 0x8002, 0x0111, 0xed6c, 0x1515 }, 16, 0x000aaa80, 1},
++	{{0xedee, 0x96c0, 0xed6a, 0x290c, 0x8002, 0x3600, 0xa100, 0x451c, 0xe9ee, 0x3600, 0xa100, 0x5415, 0xe966, 0x0414, 0xedee, 0x3600 }, 16, 0x000aaaa0, 1},
++	{{0xa100, 0xec4c, 0x5511, 0x051c, 0xed64, 0x3600, 0xa100, 0x52d5, 0xeeee, 0x3600, 0xa100, 0x421c, 0xee62, 0x3680, 0xa000, 0x53d6 }, 16, 0x000aaac0, 1},
++	{{0xee68, 0x96c0, 0x4314, 0x2c0d, 0x809a, 0x1316, 0xeced, 0x96c0, 0x4315, 0x2704, 0x8100, 0xec7a, 0x94c0, 0xed78, 0x969c, 0x0615 }, 16, 0x000aaae0, 1},
++	{{0x3c20, 0x3c74, 0x8009, 0x3542, 0x2074, 0x8009, 0x3d40, 0x2274, 0x8009, 0x3e20, 0x3e74, 0x8009, 0x90c0, 0x3610, 0xa100, 0x401e }, 16, 0x000aab00, 1},
++	{{0x401d, 0x001d, 0x401c, 0x9ac0, 0x2a0c, 0x80d2, 0x6d90, 0x2e00, 0x9828, 0x96c0, 0xe86a, 0x2c0d, 0x982c, 0x0d94, 0xc0b2, 0x96c0 }, 16, 0x000aab20, 1},
++	{{0xed3e, 0x2d0e, 0x8200, 0x96c0, 0x4e95, 0x2a0c, 0x9efe, 0x15d1, 0x39a0, 0x31e0, 0x800a, 0x3b1a, 0x8001, 0x6569, 0x90c0, 0x98c1 }, 16, 0x000aab40, 1},
++	{{0x2200, 0x807f, 0x90c0, 0xc5bf, 0x94c1, 0x4210, 0x4510, 0x92c3, 0x5a13, 0x90c0, 0x92c3, 0xeafc, 0x98c7, 0x32e4, 0x3a5c, 0x8001 }, 16, 0x000aab60, 1},
++	{{0x4a13, 0x4314, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc183, 0xc0b2, 0x9756, 0x9ac0, 0x2f0a, 0x8516, 0x90c0, 0x2f0f, 0x8542, 0x2660 }, 16, 0x000aab80, 1},
++	{{0x9fff, 0x94c8, 0x461a, 0x461f, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x82c0, 0x101d, 0x3284, 0x23a0, 0x800b, 0x5115, 0xe768 }, 16, 0x000aaba0, 1},
++	{{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x1251, 0xf486, 0x266a, 0x3a61, 0xeae8, 0x94c0, 0x535a, 0x8427 }, 16, 0x000aabc0, 1},
++	{{0x94c0, 0x7453, 0x9f44, 0x04fc, 0x9ff6, 0x2103, 0x8010, 0x96d0, 0x6448, 0x7553, 0x535a, 0x3453, 0x4058, 0x2448, 0x7553, 0x4050 }, 16, 0x000aabe0, 1},
++	{{0x9f70, 0x4251, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x280a, 0x8598, 0x94c0, 0x9620, 0x9720, 0x15d2, 0x3322, 0x3e74 }, 16, 0x000aac00, 1},
++	{{0x8009, 0x98c0, 0x3615, 0x80ff, 0x9e20, 0x9f20, 0x94c6, 0xefea, 0x6d90, 0x94c6, 0xef62, 0x4312, 0x1317, 0x52d2, 0x9ac0, 0x6f5d }, 16, 0x000aac20, 1},
++	{{0x3542, 0x2074, 0x8009, 0xe758, 0x98c0, 0xcb46, 0x3742, 0x2274, 0x8009, 0x96c0, 0xf499, 0x2a0e, 0x801c, 0x98c0, 0xebf9, 0x3222 }, 16, 0x000aac40, 1},
++	{{0x3c74, 0x8009, 0x1016, 0xebfc, 0x3680, 0xa100, 0xeb1b, 0xef1b, 0x3680, 0xa100, 0xed1b, 0x4013, 0x3820, 0xa100, 0xeb1a, 0x2e08 }, 16, 0x000aac60, 1},
++	{{0x8002, 0x3680, 0xa000, 0x5010, 0x4413, 0x3680, 0xa100, 0x4117, 0x4015, 0x11d2, 0xe9ea, 0x9ac0, 0x78c1, 0x3ca0, 0x3074, 0x8009 }, 16, 0x000aac80, 1},
++	{{0xe968, 0x37f9, 0x2e10, 0x0112, 0xedea, 0x96c0, 0x3617, 0x807f, 0xed66, 0x2718, 0x83aa, 0x0412, 0x3b40, 0x2074, 0x8009, 0x17d1 }, 16, 0x000aaca0, 1},
++	{{0x3860, 0x2ccc, 0x8009, 0x96c0, 0xfa45, 0x0907, 0xa005, 0x3640, 0xa000, 0x4711, 0xf846, 0x1194, 0x52d5, 0x9ac0, 0x2100, 0x8080 }, 16, 0x000aacc0, 1},
++	{{0x90c0, 0x331d, 0x9000, 0x26e9, 0xf142, 0x90c0, 0x98c1, 0x0902, 0xa004, 0x90c0, 0xc5fb, 0x94c1, 0x4215, 0xde82, 0x92c2, 0x4515 }, 16, 0x000aace0, 1},
++	{{0x5917, 0x90c0, 0xe9fc, 0x98c0, 0xe91b, 0x3264, 0x2010, 0x800b, 0xf941, 0x1917, 0x3d40, 0x2274, 0x8009, 0x2400, 0x8080, 0x94c0 }, 16, 0x000aad00, 1},
++	{{0xe9fc, 0xf442, 0x98c0, 0xe91d, 0x3860, 0x36a4, 0x8009, 0x3264, 0x2010, 0x800b, 0xf941, 0x1917, 0x3b20, 0x3c74, 0x8009, 0x2400 }, 16, 0x000aad20, 1},
++	{{0x8080, 0x94c0, 0xe9fc, 0xf442, 0x98c0, 0xe91b, 0x3860, 0x31b8, 0x8009, 0x3264, 0x2010, 0x800b, 0xf941, 0x3620, 0xa000, 0xf8c6 }, 16, 0x000aad40, 1},
++	{{0x5817, 0x3b20, 0x3e74, 0x8009, 0x3620, 0xa000, 0xe9e8, 0xe8fc, 0x96c0, 0xe970, 0x2100, 0x8080, 0x96c0, 0xe81b, 0x290c, 0x8008 }, 16, 0x000aad60, 1},
++	{{0x1314, 0xf102, 0x32a4, 0x2bd0, 0x800a, 0xf301, 0x1817, 0x3b40, 0x2074, 0x8009, 0x1014, 0xe9ec, 0x96c0, 0xe8fc, 0x2700, 0x8080 }, 16, 0x000aad80, 1},
++	{{0x94c0, 0xe964, 0xf702, 0x32a4, 0x2bd0, 0x800a, 0x94c0, 0xe81b, 0xf001, 0x1817, 0x3940, 0x2274, 0x8009, 0x96c0, 0x5414, 0x2c0b }, 16, 0x000aada0, 1},
++	{{0x8002, 0x96c0, 0xe8fc, 0x2500, 0x8080, 0x94c0, 0xe819, 0xf502, 0x32a4, 0x2bd0, 0x800a, 0x94c0, 0xe9eb, 0xf401, 0x1817, 0x3920 }, 16, 0x000aadc0, 1},
++	{{0x3c74, 0x8009, 0x1114, 0xeb42, 0x96c0, 0xe8fc, 0x2200, 0x8080, 0x94c0, 0xe819, 0xf202, 0x32a4, 0x2bd0, 0x800a, 0x94c0, 0xe9eb }, 16, 0x000aade0, 1},
++	{{0xf101, 0x2c90, 0x1617, 0xfac5, 0x2769, 0x3960, 0x2ae8, 0x8008, 0x94c7, 0xedea, 0x6e10, 0x96c6, 0xed64, 0x2400, 0x8080, 0x96c0 }, 16, 0x000aae00, 1},
++	{{0x4417, 0x2b03, 0x8054, 0x96c0, 0x94bd, 0x2304, 0x80ff, 0x2669, 0x3422, 0x3e74, 0x8009, 0x98c7, 0x3b40, 0x2074, 0x8009, 0x6f10 }, 16, 0x000aae20, 1},
++	{{0x98c6, 0x3ca0, 0x2004, 0x800c, 0xc681, 0x96c0, 0x969d, 0x2b02, 0x8002, 0x1317, 0x38a0, 0x2000, 0x800c, 0x2e59, 0x5259, 0x3414 }, 16, 0x000aae40, 1},
++	{{0x8100, 0x94c2, 0x3c13, 0x8100, 0x2fd9, 0x78c1, 0x7fc1, 0xcd47, 0x90c0, 0x3600, 0xa100, 0x6f59, 0xec1d, 0x3a00, 0xa100, 0x3416 }, 16, 0x000aae60, 1},
++	{{0x8100, 0xed1b, 0x5054, 0x2332, 0x1755, 0x3422, 0x3e74, 0x8009, 0x96c6, 0x62ab, 0x3c13, 0x8100, 0x2c59, 0x38c1, 0x45b8, 0x94d0 }, 16, 0x000aae80, 1},
++	{{0x7c41, 0x46bc, 0x1259, 0xcd40, 0x90c0, 0x98c0, 0x39e8, 0x3c0c, 0xbfff, 0xc0b2, 0x3a80, 0xa000, 0xec1d, 0x36e9, 0x3fff, 0xbfff }, 16, 0x000aaea0, 1},
++	{{0x3600, 0xa100, 0xed1b, 0x5554, 0x2229, 0x5155, 0x62b8, 0x4590, 0x4494, 0x5491, 0xdf04, 0x0996, 0xa000, 0x32e4, 0x3a68, 0x8001 }, 16, 0x000aaec0, 1},
++	{{0x4691, 0x9ac0, 0x6f90, 0x3ce8, 0x3c28, 0xbfff, 0xc0fd, 0x98c0, 0x39e8, 0x3c28, 0xbfff, 0xc1f7, 0x1594, 0x3de8, 0x3c28, 0xbfff }, 16, 0x000aaee0, 1},
++	{{0x9ac0, 0xdc05, 0x3be8, 0x3c28, 0xbfff, 0xc2fb, 0x0091, 0x39e8, 0x3c28, 0xbfff, 0x96c0, 0x5395, 0x26e0, 0x9f0f, 0x3c20, 0xa000 }, 16, 0x000aaf00, 1},
++	{{0xdc83, 0x3ce8, 0x3c28, 0xbfff, 0xf8c6, 0x0191, 0xc481, 0x1393, 0x3be8, 0x3c28, 0xbfff, 0x3a20, 0xa000, 0x280d, 0x9e12, 0xdd03 }, 16, 0x000aaf20, 1},
++	{{0xc3fe, 0x9ac0, 0x0902, 0xa004, 0x90c0, 0x2304, 0x80ff, 0x0291, 0x36ea, 0x3c28, 0xbfff, 0x1593, 0x3960, 0x2ae8, 0x8008, 0x98c0 }, 16, 0x000aaf40, 1},
++	{{0x2b03, 0x805c, 0xdf05, 0xfac5, 0x9ac0, 0x0906, 0xa080, 0x90c0, 0x2b02, 0x8002, 0x0694, 0x3820, 0x3c74, 0x8009, 0x0415, 0x3ca0 }, 16, 0x000aaf60, 1},
++	{{0x3000, 0x800c, 0x1293, 0x3da0, 0x3004, 0x800c, 0x98c0, 0xdd82, 0x3b40, 0x2274, 0x8009, 0x0903, 0xa001, 0x3480, 0xa000, 0x4396 }, 16, 0x000aaf80, 1},
++	{{0x1417, 0x5259, 0x6dd7, 0x3413, 0x8100, 0x94c2, 0x3c14, 0x8100, 0x2cd7, 0x7bc1, 0x7cc1, 0xcf41, 0x90c0, 0x2dd7, 0xe81f, 0x98c0 }, 16, 0x000aafa0, 1},
++	{{0x3413, 0x8100, 0xef1b, 0x5350, 0x9ac6, 0x5357, 0x90c0, 0x60bd, 0x3c14, 0x8100, 0x21bd, 0x2d57, 0x3bc1, 0x3820, 0x3c74, 0x8009 }, 16, 0x000aafc0, 1},
++	{{0x94d0, 0x7d41, 0x43bc, 0x01bd, 0xcf42, 0x5259, 0x9ac0, 0x6e90, 0xe81f, 0x39e8, 0x3c28, 0xbfff, 0x1350, 0xef1b, 0x21bd, 0x5457 }, 16, 0x000aafe0, 1},
++	{{0x6028, 0x0094, 0x3ce8, 0x3c28, 0xbfff, 0x4395, 0x0522, 0x3c70, 0x8009, 0x5491, 0x399a, 0x8000, 0x6569, 0x8415, 0x7ac1, 0x0522 }, 16, 0x000ab000, 1},
++	{{0x3c70, 0x8009, 0x5494, 0x3998, 0x8000, 0x6469, 0x81f1, 0x98c0, 0x3de8, 0x3c28, 0xbfff, 0xc0fd, 0x98c0, 0x39e8, 0x3c28, 0xbfff }, 16, 0x000ab020, 1},
++	{{0xc6fe, 0x1295, 0x38e8, 0x3c28, 0xbfff, 0xdc02, 0x0900, 0xa002, 0x4091, 0x5291, 0xdf02, 0x0906, 0xa001, 0x4690, 0x3640, 0xa000 }, 16, 0x000ab040, 1},
++	{{0xe8ea, 0xe9e8, 0x96c0, 0xe868, 0x2c00, 0x809c, 0x11d0, 0xe97c, 0x96c0, 0x331a, 0x8004, 0xebe9, 0x2569, 0x12d1, 0xeb3c, 0x94c0 }, 16, 0x000ab060, 1},
++	{{0x7941, 0x809f, 0x377a, 0x2e10, 0x0211, 0xc7fb, 0x3640, 0xa000, 0x5313, 0xede8, 0x96c0, 0x71f6, 0xc6fd, 0xed72, 0x94c0, 0xeced }, 16, 0x000ab080, 1},
++	{{0x8081, 0x96c0, 0x4411, 0x2602, 0x9828, 0x96c0, 0x52d0, 0x2d09, 0x9824, 0x96c0, 0xdf82, 0xebe9, 0xec68, 0x3820, 0xa000, 0x76ff }, 16, 0x000ab0a0, 1},
++	{{0x4710, 0xeb3e, 0x3c80, 0xa000, 0x2909, 0x8200, 0x90c0, 0x3b1c, 0x8002, 0x6669, 0x3480, 0xa000, 0x9c52, 0xea66, 0x3482, 0xa000 }, 16, 0x000ab0c0, 1},
++	{{0xec66, 0x3482, 0xa000, 0x51d4, 0x94c2, 0x0901, 0xa001, 0x3482, 0xa000, 0x4114, 0x57d0, 0xdf07, 0x4610, 0x54d2, 0x391f, 0x80ff }, 16, 0x000ab0e0, 1},
++	{{0x75d7, 0x7dc8, 0xdd9f, 0x4312, 0x03c0, 0x210a, 0x8009, 0x53d5, 0xd883, 0x4115, 0x4994, 0x3420, 0xa000, 0x4993, 0x3420, 0xa000 }, 16, 0x000ab100, 1},
++	{{0xe8e8, 0xe872, 0x3640, 0xa000, 0x57d0, 0xe8e8, 0x27e9, 0xe87a, 0x94c0, 0x5990, 0x842d, 0x280b, 0x9a2c, 0x1611, 0xe944, 0x94c0 }, 16, 0x000ab120, 1},
++	{{0xeb89, 0xf944, 0x3480, 0xa000, 0x4610, 0x3623, 0xa000, 0x280b, 0x9812, 0x98c7, 0x31a4, 0x318a, 0x800a, 0xfb44, 0x3420, 0xa000 }, 16, 0x000ab140, 1},
++	{{0xe8e8, 0xe876, 0x96c0, 0x5990, 0x280b, 0x9c28, 0x90c0, 0x1211, 0xe944, 0x94c0, 0xeb89, 0xf944, 0x3480, 0xa000, 0x4210, 0x3623 }, 16, 0x000ab160, 1},
++	{{0xa000, 0x2809, 0x9a12, 0x92c3, 0xf944, 0x3620, 0xa000, 0xece8, 0xf5c4, 0x0590, 0xec68, 0x3680, 0xa000, 0x5610, 0x5514, 0x3880 }, 16, 0x000ab180, 1},
++	{{0xa000, 0x7f4f, 0xec66, 0xe842, 0x1414, 0xe778, 0x6b15, 0x6768, 0x94c3, 0x3d46, 0x8000, 0x7f6f, 0x7f48, 0x6765, 0x7f48, 0x775e }, 16, 0x000ab1a0, 1},
++	{{0x4654, 0x3480, 0xa000, 0x4658, 0x5016, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x3480, 0xa000, 0x4010, 0x90c0 }, 16, 0x000ab1c0, 1},
++	{{0x32e4, 0x3a68, 0x8001, 0xc0b2, 0x3ba0, 0x306c, 0x8009, 0x90c0, 0x52d3, 0xd121, 0x90c0, 0x94c6, 0x8016, 0xc082, 0x92c2, 0x4013 }, 16, 0x000ab1e0, 1},
++	{{0xd123, 0x90c0, 0x92c2, 0xc284, 0x92c2, 0x4213, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ab200, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3880, 0x2ca4, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ab220, 1},
++	{{0x2400, 0x808d, 0x0347, 0x2eac, 0x8009, 0x3684, 0x8003, 0x94c0, 0x7a41, 0x9f70, 0x3474, 0x0440, 0x2eac, 0x8009, 0x90c0, 0x90c0 }, 16, 0x000ab240, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20d0 }, 16, 0x000ab260, 1},
++	{{0x800a, 0xe748, 0x33c4, 0x2050, 0x800a, 0x0dc6, 0x38d0, 0x8008, 0x3e20, 0x336c, 0x8009, 0x2d0b, 0x8026, 0x17d3, 0x0a86, 0x22d8 }, 16, 0x000ab280, 1},
++	{{0x8009, 0x3f19, 0x80ff, 0x7cc2, 0xc841, 0x90c0, 0xe81e, 0x5790, 0x4792, 0x0fc6, 0x38d0, 0x8008, 0x0d86, 0x22d8, 0x8009, 0x2f0b }, 16, 0x000ab2a0, 1},
++	{{0x8026, 0x10d3, 0xed44, 0x30cf, 0x8208, 0xc847, 0x90c0, 0xe8fe, 0xe81e, 0x5290, 0x4295, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d }, 16, 0x000ab2c0, 1},
++	{{0x804e, 0x52d5, 0x3519, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0986, 0x22d8, 0x8009, 0x90c0, 0xe948, 0x4011, 0x0ac6, 0x38d0 }, 16, 0x000ab2e0, 1},
++	{{0x8008, 0x90c0, 0x2a0f, 0x804e, 0x56d7, 0x3cc9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0986, 0x22d8, 0x8009, 0x3820, 0x336c }, 16, 0x000ab300, 1},
++	{{0x8009, 0xe94a, 0x4011, 0x0dc6, 0x38d0, 0x8008, 0x0c86, 0x22d0, 0x8009, 0x2d0e, 0x8024, 0x51d6, 0x3318, 0x80ff, 0x7c42, 0xcd40 }, 16, 0x000ab320, 1},
++	{{0x90c0, 0xed18, 0x5495, 0x4494, 0x0ec6, 0x38d0, 0x8008, 0x0a86, 0x22d0, 0x8009, 0x2e09, 0x8024, 0x13d1, 0xea44, 0x36c8, 0x8208 }, 16, 0x000ab340, 1},
++	{{0xcc40, 0x90c0, 0xecfe, 0xec18, 0x5694, 0x4692, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x804c, 0x52d4, 0x351f, 0x80ff, 0x3244 }, 16, 0x000ab360, 1},
++	{{0x3d90, 0x800a, 0x7467, 0x0d86, 0x22d0, 0x8009, 0x90c0, 0xed48, 0x4015, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x804c, 0x53d5 }, 16, 0x000ab380, 1},
++	{{0x36ce, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7466, 0x0886, 0x22d0, 0x8009, 0x90c0, 0xe84a, 0x4010, 0x0cc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ab3a0, 1},
++	{{0x2c0d, 0x8100, 0x56d5, 0x3d1c, 0x8002, 0x2669, 0x06c7, 0x2a40, 0x8009, 0x8429, 0x96c0, 0x6769, 0x2d0b, 0x8042, 0x94c0, 0x5013 }, 16, 0x000ab3c0, 1},
++	{{0x841f, 0x32a4, 0x34f0, 0x800b, 0x01a4, 0x33be, 0x8009, 0x30a4, 0x3402, 0x800a, 0x0080, 0x2ca0, 0x8009, 0x6e90, 0x0580, 0x2ca0 }, 16, 0x000ab3e0, 1},
++	{{0x8009, 0x2c00, 0x80d8, 0x3920, 0x336c, 0x8009, 0x98c0, 0xed3c, 0x0b86, 0x22dc, 0x8009, 0x50d5, 0x311c, 0x80ff, 0x7e42, 0xca44 }, 16, 0x000ab400, 1},
++	{{0x90c0, 0xea19, 0x5692, 0x4693, 0x0dc6, 0x38d0, 0x8008, 0x0886, 0x22dc, 0x8009, 0x2d0c, 0x8028, 0x15d4, 0xe844, 0x3ac8, 0x8208 }, 16, 0x000ab420, 1},
++	{{0xca40, 0x90c0, 0xeafe, 0xea19, 0x5592, 0x4590, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0e, 0x8050, 0x50d6, 0x3119, 0x80ff, 0x3244 }, 16, 0x000ab440, 1},
++	{{0x3d90, 0x800a, 0x7461, 0x0e86, 0x22dc, 0x8009, 0x90c0, 0xee48, 0x4016, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0b, 0x8050, 0x54d3 }, 16, 0x000ab460, 1},
++	{{0x38c9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0986, 0x22dc, 0x8009, 0x3820, 0x336c, 0x8009, 0xe94a, 0x4011, 0x0dc6, 0x38d0 }, 16, 0x000ab480, 1},
++	{{0x8008, 0x0e86, 0x22d4, 0x8009, 0x2d0b, 0x802a, 0x54d3, 0x391d, 0x80ff, 0x7ec2, 0xcc45, 0x90c0, 0xec18, 0x5494, 0x4496, 0x0bc6 }, 16, 0x000ab4a0, 1},
++	{{0x38d0, 0x8008, 0x0e86, 0x22d4, 0x8009, 0x2b09, 0x802a, 0x13d1, 0xee44, 0x36ca, 0x8208, 0xca42, 0x90c0, 0xeafe, 0xea18, 0x5792 }, 16, 0x000ab4c0, 1},
++	{{0x4796, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x8052, 0x55d5, 0x3b1e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x0f86, 0x22d4 }, 16, 0x000ab4e0, 1},
++	{{0x8009, 0x90c0, 0xef48, 0x4017, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0c, 0x8052, 0x51d4, 0x32c9, 0x8208, 0x3244, 0x3d90, 0x800a }, 16, 0x000ab500, 1},
++	{{0x7461, 0x0f86, 0x22d4, 0x8009, 0x3860, 0x3d54, 0x8009, 0x98c0, 0xef4a, 0x3224, 0x3010, 0x800b, 0x4017, 0x3224, 0x3010, 0x800b }, 16, 0x000ab520, 1},
++	{{0x3860, 0x3f18, 0x8009, 0x3224, 0x3010, 0x800b, 0x3860, 0x3b90, 0x8009, 0x3224, 0x3010, 0x800b, 0x3880, 0x20dc, 0x8009, 0x0fc6 }, 16, 0x000ab540, 1},
++	{{0x38d0, 0x8008, 0x3860, 0x3d54, 0x8009, 0x2f09, 0x8344, 0x290e, 0x825c, 0x3244, 0x2fe0, 0x800b, 0xfe41, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000ab560, 1},
++	{{0x3860, 0x3f18, 0x8009, 0x2a09, 0x8344, 0x290c, 0x825c, 0x3244, 0x2fe0, 0x800b, 0xfc41, 0x0bc6, 0x38d0, 0x8008, 0x3860, 0x3b90 }, 16, 0x000ab580, 1},
++	{{0x8009, 0x2b09, 0x8344, 0x290f, 0x825c, 0x3244, 0x2fe0, 0x800b, 0xff41, 0x0dc6, 0x38d0, 0x8008, 0x3880, 0x20dc, 0x8009, 0x2d09 }, 16, 0x000ab5a0, 1},
++	{{0x8300, 0x290f, 0x8200, 0x3244, 0x2fe0, 0x800b, 0xff41, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xc182, 0x98c0, 0xf142, 0x3860, 0x22f4 }, 16, 0x000ab5c0, 1},
++	{{0x8009, 0x2909, 0x8400, 0x290e, 0x8060, 0x3244, 0x35b0, 0x800b, 0xfe41, 0x2d90, 0x09c6, 0x38d0, 0x8008, 0x98c0, 0xf342, 0x3860 }, 16, 0x000ab5e0, 1},
++	{{0x27e0, 0x8009, 0x2909, 0x8420, 0x290c, 0x8050, 0x3244, 0x35b0, 0x800b, 0xfc41, 0x98c0, 0x0cc6, 0x38d0, 0x8008, 0xc481, 0x98c0 }, 16, 0x000ab600, 1},
++	{{0xf442, 0x3860, 0x2ccc, 0x8009, 0x2c09, 0x8440, 0x290e, 0x8040, 0x3244, 0x35b0, 0x800b, 0xfe41, 0x98c0, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000ab620, 1},
++	{{0xc381, 0x98c0, 0xf342, 0x3860, 0x36a4, 0x8009, 0x2c09, 0x8440, 0x290c, 0x8040, 0x3244, 0x35b0, 0x800b, 0xfc41, 0x98c0, 0x0ac6 }, 16, 0x000ab640, 1},
++	{{0x38d0, 0x8008, 0xc281, 0x98c0, 0xf242, 0x3860, 0x31b8, 0x8009, 0x2a09, 0x8440, 0x290b, 0x8040, 0x3244, 0x35b0, 0x800b, 0xfb41 }, 16, 0x000ab660, 1},
++	{{0x98c0, 0xc381, 0x3960, 0x27e0, 0x8009, 0x32a4, 0x26c0, 0x800b, 0x98c0, 0xf341, 0x3840, 0x3508, 0x8009, 0x98c0, 0xc182, 0x3960 }, 16, 0x000ab680, 1},
++	{{0x22f4, 0x8009, 0x32a4, 0x26c0, 0x800b, 0x98c0, 0xf141, 0x3840, 0x2eb0, 0x8009, 0x3284, 0x3c60, 0x800b, 0x3820, 0x2ff0, 0x800c }, 16, 0x000ab6a0, 1},
++	{{0x2c90, 0x2d10, 0x2f90, 0x0fc6, 0x38d0, 0x8008, 0x3651, 0x3c40, 0x3b62, 0x8009, 0x9ac0, 0x2f0b, 0x80b6, 0x90c0, 0x2500, 0x8140 }, 16, 0x000ab6c0, 1},
++	{{0x96c0, 0x5013, 0x2704, 0x8050, 0x98c0, 0x6c7c, 0x7452, 0x2b02, 0x8002, 0x34d4, 0x3e40, 0x3b68, 0x8009, 0x2d7d, 0x34d2, 0x3840 }, 16, 0x000ab6e0, 1},
++	{{0x3b64, 0x8009, 0x96c0, 0x4514, 0x2300, 0x8050, 0x0740, 0x3b60, 0x8009, 0x94c8, 0x4878, 0x487e, 0x9ac0, 0x7550, 0x3860, 0x2072 }, 16, 0x000ab700, 1},
++	{{0x8009, 0x9f43, 0x98c0, 0x7452, 0x74d2, 0x2b02, 0x8002, 0x0510, 0x3d60, 0x2078, 0x8009, 0x3860, 0x2074, 0x8009, 0x0260, 0x2070 }, 16, 0x000ab720, 1},
++	{{0x8009, 0x94c8, 0x4878, 0x487d, 0x9ac0, 0x7550, 0x3d40, 0x3dea, 0x8009, 0x9f43, 0x98c0, 0x7452, 0x74d2, 0x2b02, 0x8002, 0x0515 }, 16, 0x000ab740, 1},
++	{{0x3e40, 0x3df0, 0x8009, 0x3f40, 0x3dec, 0x8009, 0x0240, 0x3de8, 0x8009, 0x94c8, 0x487f, 0x487e, 0xe768, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000ab760, 1},
++	{{0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x5210, 0x280b, 0x8002, 0x51d3, 0x64e9, 0x94c0, 0xf585 }, 16, 0x000ab780, 1},
++	{{0x803d, 0x96c0, 0x70f2, 0x2b0d, 0x8002, 0x94c7, 0x66ea, 0x6d10, 0x8427, 0x96c0, 0x9b45, 0x2b03, 0x8008, 0x3941, 0x1411, 0xcc42 }, 16, 0x000ab7a0, 1},
++	{{0x90c0, 0xecfc, 0xec1d, 0x1514, 0x4414, 0x4519, 0x92d0, 0x53d3, 0x71f2, 0x92c3, 0x6d10, 0x4210, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ab7c0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x270e, 0x8020, 0x32c4, 0x29f0, 0x800a, 0x98c0, 0xe7ee, 0x07a4, 0x33be, 0x8009 }, 16, 0x000ab7e0, 1},
++	{{0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0b, 0x804e, 0x55d3, 0x3b1c, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7464, 0x0e86, 0x22d8, 0x8009 }, 16, 0x000ab800, 1},
++	{{0x90c0, 0xee48, 0x4016, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290b, 0x804e, 0x56d3, 0x3ccc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464 }, 16, 0x000ab820, 1},
++	{{0x0a86, 0x22d8, 0x8009, 0x90c0, 0xea4a, 0x4012, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x804c, 0x50d4, 0x3119, 0x80ff, 0x3244 }, 16, 0x000ab840, 1},
++	{{0x3d90, 0x800a, 0x7461, 0x0986, 0x22d0, 0x8009, 0x90c0, 0xe948, 0x4011, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290b, 0x804c, 0x52d3 }, 16, 0x000ab860, 1},
++	{{0x34c9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0c86, 0x22d0, 0x8009, 0x90c0, 0xec4a, 0x4014, 0x0fc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ab880, 1},
++	{{0x2f0a, 0x8050, 0x53d2, 0x371b, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7463, 0x0e86, 0x22dc, 0x8009, 0x90c0, 0xee48, 0x4016, 0x0dc6 }, 16, 0x000ab8a0, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x8050, 0x50d4, 0x30cc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464, 0x0f86, 0x22dc, 0x8009, 0x90c0 }, 16, 0x000ab8c0, 1},
++	{{0xef4a, 0x4017, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0d, 0x8052, 0x52d5, 0x351a, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7462, 0x0d86 }, 16, 0x000ab8e0, 1},
++	{{0x22d4, 0x8009, 0x90c0, 0xed48, 0x4015, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0c, 0x8052, 0x56d4, 0x3cca, 0x8208, 0x3244, 0x3d90 }, 16, 0x000ab900, 1},
++	{{0x800a, 0x7462, 0x0b86, 0x22d4, 0x8009, 0x3920, 0x336c, 0x8009, 0xeb4a, 0x4013, 0x0484, 0x2ca0, 0x8009, 0x266a, 0x3a61, 0x0c86 }, 16, 0x000ab920, 1},
++	{{0x22d0, 0x8009, 0x8429, 0x0480, 0x2ca0, 0x8009, 0x0426, 0x336c, 0x8009, 0x4494, 0x0986, 0x22d0, 0x8009, 0x0026, 0x336c, 0x8009 }, 16, 0x000ab940, 1},
++	{{0x98c0, 0xe944, 0x30a4, 0x39b4, 0x800a, 0x4091, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0e, 0x8024, 0x16d6, 0x0a86, 0x22d0, 0x8009 }, 16, 0x000ab960, 1},
++	{{0x3d1e, 0x80ff, 0x7f42, 0xcb46, 0x90c0, 0xeb19, 0x5293, 0x4292, 0x0ac6, 0x38d0, 0x8008, 0x0f86, 0x22d0, 0x8009, 0x2a0d, 0x8024 }, 16, 0x000ab980, 1},
++	{{0x15d5, 0xef44, 0x3aca, 0x8208, 0xce42, 0x90c0, 0xeefe, 0xee19, 0x5596, 0x4597, 0x98c0, 0x3c20, 0x218a, 0x8009, 0xc381, 0x98c0 }, 16, 0x000ab9a0, 1},
++	{{0x0b86, 0x22d8, 0x8009, 0xc081, 0x1414, 0x02a4, 0x33be, 0x8009, 0x9ac0, 0xd221, 0x5993, 0x3880, 0x2be0, 0x8009, 0x94c0, 0xeb48 }, 16, 0x000ab9c0, 1},
++	{{0x804d, 0x1513, 0xedeb, 0x94c0, 0xed64, 0xeb42, 0x1495, 0x5113, 0x94c0, 0xf206, 0xf307, 0x94c0, 0xf105, 0xf442, 0x32e4, 0x208e }, 16, 0x000ab9e0, 1},
++	{{0x800a, 0x94c0, 0xf501, 0xc7a0, 0x98c0, 0xc6a0, 0x3980, 0x2be0, 0x8009, 0x3224, 0x3990, 0x800a, 0x98c0, 0xf601, 0x3820, 0x2178 }, 16, 0x000aba00, 1},
++	{{0x8009, 0x31a4, 0x3a62, 0x800a, 0x98c0, 0x0f86, 0x22d8, 0x8009, 0xf007, 0x03a4, 0x33be, 0x8009, 0x1997, 0xef48, 0x1017, 0xebef }, 16, 0x000aba20, 1},
++	{{0x94c0, 0xeb64, 0xef42, 0x1293, 0x5417, 0x94c0, 0xf306, 0xf242, 0x94c0, 0xf405, 0xf001, 0x32e4, 0x208e, 0x800a, 0x3880, 0x26a0 }, 16, 0x000aba40, 1},
++	{{0x8009, 0x98c0, 0x3c00, 0x3816, 0x8009, 0xc481, 0x0b86, 0x22d0, 0x8009, 0x1014, 0x02a4, 0x33be, 0x8009, 0x9ac0, 0xd021, 0x5993 }, 16, 0x000aba60, 1},
++	{{0x3880, 0x2a60, 0x8009, 0x94c0, 0xeb48, 0x8045, 0x1013, 0xedeb, 0x94c0, 0xed64, 0xeb42, 0x1313, 0x5195, 0x94c0, 0xf407, 0xf206 }, 16, 0x000aba80, 1},
++	{{0x94c0, 0xf305, 0xf142, 0x32e4, 0x208e, 0x800a, 0xf001, 0x98c0, 0xf701, 0x3980, 0x2a60, 0x8009, 0x3224, 0x3990, 0x800a, 0x3800 }, 16, 0x000abaa0, 1},
++	{{0x3804, 0x8009, 0x31a4, 0x3b08, 0x800a, 0x98c0, 0x0a86, 0x22d0, 0x8009, 0xc181, 0x98c0, 0xf107, 0x05a4, 0x33be, 0x8009, 0x1992 }, 16, 0x000abac0, 1},
++	{{0xea48, 0x1012, 0xebea, 0x94c0, 0xea42, 0xeb64, 0x1193, 0x5312, 0x94c0, 0xf506, 0xf142, 0x94c0, 0xf305, 0xf001, 0x32e4, 0x208e }, 16, 0x000abae0, 1},
++	{{0x800a, 0x3880, 0x23a0, 0x8009, 0x3900, 0x34a6, 0x8009, 0x0e86, 0x22dc, 0x8009, 0x1411, 0x06a4, 0x33be, 0x8009, 0x96c0, 0xd221 }, 16, 0x000abb00, 1},
++	{{0xc481, 0x5996, 0x94c0, 0xee48, 0x804d, 0x1516, 0xedee, 0x94c0, 0xed64, 0xee42, 0x1016, 0x5395, 0x94c0, 0xf407, 0xf606, 0x94c0 }, 16, 0x000abb20, 1},
++	{{0xf005, 0xf342, 0x32e4, 0x208e, 0x800a, 0x98c0, 0xf501, 0x3880, 0x2520, 0x8009, 0x98c0, 0xf701, 0x3980, 0x2520, 0x8009, 0x3224 }, 16, 0x000abb40, 1},
++	{{0x3990, 0x800a, 0x3800, 0x3494, 0x8009, 0x31a4, 0x3bae, 0x800a, 0x98c0, 0x0f86, 0x22dc, 0x8009, 0xc381, 0x98c0, 0xf307, 0x00a4 }, 16, 0x000abb60, 1},
++	{{0x33be, 0x8009, 0x1997, 0xef48, 0x1317, 0xebef, 0x94c0, 0xef42, 0xeb64, 0x1593, 0x5217, 0x94c0, 0xf006, 0xf542, 0x94c0, 0xf205 }, 16, 0x000abb80, 1},
++	{{0xf301, 0x32e4, 0x208e, 0x800a, 0x3880, 0x22e0, 0x8009, 0x98c0, 0x3e00, 0x3212, 0x8009, 0xc481, 0x0b86, 0x22d4, 0x8009, 0x1316 }, 16, 0x000abba0, 1},
++	{{0x3880, 0x28e0, 0x8009, 0x9ac0, 0xd1a1, 0x03a4, 0x33be, 0x8009, 0x5993, 0x94c0, 0xeb48, 0x8045, 0x1113, 0xedeb, 0x94c0, 0xed64 }, 16, 0x000abbc0, 1},
++	{{0xeb42, 0x1213, 0x5595, 0x94c0, 0xf407, 0xf306, 0x94c0, 0xf205, 0xf542, 0x32e4, 0x208e, 0x800a, 0xf101, 0x98c0, 0xf701, 0x3980 }, 16, 0x000abbe0, 1},
++	{{0x28e0, 0x8009, 0x3224, 0x3990, 0x800a, 0x3800, 0x3200, 0x8009, 0x31a4, 0x3c54, 0x800a, 0x98c0, 0x0e86, 0x22d4, 0x8009, 0xc481 }, 16, 0x000abc00, 1},
++	{{0x98c0, 0xf407, 0x05a4, 0x33be, 0x8009, 0x1996, 0xee48, 0x1116, 0xefee, 0x94c0, 0xee42, 0xef64, 0x1497, 0x5216, 0x94c0, 0xf506 }, 16, 0x000abc20, 1},
++	{{0xf442, 0x94c0, 0xf205, 0xf101, 0x32e4, 0x208e, 0x800a, 0x3880, 0x25e0, 0x8009, 0x09c6, 0x38d0, 0x8008, 0x3840, 0x3508, 0x8009 }, 16, 0x000abc40, 1},
++	{{0x290f, 0x8100, 0x13d7, 0x3980, 0x23a0, 0x8009, 0x371b, 0x8002, 0x65e9, 0x844d, 0x32a4, 0x30b0, 0x800b, 0xf741, 0x98c0, 0xf741 }, 16, 0x000abc60, 1},
++	{{0x3980, 0x23a0, 0x8009, 0x3244, 0x2d10, 0x800b, 0x3860, 0x3d54, 0x8009, 0x98c0, 0xf741, 0x3980, 0x22e0, 0x8009, 0x3244, 0x2d10 }, 16, 0x000abc80, 1},
++	{{0x800b, 0x3860, 0x3f18, 0x8009, 0x98c0, 0xf741, 0x3980, 0x25e0, 0x8009, 0x3244, 0x2d10, 0x800b, 0x3860, 0x3b90, 0x8009, 0x98c0 }, 16, 0x000abca0, 1},
++	{{0xf701, 0x3980, 0x23a0, 0x8009, 0x32a4, 0x3790, 0x800a, 0x3840, 0x3b60, 0x8009, 0x98c0, 0xf701, 0x3980, 0x22e0, 0x8009, 0x32a4 }, 16, 0x000abcc0, 1},
++	{{0x3790, 0x800a, 0x3860, 0x2070, 0x8009, 0x98c0, 0xf701, 0x3980, 0x25e0, 0x8009, 0x32a4, 0x3790, 0x800a, 0x3840, 0x3de8, 0x8009 }, 16, 0x000abce0, 1},
++	{{0x27ea, 0x3657, 0x3880, 0x2460, 0x8009, 0x94c0, 0x7a61, 0x841d, 0x9f44, 0x1018, 0x3f80, 0x2760, 0x8009, 0x2103, 0x800a, 0x94c8 }, 16, 0x000abd00, 1},
++	{{0x401f, 0x5018, 0x4017, 0x27ea, 0x3757, 0x3c80, 0x2820, 0x8009, 0x8479, 0x3d80, 0x2760, 0x8009, 0x3a80, 0x25e0, 0x8009, 0x3f80 }, 16, 0x000abd20, 1},
++	{{0x22e0, 0x8009, 0x3e80, 0x23a0, 0x8009, 0x3b80, 0x26a0, 0x8009, 0x98c0, 0x05a6, 0x33b8, 0x8009, 0xfc44, 0x96c0, 0x7ac1, 0xfd43 }, 16, 0x000abd40, 1},
++	{{0xfa42, 0x94c0, 0xff41, 0xe9ee, 0x94c0, 0xe8eb, 0xfc45, 0x94c0, 0xfd46, 0xfa47, 0x3224, 0x3120, 0x800c, 0x98c0, 0xfb48, 0x05a2 }, 16, 0x000abd60, 1},
++	{{0x33b8, 0x8009, 0x96c0, 0x7b61, 0xfcc5, 0xfdc6, 0x96c0, 0x676a, 0xfac7, 0xfbc8, 0x94c0, 0xee42, 0xef42, 0x94c0, 0xeb42, 0xea42 }, 16, 0x000abd80, 1},
++	{{0x81b0, 0x94c0, 0xed42, 0xec42, 0x0ac6, 0x38d0, 0x8008, 0x3980, 0x2760, 0x8009, 0x2a0d, 0x8100, 0x16d5, 0x3840, 0x2eb0, 0x8009 }, 16, 0x000abda0, 1},
++	{{0x3d1e, 0x8002, 0x6769, 0x8479, 0x32a4, 0x30b0, 0x800b, 0xf741, 0x98c0, 0x3181, 0x2760, 0x8009, 0xf742, 0x94c0, 0xf141, 0xc941 }, 16, 0x000abdc0, 1},
++	{{0x3264, 0x2010, 0x800b, 0x3860, 0x22f4, 0x8009, 0x98c0, 0x3581, 0x2820, 0x8009, 0xf742, 0x94c0, 0xf541, 0xc945, 0x3264, 0x2010 }, 16, 0x000abde0, 1},
++	{{0x800b, 0x3860, 0x27e0, 0x8009, 0x98c0, 0x3521, 0x2ff0, 0x800c, 0xf741, 0x98c0, 0xf542, 0x3980, 0x2460, 0x8009, 0x3284, 0x3d40 }, 16, 0x000abe00, 1},
++	{{0x800b, 0x3880, 0x2760, 0x8009, 0x98c0, 0xf741, 0x3980, 0x2760, 0x8009, 0x3244, 0x2d10, 0x800b, 0x3880, 0x20dc, 0x8009, 0x3800 }, 16, 0x000abe20, 1},
++	{{0x3d3e, 0x8009, 0x3980, 0x2820, 0x8009, 0x1010, 0x3800, 0x3d2c, 0x8009, 0x98c0, 0xd021, 0x04a4, 0x33be, 0x8009, 0x8011, 0x3224 }, 16, 0x000abe40, 1},
++	{{0x3a38, 0x800a, 0xf701, 0x31a4, 0x3e8e, 0x800a, 0x266a, 0x3a61, 0x3d80, 0x2820, 0x8009, 0x8419, 0x9f44, 0x1c1d, 0x3b80, 0x29a0 }, 16, 0x000abe60, 1},
++	{{0x8009, 0x2103, 0x800a, 0x94c8, 0x4c1b, 0x5c1d, 0x4c13, 0x3f00, 0x3b86, 0x8009, 0x3980, 0x2760, 0x8009, 0x1217, 0x3800, 0x3b74 }, 16, 0x000abe80, 1},
++	{{0x8009, 0x98c0, 0xd121, 0x03a4, 0x33be, 0x8009, 0x8011, 0x3224, 0x3a38, 0x800a, 0xf701, 0x31a4, 0x3ede, 0x800a, 0x25ea, 0x39e1 }, 16, 0x000abea0, 1},
++	{{0x3a80, 0x2760, 0x8009, 0x8419, 0x9f43, 0x161a, 0x3d80, 0x2b20, 0x8009, 0x2103, 0x800a, 0x94c8, 0x461d, 0x561a, 0x4615, 0x33c4 }, 16, 0x000abec0, 1},
++	{{0x3120, 0x800a, 0x27ef, 0x9fe0, 0xe7ef, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000abee0, 1},
++	{{0x3264, 0x2470, 0x800a, 0x94c0, 0x9e20, 0x9f20, 0x32a4, 0x3230, 0x800a, 0x08a2, 0x3330, 0x8009, 0x2c10, 0x3fa0, 0x3354, 0x8009 }, 16, 0x000abf00, 1},
++	{{0x3264, 0x3c70, 0x800a, 0x4897, 0x94c0, 0xef4c, 0xc081, 0x3264, 0x3c70, 0x800a, 0x4897, 0x94c0, 0xef44, 0xc082, 0x3264, 0x3c70 }, 16, 0x000abf20, 1},
++	{{0x800a, 0x4897, 0x9ac0, 0x6c10, 0xef44, 0x3284, 0x2090, 0x800a, 0x4897, 0x96c0, 0xc081, 0x2f0e, 0x8020, 0x3284, 0x2090, 0x800a }, 16, 0x000abf40, 1},
++	{{0x4896, 0x94c0, 0xee44, 0xc082, 0x3284, 0x2090, 0x800a, 0x4896, 0x9ac0, 0x6c10, 0xee44, 0x3244, 0x2150, 0x800c, 0x4896, 0x94c0 }, 16, 0x000abf60, 1},
++	{{0xcba4, 0xedee, 0xc081, 0x98c0, 0xed3b, 0x3244, 0x2150, 0x800c, 0x4895, 0x94c0, 0xc9a0, 0xecee, 0xc082, 0x98c0, 0xec39, 0x3244 }, 16, 0x000abf80, 1},
++	{{0x2150, 0x800c, 0x4894, 0x94c0, 0xecee, 0xc083, 0x98c0, 0xec7c, 0x3244, 0x2150, 0x800c, 0x4894, 0x2c10, 0xedee, 0x98c0, 0xed78 }, 16, 0x000abfa0, 1},
++	{{0x3264, 0x33e0, 0x800a, 0x4895, 0x94c0, 0xedee, 0xc081, 0x98c0, 0xed74, 0x3264, 0x33e0, 0x800a, 0x4895, 0x94c0, 0xebee, 0xc082 }, 16, 0x000abfc0, 1},
++	{{0x98c0, 0xeb70, 0x3264, 0x33e0, 0x800a, 0x4893, 0xebee, 0x98c0, 0xeb6c, 0x32e4, 0x2060, 0x800a, 0x4893, 0x96c0, 0xc083, 0x2e0f }, 16, 0x000abfe0, 1},
++	{{0x8020, 0x3264, 0x3870, 0x800a, 0x4897, 0x2c10, 0xeaef, 0x98c0, 0xea64, 0x3264, 0x3870, 0x800a, 0x4892, 0x94c0, 0xeaef, 0xc081 }, 16, 0x000ac000, 1},
++	{{0x98c0, 0xea70, 0x3264, 0x3870, 0x800a, 0x4892, 0x94c0, 0xe9ef, 0xc082, 0x98c0, 0xe96c, 0x3264, 0x3870, 0x800a, 0x4891, 0xef68 }, 16, 0x000ac020, 1},
++	{{0x4897, 0x94c0, 0x9e21, 0x9f21, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x3384, 0x2130, 0x800a, 0x0bc6, 0x2100, 0x8009, 0x0284, 0x2ca2 }, 16, 0x000ac040, 1},
++	{{0x8009, 0x9ac0, 0x20e0, 0x99ff, 0x90c0, 0x2b09, 0x8064, 0x98c0, 0xdd00, 0x3880, 0x2ca4, 0x8009, 0x32a4, 0x2990, 0x800a, 0x0280 }, 16, 0x000ac060, 1},
++	{{0x2ca2, 0x8009, 0x33a4, 0x3f00, 0x800a, 0x3224, 0x3000, 0x800c, 0x38a0, 0x3070, 0x8009, 0x0284, 0x2ca2, 0x8009, 0x0902, 0xa060 }, 16, 0x000ac080, 1},
++	{{0x74f2, 0x96c0, 0x33fa, 0x9fe0, 0x9f70, 0x0280, 0x2ca2, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ac0a0, 1},
++	{{0x98c0, 0x38a0, 0x3330, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x3ec0, 0xa00c, 0x74d7, 0x7456, 0xeaef, 0x0dc6, 0x2100, 0x8009 }, 16, 0x000ac0c0, 1},
++	{{0x3a00, 0xa100, 0x0fc6, 0x38d0, 0x8008, 0xe9ee, 0x90c0, 0x3680, 0xa000, 0x2f08, 0x8160, 0x3480, 0xa000, 0x5210, 0x3480, 0xa000 }, 16, 0x000ac0e0, 1},
++	{{0x4215, 0x0cc6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2c0c, 0x8162, 0x1514, 0xef42, 0x4517, 0x0ec6, 0x38d0, 0x8008, 0x0ac6 }, 16, 0x000ac100, 1},
++	{{0x2100, 0x8009, 0x2e0d, 0x8164, 0x1715, 0xea44, 0x4712, 0x09c6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x290b, 0x8166, 0x1113 }, 16, 0x000ac120, 1},
++	{{0xec46, 0x4114, 0x0dc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2d08, 0x8170, 0x1110, 0xee48, 0x4116, 0x0dc6, 0x38d0, 0x8008 }, 16, 0x000ac140, 1},
++	{{0x0bc6, 0x2100, 0x8009, 0x2d0a, 0x8172, 0x1712, 0xeb4a, 0x4713, 0x0ec6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2e0d, 0x8174 }, 16, 0x000ac160, 1},
++	{{0x11d5, 0xef4c, 0x4117, 0x0fc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2f0e, 0x8168, 0x1716, 0xe850, 0x4710, 0x0dc6, 0x38d0 }, 16, 0x000ac180, 1},
++	{{0x8008, 0x0fc6, 0x2100, 0x8009, 0x2d09, 0x816a, 0x1011, 0xef52, 0x4017, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280c }, 16, 0x000ac1a0, 1},
++	{{0x816c, 0x1714, 0xe954, 0x4711, 0x09c6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2909, 0x816e, 0x1211, 0xef56, 0x4217, 0x0dc6 }, 16, 0x000ac1c0, 1},
++	{{0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2d09, 0x8174, 0x12d1, 0xec58, 0x4214, 0x0bc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009 }, 16, 0x000ac1e0, 1},
++	{{0x2b0d, 0x81e6, 0x96c0, 0x5115, 0x2e0b, 0x8028, 0x4113, 0x0dc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2d0a, 0x81e8, 0x96c0 }, 16, 0x000ac200, 1},
++	{{0x5212, 0x2909, 0x802a, 0x4211, 0x0ec6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2e0c, 0x81ea, 0x96c0, 0x5614, 0x2809, 0x802c }, 16, 0x000ac220, 1},
++	{{0x4611, 0x08c6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x280e, 0x81ec, 0x96c0, 0x5116, 0x2f0c, 0x802e, 0x4114, 0x0bc6, 0x38d0 }, 16, 0x000ac240, 1},
++	{{0x8008, 0x0ec6, 0x2100, 0x8009, 0x2b0b, 0x81ee, 0x96c0, 0x5213, 0x2e09, 0x8030, 0x4211, 0x09c6, 0x38d0, 0x8008, 0x0bc6, 0x2100 }, 16, 0x000ac260, 1},
++	{{0x8009, 0x290e, 0x81f0, 0x96c0, 0x5116, 0x2b0f, 0x8032, 0x4117, 0x0fc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2f0d, 0x81f2 }, 16, 0x000ac280, 1},
++	{{0x96c0, 0x5015, 0x2909, 0x8034, 0x4011, 0x0ac6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2a0b, 0x81f4, 0x96c0, 0x5413, 0x2d0f }, 16, 0x000ac2a0, 1},
++	{{0x8036, 0x4417, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0b, 0x8126, 0x96c0, 0x5313, 0x290a, 0x8038, 0x4312, 0x08c6 }, 16, 0x000ac2c0, 1},
++	{{0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280b, 0x813e, 0x96c0, 0x50d3, 0x290a, 0x803a, 0x4012, 0x0ec6, 0x38d0, 0x8008, 0x0dc6 }, 16, 0x000ac2e0, 1},
++	{{0x2100, 0x8009, 0x2e0f, 0x81fc, 0x96c0, 0x5617, 0x2d0d, 0x803c, 0x4615, 0x0ac6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2a0a }, 16, 0x000ac300, 1},
++	{{0x81d6, 0x96c0, 0x5212, 0x2e0b, 0x8044, 0x4213, 0x0dc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2d0c, 0x8132, 0x96c0, 0x5714 }, 16, 0x000ac320, 1},
++	{{0x2e0b, 0x8046, 0x4713, 0x09c6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2909, 0x8134, 0x96c0, 0x5211, 0x2c0d, 0x8048, 0x4215 }, 16, 0x000ac340, 1},
++	{{0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280d, 0x8138, 0x96c0, 0x53d5, 0x290f, 0x804a, 0x4317, 0x09c6, 0x38d0, 0x8008 }, 16, 0x000ac360, 1},
++	{{0x0ac6, 0x2100, 0x8009, 0x290c, 0x8130, 0x96c0, 0x56d4, 0x2a0d, 0x804c, 0x4615, 0x0fc6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009 }, 16, 0x000ac380, 1},
++	{{0x2f0c, 0x8136, 0x96c0, 0x5214, 0x2d0e, 0x804e, 0x4216, 0x0ac6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2a0f, 0x815c, 0x96c0 }, 16, 0x000ac3a0, 1},
++	{{0x5617, 0x2908, 0x8050, 0x4610, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280c, 0x81fe, 0x96c0, 0x5414, 0x2909, 0x8052 }, 16, 0x000ac3c0, 1},
++	{{0x4411, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x290d, 0x81a2, 0x96c0, 0x5615, 0x2e0c, 0x8064, 0x4614, 0x09c6, 0x2100 }, 16, 0x000ac3e0, 1},
++	{{0x8009, 0x0bc6, 0x38d0, 0x8008, 0x2908, 0x8066, 0x2b0e, 0x81a4, 0x1216, 0xc7fd, 0x4210, 0x08c6, 0x38d0, 0x8008, 0x0bc6, 0x2100 }, 16, 0x000ac400, 1},
++	{{0x8009, 0x280d, 0x81a6, 0x96c0, 0x5215, 0x2b0f, 0x8068, 0x4217, 0x0ec6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2e0c, 0x81a8 }, 16, 0x000ac420, 1},
++	{{0x96c0, 0x5414, 0x2d0f, 0x806a, 0x4417, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0e, 0x81aa, 0x96c0, 0x5016, 0x290d }, 16, 0x000ac440, 1},
++	{{0x806c, 0x4015, 0x0dc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2d0c, 0x81ac, 0x96c0, 0x5614, 0x280f, 0x806e, 0x4617, 0x0ac6 }, 16, 0x000ac460, 1},
++	{{0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x2a0e, 0x81ae, 0x96c0, 0x5616, 0x2b0c, 0x8070, 0x4614, 0x0ec6, 0x38d0, 0x8008, 0x09c6 }, 16, 0x000ac480, 1},
++	{{0x2100, 0x8009, 0x2e0b, 0x81b0, 0x96c0, 0x5413, 0x2908, 0x8072, 0x4410, 0x0ec6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2e0d }, 16, 0x000ac4a0, 1},
++	{{0x81b2, 0x96c0, 0x5115, 0x290a, 0x8074, 0x4112, 0x0ec6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2e08, 0x81b4, 0x96c0, 0x5510 }, 16, 0x000ac4c0, 1},
++	{{0x2c0d, 0x8076, 0x4515, 0x09c6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x290c, 0x81b6, 0x96c0, 0x5114, 0x280b, 0x8078, 0x4113 }, 16, 0x000ac4e0, 1},
++	{{0x0fc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2f09, 0x81b8, 0x96c0, 0x5311, 0x280b, 0x807a, 0x4313, 0x09c6, 0x38d0, 0x8008 }, 16, 0x000ac500, 1},
++	{{0x0ec6, 0x2100, 0x8009, 0x290b, 0x81ba, 0x96c0, 0x5013, 0x2e0c, 0x807e, 0x4014, 0x0fc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009 }, 16, 0x000ac520, 1},
++	{{0x2f0a, 0x81bc, 0x96c0, 0x5412, 0x2e0b, 0x8080, 0x4413, 0x0dc6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2d09, 0x81be, 0x96c0 }, 16, 0x000ac540, 1},
++	{{0x5511, 0x2f0f, 0x8082, 0x4517, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280d, 0x81c2, 0x96c0, 0x5215, 0x290a, 0x8086 }, 16, 0x000ac560, 1},
++	{{0x4212, 0x09c6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x290f, 0x81c4, 0x96c0, 0x5517, 0x2d0a, 0x8088, 0x4512, 0x0bc6, 0x38d0 }, 16, 0x000ac580, 1},
++	{{0x8008, 0x0dc6, 0x2100, 0x8009, 0x2b0e, 0x81c6, 0x96c0, 0x5516, 0x2d0f, 0x808a, 0x4517, 0x0fc6, 0x38d0, 0x8008, 0x0bc6, 0x2100 }, 16, 0x000ac5a0, 1},
++	{{0x8009, 0x2f0d, 0x8124, 0x96c0, 0x5315, 0x2b0f, 0x808c, 0x4317, 0x0fc6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2f08, 0x81c8 }, 16, 0x000ac5c0, 1},
++	{{0x96c0, 0x51d0, 0x2d0b, 0x808e, 0x4113, 0x0ac6, 0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x2a0e, 0x81d2, 0x96c0, 0x56d6, 0x2b09 }, 16, 0x000ac5e0, 1},
++	{{0x8090, 0x4611, 0x0bc6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2b0b, 0x81ca, 0x96c0, 0x5113, 0x2f0e, 0x8092, 0x4116, 0x09c6 }, 16, 0x000ac600, 1},
++	{{0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x290f, 0x81cc, 0x96c0, 0x5417, 0x2b0c, 0x807c, 0x4414, 0x0fc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ac620, 1},
++	{{0x2f0a, 0x81c0, 0x5612, 0xdf86, 0x4712, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8102, 0x55d5, 0x3b18, 0x8001, 0x6469, 0x90c0 }, 16, 0x000ac640, 1},
++	{{0x94c3, 0x2d0d, 0x80be, 0x92c3, 0x5415, 0x94c3, 0x0904, 0xa002, 0x92c3, 0x4415, 0x0dc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009 }, 16, 0x000ac660, 1},
++	{{0x2d0f, 0x81c0, 0x96c0, 0x5617, 0x280e, 0x8084, 0x4616, 0x0fc6, 0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x2f09, 0x81c0, 0x1711 }, 16, 0x000ac680, 1},
++	{{0x05a4, 0x33c0, 0x8009, 0x98c0, 0xd2a8, 0x07c0, 0x2106, 0x8009, 0x2b0e, 0x8084, 0x94c6, 0x5216, 0xc4fe, 0x94c1, 0xc481, 0xde02 }, 16, 0x000ac6a0, 1},
++	{{0x92c3, 0xde1a, 0x4416, 0x08c6, 0x38d0, 0x8008, 0x0ac6, 0x2100, 0x8009, 0x280d, 0x810c, 0x96c0, 0x55d5, 0x2a0e, 0x80a8, 0x4516 }, 16, 0x000ac6c0, 1},
++	{{0x0ac6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2a0f, 0x810e, 0x96c0, 0x50d7, 0x2d0e, 0x80aa, 0x4016, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000ac6e0, 1},
++	{{0x08c6, 0x2100, 0x8009, 0x2e0c, 0x812a, 0x96c0, 0x5514, 0x280d, 0x80ac, 0x4515, 0x0fc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009 }, 16, 0x000ac700, 1},
++	{{0x2f0a, 0x8110, 0x96c0, 0x5012, 0x280f, 0x80ae, 0x4017, 0x0ac6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2a0d, 0x81f6, 0x96c0 }, 16, 0x000ac720, 1},
++	{{0x5115, 0x2c0f, 0x80ba, 0x4117, 0x0ec6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2e0a, 0x812c, 0x96c0, 0x55d2, 0x2c08, 0x80bc }, 16, 0x000ac740, 1},
++	{{0x4510, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280c, 0x813a, 0x96c0, 0x5414, 0x2908, 0x80be, 0x4410, 0x09c6, 0x38d0 }, 16, 0x000ac760, 1},
++	{{0x8008, 0x08c6, 0x2100, 0x8009, 0x290e, 0x813c, 0x96c0, 0x5116, 0x280f, 0x80c0, 0x4117, 0x09c6, 0x38d0, 0x8008, 0x0dc6, 0x2100 }, 16, 0x000ac780, 1},
++	{{0x8009, 0x290c, 0x812e, 0x96c0, 0x5414, 0x2d09, 0x80c2, 0x4411, 0x0dc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2d0f, 0x8128 }, 16, 0x000ac7a0, 1},
++	{{0x96c0, 0x5417, 0x290a, 0x80c4, 0x4412, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x290a, 0x81d4, 0x96c0, 0x5512, 0x2e0e }, 16, 0x000ac7c0, 1},
++	{{0x80c6, 0x4516, 0x0fc6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2f0d, 0x81d6, 0x96c0, 0x5415, 0x2c0c, 0x80c8, 0x4414, 0x0fc6 }, 16, 0x000ac7e0, 1},
++	{{0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2f08, 0x81d8, 0x96c0, 0x5310, 0x2d0e, 0x80ca, 0x4316, 0x0ec6, 0x38d0, 0x8008, 0x0ac6 }, 16, 0x000ac800, 1},
++	{{0x2100, 0x8009, 0x2e0d, 0x81dc, 0x96c0, 0x52cd, 0x2a0f, 0x80cc, 0x16d5, 0xda92, 0xdf1d, 0x4697, 0x08c6, 0x38d0, 0x8008, 0x0cc6 }, 16, 0x000ac820, 1},
++	{{0x2100, 0x8009, 0x280d, 0x810a, 0x96c0, 0x5715, 0x2c0c, 0x80d0, 0x3600, 0xa800, 0x77d1, 0x4714, 0x0ac6, 0x38d0, 0x8008, 0x0ec6 }, 16, 0x000ac840, 1},
++	{{0x2100, 0x8009, 0x2a0d, 0x8100, 0x96c0, 0x55d5, 0x2e0c, 0x80d4, 0x4514, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0c }, 16, 0x000ac860, 1},
++	{{0x8102, 0x96c0, 0x56d4, 0x290a, 0x80d6, 0x3600, 0xa800, 0x7750, 0x4612, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c08 }, 16, 0x000ac880, 1},
++	{{0x8102, 0x96c0, 0x54d0, 0x280c, 0x803e, 0x04c0, 0x2104, 0x8009, 0x96c0, 0x5114, 0x290e, 0x80dc, 0x4116, 0x09c6, 0x38d0, 0x8008 }, 16, 0x000ac8a0, 1},
++	{{0x0fc6, 0x2100, 0x8009, 0x2908, 0x8142, 0x96c0, 0x5110, 0x2f0c, 0x80de, 0x4114, 0x0fc6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009 }, 16, 0x000ac8c0, 1},
++	{{0x2f09, 0x8144, 0x96c0, 0x5011, 0x2d0e, 0x80f2, 0x4016, 0x09c6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x290c, 0x8146, 0x96c0 }, 16, 0x000ac8e0, 1},
++	{{0x5114, 0x2809, 0x80f0, 0x4111, 0x0fc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2f0d, 0x8148, 0x96c0, 0x5315, 0x2908, 0x80e0 }, 16, 0x000ac900, 1},
++	{{0x4310, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0c, 0x814a, 0x96c0, 0x5414, 0x290e, 0x80e2, 0x4416, 0x0ec6, 0x38d0 }, 16, 0x000ac920, 1},
++	{{0x8008, 0x0dc6, 0x2100, 0x8009, 0x2e0a, 0x814c, 0x96c0, 0x5312, 0x2d09, 0x80e4, 0x4311, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100 }, 16, 0x000ac940, 1},
++	{{0x8009, 0x2908, 0x814e, 0x96c0, 0x5210, 0x2e0e, 0x80e6, 0x4216, 0x0ec6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2e0e, 0x8150 }, 16, 0x000ac960, 1},
++	{{0x96c0, 0x5316, 0x2808, 0x80e8, 0x4310, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x290d, 0x8152, 0x96c0, 0x5115, 0x2e0c }, 16, 0x000ac980, 1},
++	{{0x80ea, 0x4114, 0x09c6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x290f, 0x8154, 0x96c0, 0x5217, 0x2d0d, 0x80ec, 0x3640, 0xa000 }, 16, 0x000ac9a0, 1},
++	{{0x4215, 0xefea, 0x0dc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2d0d, 0x8156, 0x96c0, 0x5015, 0x2e08, 0x80ee, 0x9f70, 0x3640 }, 16, 0x000ac9c0, 1},
++	{{0xa000, 0x4010, 0xeee9, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20c0 }, 16, 0x000ac9e0, 1},
++	{{0x800a, 0xe748, 0x3e40, 0xa000, 0x6f10, 0x6e90, 0x0cc6, 0x38d0, 0x8008, 0xc9a4, 0x9ac0, 0x280d, 0x8080, 0x90c0, 0x2202, 0x8050 }, 16, 0x000aca00, 1},
++	{{0x96c0, 0xeeed, 0x2c0f, 0x8102, 0x17d7, 0x04c4, 0x2104, 0x8009, 0x9ac0, 0x2f0c, 0x80be, 0xde17, 0x2b00, 0x804c, 0x3c20, 0xa000 }, 16, 0x000aca20, 1},
++	{{0x391c, 0x8001, 0xcda0, 0x2002, 0x8048, 0x3820, 0xa000, 0x6669, 0xc9a8, 0xee39, 0x3a80, 0xa000, 0xefed, 0x03c4, 0x2106, 0x8009 }, 16, 0x000aca40, 1},
++	{{0x1014, 0xeaed, 0x38a0, 0xa100, 0xdd90, 0xeced, 0xef3a, 0x3a80, 0xa100, 0x3719, 0x8002, 0xe9ed, 0xebed, 0x3880, 0xa000, 0xec39 }, 16, 0x000aca60, 1},
++	{{0x2202, 0x805c, 0x90c0, 0x3620, 0xa100, 0xea3d, 0xeb3b, 0x36a0, 0xa000, 0xe938, 0xebed, 0x3680, 0xa000, 0xeded, 0xe9ed, 0x36c0 }, 16, 0x000aca80, 1},
++	{{0xa000, 0xeeed, 0x5895, 0x3a47, 0xa000, 0x90c0, 0xed3a, 0xc681, 0x64e9, 0x36c0, 0xa000, 0xc058, 0x5890, 0x36c0, 0xa100, 0x5897 }, 16, 0x000acaa0, 1},
++	{{0x5a94, 0x3620, 0xa000, 0x5c96, 0x5e92, 0x3600, 0xa100, 0xeb70, 0x5a93, 0x96c7, 0x6769, 0xc581, 0xe968, 0x3680, 0xa100, 0xed64 }, 16, 0x000acac0, 1},
++	{{0xee6c, 0x3680, 0xa100, 0xc84d, 0x5891, 0x3680, 0xa100, 0xce4a, 0xc259, 0x3680, 0xa000, 0xca4c, 0x5a93, 0x3680, 0xa100, 0x5e95 }, 16, 0x000acae0, 1},
++	{{0xc84e, 0x3680, 0xa100, 0xc45b, 0x5b96, 0x8064, 0x3640, 0xa000, 0x5991, 0x5a95, 0xc7fd, 0x3840, 0xa000, 0xdf80, 0x2a0f, 0x8500 }, 16, 0x000acb00, 1},
++	{{0x4714, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0d, 0x8102, 0x57d5, 0x3f1e, 0x8001, 0x6769, 0x90c0, 0x94c3, 0x2d0c, 0x80be, 0x92c3 }, 16, 0x000acb20, 1},
++	{{0x5514, 0x94c3, 0x0905, 0xa002, 0x92c3, 0x4514, 0x0dc6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2d0d, 0x81c0, 0x96c0, 0x5315 }, 16, 0x000acb40, 1},
++	{{0x2c0c, 0x8084, 0x0314, 0x30c4, 0x2baa, 0x800a, 0x4317, 0x26e9, 0xc0fe, 0x94c0, 0xdc07, 0x8039, 0x4017, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000acb60, 1},
++	{{0x90c0, 0x2c0c, 0x81c0, 0x5514, 0x3b18, 0x8002, 0x6469, 0x90c0, 0x94c3, 0x2d00, 0x80be, 0x90c0, 0x92c3, 0xec3d, 0x92c3, 0x54d4 }, 16, 0x000acb80, 1},
++	{{0x94c3, 0x0904, 0xa001, 0x92c3, 0x4414, 0x3a00, 0xa100, 0x0cc6, 0x38d0, 0x8008, 0xe84e, 0x9ac0, 0x2f00, 0x80c0, 0x90c0, 0x2302 }, 16, 0x000acba0, 1},
++	{{0x82a6, 0x3c40, 0xa000, 0x2c0d, 0x8102, 0x90c0, 0x280c, 0x82aa, 0x3800, 0xa100, 0x50d5, 0x2d0d, 0x80be, 0x98c0, 0x00c0, 0x2104 }, 16, 0x000acbc0, 1},
++	{{0x8009, 0xc2fe, 0x3680, 0xa100, 0x5015, 0xed3f, 0x98c0, 0x00c0, 0x2106, 0x8009, 0xe8ec, 0x3a00, 0xa100, 0x34a2, 0x3c9c, 0x8009 }, 16, 0x000acbe0, 1},
++	{{0x57d5, 0x3860, 0xa100, 0xe83b, 0x2a0a, 0x84b4, 0x38c0, 0xa100, 0x471c, 0x2a09, 0x805e, 0x3880, 0xa000, 0x56d5, 0x2302, 0x82a8 }, 16, 0x000acc00, 1},
++	{{0x3840, 0xa000, 0xdd06, 0xe0e9, 0xc3f7, 0x3680, 0xa100, 0x4215, 0xc25f, 0x3a00, 0xa100, 0x0dc6, 0x38d0, 0x8008, 0xedec, 0x36a0 }, 16, 0x000acc20, 1},
++	{{0xa100, 0xed3b, 0xeaec, 0x3c80, 0xa000, 0x2d09, 0x8102, 0x90c0, 0x2302, 0x8150, 0x3880, 0xa000, 0x57d1, 0x2f00, 0x81dc, 0x38a0 }, 16, 0x000acc40, 1},
++	{{0xa100, 0xdd87, 0x4714, 0xea3b, 0x3880, 0xa000, 0x4311, 0x2402, 0x8268, 0x3a20, 0xa000, 0x0bc6, 0x38d0, 0x8008, 0xc25a, 0x36c0 }, 16, 0x000acc60, 1},
++	{{0xa100, 0xeaec, 0xeee8, 0x38e0, 0xa100, 0xea3c, 0x2b0b, 0x810e, 0x3680, 0xa000, 0x51d3, 0xc558, 0x3680, 0xa100, 0x4110, 0xc051 }, 16, 0x000acc80, 1},
++	{{0x3a00, 0xa100, 0x0dc6, 0x38d0, 0x8008, 0xc453, 0x38c0, 0xa100, 0xedec, 0x2808, 0x800a, 0x38c0, 0xa100, 0xed3f, 0x2c0c, 0x800a }, 16, 0x000acca0, 1},
++	{{0x3820, 0xa000, 0xedec, 0x2d0f, 0x810c, 0x3640, 0xa000, 0x54d7, 0xefe8, 0x3680, 0xa000, 0xee62, 0xef68, 0x3680, 0xa000, 0x4416 }, 16, 0x000accc0, 1},
++	{{0xed68, 0x94c0, 0xcf4f, 0xcd49, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xefec, 0x94c0, 0xef68, 0xee58, 0x3800, 0xa100, 0xe2ef, 0x2d0e }, 16, 0x000acce0, 1},
++	{{0x810a, 0x3680, 0xa000, 0x5516, 0xefec, 0x0514, 0xef64, 0x3a20, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0xe3ef, 0x3600, 0xa100, 0xedee }, 16, 0x000acd00, 1},
++	{{0xefec, 0x3840, 0xa000, 0xed62, 0x2e0f, 0x8110, 0x1517, 0xfd41, 0x3600, 0xa100, 0x4510, 0xef6c, 0x3a00, 0xa100, 0x08c6, 0x38d0 }, 16, 0x000acd20, 1},
++	{{0x8008, 0xe9ec, 0x3680, 0xa000, 0xe96a, 0xe958, 0x3880, 0xa100, 0xc846, 0x280e, 0x8126, 0x3680, 0xa100, 0x5316, 0xc654, 0x3640 }, 16, 0x000acd40, 1},
++	{{0xa000, 0x65e4, 0xe1e9, 0x3600, 0xa100, 0x4310, 0xc152, 0x3600, 0xa100, 0xe846, 0x4316, 0x3680, 0xa100, 0xc84e, 0xc845, 0x38c0 }, 16, 0x000acd60, 1},
++	{{0xa100, 0xee46, 0x2909, 0x800a, 0x3600, 0xa100, 0x4310, 0xc65c, 0x3a40, 0xa100, 0x0dc6, 0x38d0, 0x8008, 0xebe9, 0x3680, 0xa000 }, 16, 0x000acd80, 1},
++	{{0xeb68, 0xe846, 0x3880, 0xa100, 0xc84d, 0x2d0e, 0x8128, 0x3680, 0xa100, 0x5616, 0xc846, 0x3680, 0xa100, 0x4617, 0xc654, 0x0dc6 }, 16, 0x000acda0, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x3800, 0xa100, 0xcd41, 0x2d0f, 0x812a, 0x3680, 0xa000, 0x5617, 0xc750, 0x90c0, 0x3480, 0xa000, 0x4617 }, 16, 0x000acdc0, 1},
++	{{0x3820, 0xa000, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2f0f, 0x812e, 0x3680, 0xa000, 0x5617, 0xc752, 0x3680, 0xa100 }, 16, 0x000acde0, 1},
++	{{0x4615, 0x4612, 0x3480, 0xa000, 0x4617, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x3800, 0xa100, 0xcf47, 0x2f0a, 0x8130, 0x3680, 0xa100 }, 16, 0x000ace00, 1},
++	{{0x53d2, 0xc257, 0x3480, 0xa000, 0x4311, 0x3680, 0xa100, 0x4314, 0xe94a, 0x3680, 0xa100, 0x4310, 0xec4a, 0x3a20, 0xa100, 0x0dc6 }, 16, 0x000ace20, 1},
++	{{0x38d0, 0x8008, 0xe84a, 0x90c0, 0x36a0, 0xa000, 0x2d0d, 0x8132, 0x3480, 0xa000, 0x5415, 0x3480, 0xa000, 0x4413, 0x4415, 0x4417 }, 16, 0x000ace40, 1},
++	{{0x3820, 0xa000, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x3620, 0xa000, 0x2b0d, 0x815e, 0x5115, 0x3480, 0xa000, 0x4111, 0x3680, 0xa100 }, 16, 0x000ace60, 1},
++	{{0x4114, 0xe970, 0x3680, 0xa100, 0x4110, 0xec70, 0x3a00, 0xa100, 0x0fc6, 0x38d0, 0x8008, 0xe870, 0x90c0, 0x3680, 0xa000, 0x2f0b }, 16, 0x000ace80, 1},
++	{{0x8134, 0x3480, 0xa000, 0x5313, 0x3480, 0xa000, 0x4311, 0x3680, 0xa100, 0x4314, 0xe9e0, 0x3480, 0xa000, 0x4310, 0x0dc6, 0x38d0 }, 16, 0x000acea0, 1},
++	{{0x8008, 0x90c0, 0x2d0d, 0x813e, 0x50d5, 0x3600, 0xa100, 0x4010, 0xc845, 0x3480, 0xa000, 0x4016, 0x4010, 0x3820, 0xa000, 0x0fc6 }, 16, 0x000acec0, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2f0d, 0x81a2, 0x3480, 0xa000, 0x5115, 0x3880, 0xa000, 0x4112, 0x2202, 0x805c, 0x3820 }, 16, 0x000acee0, 1},
++	{{0xa000, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x3620, 0xa000, 0x2b0d, 0x81c8, 0x57d5, 0x3480, 0xa000, 0x4711, 0x3a60, 0xa100, 0x08c6 }, 16, 0x000acf00, 1},
++	{{0x38d0, 0x8008, 0xe93a, 0x90c0, 0x3620, 0xa000, 0x280f, 0x81ca, 0x1017, 0xefe2, 0x3480, 0xa000, 0x4011, 0x3a20, 0xa100, 0x0cc6 }, 16, 0x000acf20, 1},
++	{{0x38d0, 0x8008, 0xe9e1, 0x3820, 0xa000, 0x08c6, 0x2100, 0x8009, 0x36a0, 0xa000, 0x2c0d, 0x81d2, 0x38c0, 0xa100, 0x51d5, 0x2808 }, 16, 0x000acf40, 1},
++	{{0x8090, 0x3480, 0xa000, 0x4110, 0x3820, 0xa000, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x38c0, 0xa100, 0xc051, 0x280c, 0x81d4, 0x3680 }, 16, 0x000acf60, 1},
++	{{0xa100, 0x5214, 0xc453, 0x3680, 0xa100, 0x4211, 0xc152, 0x3820, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2e0f }, 16, 0x000acf80, 1},
++	{{0x81d6, 0x3480, 0xa000, 0x5017, 0x3480, 0xa000, 0x4011, 0x3680, 0xa000, 0x4014, 0xea58, 0x3480, 0xa000, 0x4010, 0x3820, 0xa000 }, 16, 0x000acfa0, 1},
++	{{0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2d0b, 0x81d8, 0x3480, 0xa000, 0x5013, 0x4017, 0x98c0, 0x0dc6, 0x38d0, 0x8008 }, 16, 0x000acfc0, 1},
++	{{0xefe3, 0x90c0, 0x3800, 0xa100, 0xfdc1, 0x2d0e, 0x81dc, 0x3480, 0xa000, 0x50ce, 0x3600, 0xa100, 0xd990, 0x50d6, 0xdc1b, 0x4097 }, 16, 0x000acfe0, 1},
++	{{0x3820, 0xa000, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2f0d, 0x81e6, 0x3480, 0xa000, 0x5115, 0x4116, 0x3a20, 0xa000 }, 16, 0x000ad000, 1},
++	{{0x0bc6, 0x38d0, 0x8008, 0xee44, 0x90c0, 0x3840, 0xa100, 0xeb58, 0x2b0f, 0x81e8, 0x3680, 0xa100, 0x5517, 0xe9eb, 0x3600, 0xa100 }, 16, 0x000ad020, 1},
++	{{0x4515, 0xe962, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x81ea, 0x5210, 0x420e, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x81ec }, 16, 0x000ad040, 1},
++	{{0x1410, 0xe8e9, 0x0416, 0xe862, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0e, 0x81ee, 0x1016, 0xeeea, 0x0011, 0xee62, 0x0013, 0xe944 }, 16, 0x000ad060, 1},
++	{{0x0012, 0xeb44, 0x3a20, 0xa000, 0x0cc6, 0x38d0, 0x8008, 0xea44, 0x90c0, 0x36a0, 0xa000, 0x2c0c, 0x81f0, 0x3480, 0xa000, 0x5114 }, 16, 0x000ad080, 1},
++	{{0x3600, 0xa100, 0x4110, 0xc840, 0x3880, 0xa000, 0x4111, 0x2102, 0x829c, 0x4116, 0x3a40, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0xec39 }, 16, 0x000ad0a0, 1},
++	{{0x90c0, 0x2e0e, 0x81f2, 0x5616, 0x4609, 0x460b, 0x460a, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0e, 0x81f4, 0x5216, 0x4211, 0x4213 }, 16, 0x000ad0c0, 1},
++	{{0x4212, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x2909, 0x81f6, 0x5611, 0x4614, 0x0cc6, 0x38d0, 0x8008, 0x32c4, 0x3b60, 0x800a, 0x2c09 }, 16, 0x000ad0e0, 1},
++	{{0x8200, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad100, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x32c4, 0x20c0, 0x800a, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x5890, 0x280d, 0x804c, 0x96c0, 0x5f95, 0x2d0b }, 16, 0x000ad120, 1},
++	{{0x8034, 0x1e93, 0xe844, 0x32a4, 0x2050, 0x800b, 0x1090, 0xc84e, 0x98c0, 0xc846, 0x3b00, 0x2068, 0x8008, 0x9ac0, 0x31fc, 0x9fff }, 16, 0x000ad140, 1},
++	{{0xcda8, 0x2702, 0x816a, 0x0090, 0x3a00, 0x206c, 0x8008, 0x0413, 0x3b00, 0x206a, 0x8008, 0x96c0, 0x5290, 0x280c, 0x805e, 0x98c0 }, 16, 0x000ad160, 1},
++	{{0x34cd, 0x8410, 0xe9ec, 0xc8a6, 0x0513, 0x3b00, 0x206e, 0x8008, 0x1017, 0x3f00, 0x2072, 0x8008, 0x0012, 0xe93d, 0x1614, 0xedec }, 16, 0x000ad180, 1},
++	{{0x0613, 0x3b00, 0x2074, 0x8008, 0x1311, 0xed38, 0x0317, 0x3800, 0x207c, 0x8008, 0x96c0, 0x5115, 0x2c0a, 0x825a, 0x0113, 0xefea }, 16, 0x000ad1a0, 1},
++	{{0x1212, 0xef62, 0x0210, 0x3b00, 0x2078, 0x8008, 0x1017, 0x3800, 0x2076, 0x8008, 0x0013, 0xea42, 0x1512, 0x3f00, 0x2088, 0x8008 }, 16, 0x000ad1c0, 1},
++	{{0x96c0, 0x4510, 0x2800, 0x81f8, 0x3600, 0xa100, 0x5511, 0xebea, 0x96c0, 0x4517, 0x2f00, 0x816c, 0x3a00, 0xa100, 0x3900, 0x208a }, 16, 0x000ad1e0, 1},
++	{{0x8008, 0xeb38, 0x3680, 0xa000, 0x5013, 0xebea, 0x96c0, 0x4011, 0x2900, 0x80e0, 0x98c0, 0xeb3f, 0x3800, 0x208c, 0x8008, 0x1613 }, 16, 0x000ad200, 1},
++	{{0xefea, 0x0610, 0xef39, 0x1517, 0x3202, 0x208e, 0x8008, 0x98c0, 0x3b00, 0x2080, 0x8008, 0xe9ea, 0x3880, 0xa000, 0x4512, 0x2800 }, 16, 0x000ad220, 1},
++	{{0x81f6, 0x1615, 0x3f00, 0x2082, 0x8008, 0x0613, 0xe938, 0x1011, 0xedea, 0x96c0, 0x4017, 0x2b00, 0x80de, 0x3a40, 0xa000, 0x3800 }, 16, 0x000ad240, 1},
++	{{0x2084, 0x8008, 0xed3f, 0x1515, 0xefea, 0x0510, 0xef3b, 0x1517, 0x3d00, 0x2086, 0x8008, 0x96c0, 0xe8ea, 0x2b00, 0x81d0, 0x0515 }, 16, 0x000ad260, 1},
++	{{0x3f00, 0x2090, 0x8008, 0x1314, 0xe83b, 0x0317, 0x3900, 0x2092, 0x8008, 0x96c0, 0xecea, 0x2b00, 0x8144, 0x1410, 0x3d00, 0x2094 }, 16, 0x000ad280, 1},
++	{{0x8008, 0x96c0, 0x4411, 0x2900, 0x80b8, 0x94c0, 0xec3b, 0xee42, 0x1314, 0x3c00, 0x2096, 0x8008, 0x0315, 0xea39, 0x5712, 0x4714 }, 16, 0x000ad2a0, 1},
++	{{0x10d6, 0x06c5, 0x231c, 0x8009, 0x2769, 0x09c6, 0x38d0, 0x8008, 0x802b, 0x96c0, 0x6d90, 0x290f, 0x8200, 0x55d7, 0x96c0, 0x7065 }, 16, 0x000ad2c0, 1},
++	{{0x3b7e, 0x9c7f, 0x843b, 0x4617, 0x03c1, 0x231e, 0x8009, 0x30c4, 0x331e, 0x800a, 0x03c1, 0x231c, 0x8009, 0x2d90, 0x05c5, 0x231d }, 16, 0x000ad2e0, 1},
++	{{0x8009, 0x26e9, 0x0cc6, 0x38d0, 0x8008, 0x8015, 0x2c0a, 0x8200, 0x51d2, 0x337f, 0x9fff, 0x4712, 0x03c1, 0x231d, 0x8009, 0x94c0 }, 16, 0x000ad300, 1},
++	{{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x33c4, 0x20c0, 0x800a, 0x1c90, 0x0bc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ad320, 1},
++	{{0x9ac0, 0x2b0a, 0x8024, 0x90c0, 0x2c0d, 0x8028, 0x96c0, 0x54d2, 0x2d0b, 0x808c, 0x9ac0, 0x2b0a, 0x8118, 0x6669, 0x2b08, 0x808c }, 16, 0x000ad340, 1},
++	{{0x92c2, 0x6e90, 0x92c3, 0xc581, 0x4515, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x8028, 0x54d4, 0x6669, 0x92c2, 0x6d10, 0x92c3 }, 16, 0x000ad360, 1},
++	{{0xc281, 0x4213, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0d, 0x802a, 0x55d5, 0x66e9, 0x92c2, 0x6d10, 0x92c3, 0xc281, 0x4210, 0x0dc6 }, 16, 0x000ad380, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x802c, 0x54d5, 0x6669, 0x92c2, 0x6d90, 0x94c7, 0x9f70, 0xc381, 0x4312, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad3a0, 1},
++	{{0x36d1, 0xc281, 0x98c0, 0x74d2, 0x7750, 0x9620, 0x9720, 0x98c0, 0x6d7c, 0x6e7c, 0x9e20, 0x9f20, 0x3284, 0x20b0, 0x800a, 0x3455 }, 16, 0x000ad3c0, 1},
++	{{0xce45, 0x35d0, 0x7456, 0x7de3, 0x79ee, 0x2f90, 0x3284, 0x20b0, 0x800a, 0x6f7c, 0x98c0, 0x7c63, 0x6e10, 0xce4d, 0xc181, 0x386e }, 16, 0x000ad3e0, 1},
++	{{0xd69f, 0x2c7c, 0x7575, 0x94c0, 0xd71c, 0xce44, 0x2aaa, 0xd7c4, 0x66e6, 0x2d7c, 0x3284, 0x20b0, 0x800a, 0x3455, 0xcf45, 0x3e00 }, 16, 0x000ad400, 1},
++	{{0xa00d, 0x7450, 0x6e10, 0x6e90, 0x3381, 0x2000, 0x8000, 0x3e00, 0xa004, 0x7c63, 0x757b, 0xcf4d, 0x3c60, 0x32dc, 0x8008, 0x3600 }, 16, 0x000ad420, 1},
++	{{0xa004, 0x7863, 0xce4c, 0x3600, 0xa80c, 0x74d0, 0x786b, 0x3600, 0xb80c, 0x6c7c, 0x6d7c, 0x3800, 0xba40, 0x6d95, 0xd69c, 0xd7c4 }, 16, 0x000ad440, 1},
++	{{0x3c00, 0xa002, 0x7475, 0x74d5, 0xd69b, 0x3f1b, 0x8001, 0x3800, 0xa009, 0x7ae1, 0x65e9, 0x75f1, 0x3a07, 0xa402, 0x7be1, 0x7ec1 }, 16, 0x000ad460, 1},
++	{{0x90c0, 0xd813, 0x3e07, 0xa008, 0x90c0, 0xcf45, 0xc181, 0x371d, 0x8001, 0x75c7, 0x92c2, 0x6c90, 0xef1c, 0x3420, 0xa000, 0x5217 }, 16, 0x000ad480, 1},
++	{{0x3400, 0xa840, 0x6bbc, 0x7fef, 0x3600, 0xa044, 0x3400, 0x8007, 0x3400, 0xa004, 0x6466, 0x3400, 0xa004, 0xd41b, 0x3400, 0xa004 }, 16, 0x000ad4a0, 1},
++	{{0x7072, 0x3601, 0xa0cc, 0x6c92, 0x6e12, 0x3a61, 0xb299, 0xc48f, 0x6b28, 0x6b38, 0xc48f, 0x3600, 0xb004, 0x6766, 0x6e34, 0x3402 }, 16, 0x000ad4c0, 1},
++	{{0xa004, 0x6764, 0x3400, 0xa004, 0xd742, 0x3400, 0xa004, 0x7f70, 0x3400, 0xa844, 0x6cca, 0x3400, 0xa804, 0x7771, 0x3400, 0xa840 }, 16, 0x000ad4e0, 1},
++	{{0x6ba6, 0x7fef, 0x3c00, 0xa006, 0x34e6, 0x8000, 0x90c0, 0x36e7, 0x8000, 0x3600, 0xa004, 0x30e6, 0x8000, 0x3400, 0xa800, 0xdb96 }, 16, 0x000ad500, 1},
++	{{0x3400, 0xa800, 0xd7c7, 0x67e1, 0x67e6, 0xd79b, 0x73f2, 0x3601, 0xa00c, 0x6fab, 0x6eab, 0x3601, 0xb808, 0x7477, 0x7475, 0x3601 }, 16, 0x000ad520, 1},
++	{{0xb88c, 0x6ab1, 0x6ab1, 0x3400, 0xa004, 0x66e6, 0x3606, 0xa004, 0x66e4, 0x66e9, 0x3a07, 0xa008, 0x78c1, 0xd6c2, 0x79e1, 0xf28d }, 16, 0x000ad540, 1},
++	{{0x3c00, 0xa008, 0x6e08, 0x7ef0, 0x75c3, 0x331a, 0x8001, 0x3600, 0xb008, 0x6569, 0xd4c5, 0x3601, 0xb000, 0x76c1, 0x77f1, 0x3801 }, 16, 0x000ad560, 1},
++	{{0xa004, 0xd5c5, 0x3e57, 0x9a82, 0x3607, 0xa080, 0x67e6, 0x6ccc, 0x3a07, 0xa001, 0x90c0, 0x77f6, 0x3f41, 0x8000, 0x3607, 0xa004 }, 16, 0x000ad580, 1},
++	{{0x7cef, 0x6668, 0x3600, 0xa040, 0x6827, 0x803b, 0x24e8, 0x6466, 0x801b, 0xd4c3, 0x64e8, 0x94c7, 0x844a, 0x64e4, 0x92c3, 0xd411 }, 16, 0x000ad5a0, 1},
++	{{0x98c0, 0xd419, 0x31c4, 0x3600, 0x800a, 0x3600, 0xa004, 0x7271, 0xd419, 0x98c7, 0x30c4, 0x3600, 0x800a, 0x7c6f, 0xd41b, 0x3600 }, 16, 0x000ad5c0, 1},
++	{{0xb080, 0x77f6, 0x6cac, 0x3600, 0xa040, 0x6827, 0x64e8, 0x6466, 0xd41c, 0xd41b, 0x3601, 0xb000, 0xd419, 0xd41b, 0x92c2, 0x7c6f }, 16, 0x000ad5e0, 1},
++	{{0x96c0, 0x6461, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad600, 1},
++	{{0x96c0, 0x6c90, 0x9620, 0x9720, 0x0190, 0xc94e, 0x14d1, 0xe84a, 0x9ac0, 0x399f, 0x8000, 0x90c0, 0x3978, 0x9fff, 0x67e9, 0x92c2 }, 16, 0x000ad620, 1},
++	{{0x6f90, 0x98c7, 0x3224, 0x24f0, 0x800a, 0xc781, 0x0710, 0xc84f, 0x94c0, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xece8, 0xe942, 0x94c0 }, 16, 0x000ad640, 1},
++	{{0xec66, 0xc94e, 0x4094, 0x1511, 0x3244, 0x3d90, 0x800a, 0x7465, 0x96c0, 0x6e10, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xebe8, 0xe942 }, 16, 0x000ad660, 1},
++	{{0x94c0, 0xeb62, 0xe842, 0x0013, 0xc94e, 0x4490, 0x14d1, 0xe84a, 0x9ac0, 0x399f, 0x8000, 0x90c0, 0x3978, 0x9fff, 0x27e9, 0xc84f }, 16, 0x000ad680, 1},
++	{{0x92c2, 0x6d10, 0x98c7, 0x3224, 0x24f0, 0x800a, 0xc281, 0x4210, 0x94c0, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xeae8, 0xe942, 0xea66 }, 16, 0x000ad6a0, 1},
++	{{0x4092, 0x1211, 0x3244, 0x3d90, 0x800a, 0x7462, 0xc847, 0x94c0, 0x9621, 0x9721, 0x94c0, 0xe862, 0x9f70, 0x4010, 0x90c0, 0x90c0 }, 16, 0x000ad6c0, 1},
++	{{0x96c0, 0xd028, 0x77d0, 0x9720, 0x94c0, 0x9f20, 0x807f, 0x9ac0, 0x2040, 0x8e20, 0x90c0, 0x3417, 0x8030, 0x805b, 0x9ac0, 0x2020 }, 16, 0x000ad6e0, 1},
++	{{0x99d0, 0x90c0, 0x3417, 0x8020, 0x803b, 0x96c0, 0xd3b8, 0x2020, 0x8bc0, 0x801f, 0x96c0, 0xd3b0, 0x2000, 0x9c20, 0x844b, 0x3324 }, 16, 0x000ad700, 1},
++	{{0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a, 0x00c2, 0x22bc, 0x8009, 0x3324, 0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a, 0x00c2, 0x22bc }, 16, 0x000ad720, 1},
++	{{0x8009, 0x3324, 0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a, 0x00c2, 0x22bc, 0x8009, 0x3324, 0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a }, 16, 0x000ad740, 1},
++	{{0x00c2, 0x22bc, 0x8009, 0x3224, 0x24f0, 0x800a, 0x96c0, 0xc788, 0x2000, 0x8d48, 0x00c2, 0x22bc, 0x8009, 0x3fc1, 0x0cc6, 0x38d0 }, 16, 0x000ad760, 1},
++	{{0x8008, 0x38c0, 0x210c, 0x8009, 0x2c09, 0x80b8, 0x32c4, 0x3620, 0x800a, 0x07c0, 0x22cc, 0x8009, 0x0dc6, 0x38d0, 0x8008, 0x38c0 }, 16, 0x000ad780, 1},
++	{{0x21e4, 0x8009, 0x32c4, 0x3620, 0x800a, 0x2d09, 0x80c0, 0x3224, 0x24f0, 0x800a, 0x2000, 0x8064, 0x00c2, 0x22c4, 0x8009, 0x3224 }, 16, 0x000ad7a0, 1},
++	{{0x24f0, 0x800a, 0x2000, 0x83e8, 0x98c0, 0x01c6, 0x22c4, 0x8009, 0x9f21, 0x9ac0, 0x6c51, 0x02c6, 0x22bc, 0x8009, 0x9721, 0x7170 }, 16, 0x000ad7c0, 1},
++	{{0x90c0, 0x98c7, 0x9f70, 0x30e8, 0x3fff, 0xbfff, 0x96c3, 0x00c2, 0x22bc, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad7e0, 1},
++	{{0x96c0, 0x5011, 0x280b, 0x800a, 0x96c0, 0x6468, 0x9620, 0x9720, 0x94c0, 0x9e20, 0xc3fe, 0x96c7, 0xc94e, 0x280c, 0x800a, 0x94c7 }, 16, 0x000ad800, 1},
++	{{0xc84f, 0x5514, 0x96c7, 0xeeeb, 0x0905, 0xa001, 0x94c7, 0x8423, 0x4514, 0x5413, 0xdd84, 0x0313, 0x3224, 0x24f0, 0x800a, 0x5011 }, 16, 0x000ad820, 1},
++	{{0x94c0, 0xebee, 0xc946, 0x94c0, 0xeb66, 0xc847, 0x4093, 0x94c0, 0xe942, 0xc84f, 0x1611, 0x3244, 0x3d90, 0x800a, 0x3466, 0xc94e }, 16, 0x000ad840, 1},
++	{{0x94c0, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xe848, 0xe942, 0x0010, 0xc0fe, 0x1511, 0xc84f, 0x66e8, 0x90c0, 0x94c3, 0x280c, 0x800e }, 16, 0x000ad860, 1},
++	{{0x92c3, 0x5214, 0x96c7, 0x8432, 0x0902, 0xa001, 0x92c3, 0x4214, 0x280c, 0x800e, 0x1614, 0xeeec, 0x94c0, 0xdc06, 0xc94e, 0x0014 }, 16, 0x000ad880, 1},
++	{{0x3224, 0x24f0, 0x800a, 0x5011, 0x94c0, 0xecee, 0xc946, 0x94c0, 0xec66, 0xc847, 0x4094, 0x94c0, 0xe942, 0xc84f, 0x1011, 0x3244 }, 16, 0x000ad8a0, 1},
++	{{0x3d90, 0x800a, 0x7460, 0x94c0, 0xc847, 0x9e21, 0x94c0, 0x9621, 0x9721, 0x94c0, 0xe84c, 0x9f70, 0x4010, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad8c0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x0bc6, 0x38d0, 0x8008, 0x270a, 0x8030, 0x98c0, 0x38c0, 0x210c, 0x8009, 0xe7ea }, 16, 0x000ad8e0, 1},
++	{{0x32c4, 0x3800, 0x800a, 0x2b09, 0x80b8, 0x0ac6, 0x38d0, 0x8008, 0x38c0, 0x21e4, 0x8009, 0x32c4, 0x3800, 0x800a, 0x2a09, 0x80c0 }, 16, 0x000ad900, 1},
++	{{0x2f90, 0x38c0, 0x2116, 0x8009, 0x00c4, 0x22cc, 0x8009, 0x98c0, 0x280d, 0x800c, 0x646a, 0x5310, 0x98c0, 0x371a, 0x8001, 0x5115 }, 16, 0x000ad920, 1},
++	{{0xed62, 0x9ac0, 0x331e, 0x8001, 0xf241, 0x2718, 0x8168, 0x94c0, 0xece8, 0xefed, 0x94c0, 0xeeed, 0xec62, 0x94c0, 0xe866, 0xef68 }, 16, 0x000ad940, 1},
++	{{0x9ec0, 0xee64, 0x3ac0, 0x2124, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x1254, 0x00c6, 0x210c, 0x8009, 0x94c0, 0xf242, 0xf843, 0x94c0 }, 16, 0x000ad960, 1},
++	{{0xfd44, 0xfc45, 0x3224, 0x2590, 0x800a, 0xfa46, 0x9ac0, 0x74d0, 0xf8c3, 0x02c6, 0x210c, 0x8009, 0x94c0, 0xfdc4, 0xf147, 0x5090 }, 16, 0x000ad980, 1},
++	{{0xd540, 0x02c2, 0x210c, 0x8009, 0x3620, 0xa000, 0x5355, 0x5097, 0x3224, 0x2590, 0x800a, 0x3420, 0xa000, 0xf348, 0x3820, 0xa004 }, 16, 0x000ad9a0, 1},
++	{{0xda10, 0xf1c7, 0xf3c8, 0x3a40, 0xb084, 0xd891, 0x602c, 0x5197, 0x5296, 0x3c00, 0xa004, 0xd541, 0x31e8, 0x9fff, 0xf3c1, 0xf2c2 }, 16, 0x000ad9c0, 1},
++	{{0x3a40, 0xa080, 0x65e9, 0x6018, 0xfac6, 0x4297, 0x94c0, 0xf8c3, 0xfdc4, 0x8056, 0x005a, 0xfcc5, 0x01c4, 0x22c2, 0x8009, 0x03c4 }, 16, 0x000ad9e0, 1},
++	{{0x22ca, 0x8009, 0x9ac0, 0xd813, 0xd991, 0x09c3, 0x22c8, 0x8009, 0x98c0, 0xda99, 0x09c3, 0x22c0, 0x8009, 0x9ac0, 0x2461, 0x9541 }, 16, 0x000ada00, 1},
++	{{0xd919, 0x21e1, 0x83af, 0x2220, 0x21b9, 0x09c3, 0x22bc, 0x8009, 0x2e55, 0x6ddd, 0x2c4c, 0x04c2, 0x22c8, 0x8009, 0x2274, 0x03c2 }, 16, 0x000ada20, 1},
++	{{0x22c0, 0x8009, 0x6e74, 0x4490, 0x2769, 0x01c4, 0x22ca, 0x8009, 0x94c0, 0xd991, 0x804d, 0x05c4, 0x22c2, 0x8009, 0x98c0, 0xd915 }, 16, 0x000ada40, 1},
++	{{0x08c3, 0x22c0, 0x8009, 0x0dc3, 0x22c8, 0x8009, 0x9cc0, 0xda1d, 0x2161, 0x9541, 0xda98, 0x20e1, 0x83af, 0x21b9, 0x2032, 0x09c3 }, 16, 0x000ada60, 1},
++	{{0x22bc, 0x8009, 0x2e4c, 0x6dc1, 0x2c4c, 0x03c2, 0x22c0, 0x8009, 0x21f4, 0x04c2, 0x22c8, 0x8009, 0x6df4, 0x4396, 0x3bc1, 0x00c4 }, 16, 0x000ada80, 1},
++	{{0x22cc, 0x8009, 0x7077, 0x2dff, 0x9ecb, 0x246a, 0x2f10, 0x3ac0, 0x21ec, 0x8009, 0x8497, 0x96c0, 0xe8ea, 0x2a0d, 0x800c, 0x98c0 }, 16, 0x000adaa0, 1},
++	{{0x3bc0, 0x21fc, 0x8009, 0xe864, 0x94c0, 0xeeed, 0xefed, 0x94c0, 0xfb49, 0xef64, 0x94c0, 0xee68, 0xf84a, 0x3dc0, 0x21ec, 0x8009 }, 16, 0x000adac0, 1},
++	{{0x00c6, 0x21e4, 0x8009, 0x1755, 0x3324, 0x2590, 0x800a, 0x9ac0, 0x75d0, 0xfaca, 0x04c6, 0x21e4, 0x8009, 0x98c0, 0x3bc0, 0x21f8 }, 16, 0x000adae0, 1},
++	{{0x8009, 0xf34b, 0x5192, 0xd641, 0x04c2, 0x21e4, 0x8009, 0x1153, 0x5096, 0x3224, 0x2590, 0x800a, 0xf14c, 0x3b41, 0x1497, 0x1596 }, 16, 0x000adb00, 1},
++	{{0xd910, 0x96c0, 0xd645, 0xf1cc, 0xf3cb, 0x98c0, 0x6238, 0xd993, 0x4496, 0xf9c9, 0x39ec, 0x9fff, 0x220f, 0x00c4, 0x22cc, 0x8009 }, 16, 0x000adb20, 1},
++	{{0x3076, 0x4459, 0x94c0, 0xf949, 0x8197, 0x27ea, 0x9fd0, 0xe7ea, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000adb40, 1},
++	{{0x3c00, 0xa006, 0x74d7, 0x280d, 0x8002, 0x7456, 0x57d1, 0x96c0, 0x4715, 0x290a, 0x8002, 0x13d1, 0xed44, 0x3a80, 0xa100, 0x3718 }, 16, 0x000adb60, 1},
++	{{0x8800, 0xe8ee, 0xe9ef, 0x96c0, 0x6469, 0xeeed, 0x9748, 0xee62, 0x96c3, 0x50d0, 0x26e0, 0x9cff, 0x98c1, 0xdf07, 0x4710, 0x311c }, 16, 0x000adb80, 1},
++	{{0x8300, 0x9cc7, 0x280b, 0x800c, 0x90c0, 0x4610, 0x90c0, 0xde1e, 0x98c7, 0x290c, 0x8008, 0x90c0, 0x4410, 0x16da, 0x07c4, 0x2318 }, 16, 0x000adba0, 1},
++	{{0x8009, 0x96c0, 0xd897, 0x2a0f, 0x8026, 0x3424, 0x8006, 0x4415, 0x10d2, 0xed42, 0x4016, 0x17cf, 0x05c4, 0x2318, 0x8009, 0xda95 }, 16, 0x000adbc0, 1},
++	{{0x34a7, 0x8007, 0x471d, 0x12d7, 0x01c4, 0x2318, 0x8009, 0xdb91, 0x34e0, 0x8002, 0x4015, 0x92d0, 0x56dc, 0x461b, 0x9748, 0x94c0 }, 16, 0x000adbe0, 1},
++	{{0xe85c, 0xe958, 0x92d0, 0x50d9, 0x4018, 0x9f70, 0x3a60, 0xb800, 0x77d1, 0x7750, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000adc00, 1},
++	{{0x98c0, 0x05a4, 0x33c0, 0x8009, 0xc3bc, 0x96c0, 0x7ee3, 0x9620, 0x9720, 0x9ac0, 0x7ae1, 0x05c0, 0x2318, 0x8009, 0xc94e, 0x3ec1 }, 16, 0x000adc20, 1},
++	{{0x34c2, 0x230c, 0x8009, 0x2c90, 0xcb45, 0x94c0, 0x9e20, 0x9f20, 0x3640, 0xa000, 0xe748, 0xeb1c, 0x1513, 0xf341, 0x32e4, 0x3c8a }, 16, 0x000adc40, 1},
++	{{0x8001, 0x98c0, 0xeee8, 0x05c0, 0x231a, 0x8009, 0x96c0, 0xc946, 0x2e08, 0x8002, 0x9748, 0x3800, 0xa100, 0x54d1, 0x290b, 0x8002 }, 16, 0x000adc60, 1},
++	{{0x96c0, 0x4410, 0x2e0a, 0x800c, 0x15d1, 0xe844, 0x9ac0, 0x3b1b, 0x8800, 0xebe8, 0x280d, 0x8002, 0x98c0, 0x65e9, 0xeb62, 0x290f }, 16, 0x000adc80, 1},
++	{{0x8008, 0x90c0, 0x96c3, 0x51d6, 0x23e0, 0x9cff, 0x96c3, 0xdd84, 0x331c, 0x8300, 0x94c3, 0xde1b, 0x4316, 0x4416, 0x3a00, 0xa100 }, 16, 0x000adca0, 1},
++	{{0x05c4, 0x2318, 0x8009, 0x51db, 0x3840, 0xa000, 0xd915, 0x2b0c, 0x8026, 0x3442, 0x8001, 0x4210, 0x3480, 0xa000, 0x55d3, 0x4513 }, 16, 0x000adcc0, 1},
++	{{0x12cc, 0x00c4, 0x2318, 0x8009, 0xd810, 0x3401, 0x8002, 0x411d, 0x12d4, 0x04c4, 0x2318, 0x8009, 0xda14, 0x3482, 0x8002, 0x4215 }, 16, 0x000adce0, 1},
++	{{0x92d0, 0x52df, 0x421a, 0x9748, 0x94c0, 0xee5c, 0xe958, 0x92d0, 0x56d9, 0x461e, 0x96c0, 0x55d0, 0x2d0c, 0x802c, 0x051c, 0xc781 }, 16, 0x000add00, 1},
++	{{0x071c, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x4714, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000add20, 1},
++	{{0x9ac0, 0x2260, 0x8488, 0x76f8, 0x2400, 0x8555, 0x3c55, 0x8000, 0x34f5, 0x35f5, 0x3000, 0x2000, 0x9000, 0x96c0, 0x64e6, 0x3743 }, 16, 0x000add40, 1},
++	{{0x8000, 0x9ac0, 0x3631, 0x9fff, 0x90c0, 0x379b, 0x8000, 0x90c0, 0x96c2, 0x3581, 0x2000, 0x8000, 0x92c2, 0x76fd, 0x94c6, 0x65e9 }, 16, 0x000add60, 1},
++	{{0x6c85, 0x3623, 0x8002, 0x7dee, 0x3665, 0x8003, 0x3aca, 0x944f, 0x9ac0, 0x3641, 0x8004, 0x90c0, 0x3444, 0x8004, 0xd994, 0xd5c1 }, 16, 0x000add80, 1},
++	{{0x36cd, 0x94cd, 0x3c55, 0x8000, 0x9ac0, 0x3444, 0x8005, 0x90c0, 0x3641, 0x8005, 0x3044, 0x8005, 0xda14, 0xd641, 0x6661, 0xd444 }, 16, 0x000adda0, 1},
++	{{0x7c6e, 0x94c7, 0x9f70, 0x6464, 0x7470, 0x90c0, 0x90c0, 0x90c0, 0x3a00, 0xa10c, 0x7456, 0x74d7, 0x50d0, 0xe9ef, 0x3c80, 0xa000 }, 16, 0x000addc0, 1},
++	{{0x311a, 0x8800, 0xe8ee, 0x311e, 0x8080, 0x9ac0, 0x23e0, 0x9b7f, 0x6569, 0x280f, 0x803a, 0x94c0, 0xdd80, 0x8485, 0x9cc0, 0x6769 }, 16, 0x000adde0, 1},
++	{{0x319e, 0x8000, 0xc781, 0x280a, 0x8036, 0x804b, 0x07c1, 0x231e, 0x8009, 0x1412, 0x57d0, 0x96c0, 0x6669, 0x3f98, 0x8000, 0x8013 }, 16, 0x000ade00, 1},
++	{{0x6469, 0x98c6, 0x2418, 0x80fe, 0x90c0, 0x7a61, 0x92c2, 0x4412, 0x94c0, 0xc481, 0xcfb0, 0x98c0, 0x04c1, 0x231c, 0x8009, 0xeeea }, 16, 0x000ade20, 1},
++	{{0x11d0, 0xee3f, 0x3378, 0x9c7f, 0x4010, 0x11d6, 0x30c4, 0x3f20, 0x800a, 0x4112, 0x98c0, 0x280b, 0x8036, 0x6769, 0xc9b0, 0xeaeb }, 16, 0x000ade40, 1},
++	{{0x94c7, 0xea39, 0xc781, 0x84ba, 0x96c3, 0x07c1, 0x231d, 0x8009, 0x10d2, 0x30c4, 0x3f20, 0x800a, 0x4013, 0x98c0, 0x77fb, 0x4310 }, 16, 0x000ade60, 1},
++	{{0x26e0, 0x9eff, 0x98c0, 0x3f1b, 0x8100, 0x5117, 0xe9ef, 0x3551, 0x38e1, 0xe962, 0x656d, 0x8473, 0x9ac0, 0x3413, 0x8100, 0xecef }, 16, 0x000ade80, 1},
++	{{0x22e0, 0x9dff, 0x94c0, 0x9e57, 0x9d57, 0x94c0, 0xcab0, 0xebef, 0x94c2, 0xee6c, 0xed6e, 0x94c6, 0xec6c, 0x5016, 0x94c6, 0xeb3a }, 16, 0x000adea0, 1},
++	{{0x4015, 0x11d0, 0xedef, 0x94c0, 0xdf01, 0xed6e, 0x0610, 0x0906, 0xa200, 0x347e, 0x4610, 0x1411, 0xdd00, 0x36d4, 0x7a61, 0x66ed }, 16, 0x000adec0, 1},
++	{{0x8421, 0x0210, 0x0902, 0xa100, 0x4210, 0x1215, 0xcdb2, 0x4214, 0x56d3, 0x4617, 0xef3d, 0x12d7, 0x30c4, 0x3f0a, 0x800a, 0x4211 }, 16, 0x000adee0, 1},
++	{{0x0411, 0x31c4, 0x3f0a, 0x800a, 0x4117, 0x56d0, 0x3d9d, 0x8000, 0x66e9, 0x90c0, 0x92c3, 0xc481, 0x96c3, 0x04c1, 0x231d, 0x8009 }, 16, 0x000adf00, 1},
++	{{0x98c0, 0x6c90, 0x52d0, 0x280f, 0x802c, 0x9ac0, 0x351c, 0x8200, 0x5017, 0x2809, 0x8030, 0x6669, 0x804b, 0x33c4, 0x3d40, 0x800a }, 16, 0x000adf20, 1},
++	{{0x96c0, 0xecef, 0x2f0d, 0x8004, 0x4015, 0x11d0, 0x0fc3, 0x231a, 0x8009, 0x9ac0, 0x3318, 0x8040, 0x5217, 0x3319, 0x8030, 0x2469 }, 16, 0x000adf40, 1},
++	{{0x7ce3, 0xc941, 0x94c1, 0xca90, 0xcaa0, 0xe9fc, 0xec3a, 0xe91c, 0x5151, 0x6360, 0x643f, 0xd998, 0x2f5d, 0x30c4, 0x3f88, 0x800a }, 16, 0x000adf60, 1},
++	{{0x4617, 0x4111, 0xe964, 0x4111, 0x98c0, 0x6d90, 0x55d0, 0x280e, 0x802e, 0x9ac0, 0x3b1e, 0x8100, 0x5016, 0x280c, 0x8032, 0x6769 }, 16, 0x000adf80, 1},
++	{{0x804b, 0x33c4, 0x3d40, 0x800a, 0x96c0, 0xebee, 0x2e0c, 0x8004, 0x4014, 0x17d0, 0x0bc3, 0x231a, 0x8009, 0x9ac0, 0x3f18, 0x8040 }, 16, 0x000adfa0, 1},
++	{{0x5516, 0x3f1a, 0x800c, 0x2469, 0x7442, 0xcc40, 0x94c1, 0xc990, 0xc9a0, 0xecfc, 0xeb39, 0xec1b, 0x5654, 0x6e5e, 0x642c, 0xdb98 }, 16, 0x000adfc0, 1},
++	{{0x2ddb, 0x30c4, 0x3ff0, 0x800a, 0x4316, 0x4314, 0xec64, 0x4314, 0x3820, 0xa800, 0x7750, 0x50d0, 0xefe9, 0x3820, 0xa000, 0x311a }, 16, 0x000adfe0, 1},
++	{{0x8400, 0xeee8, 0x6569, 0x90c0, 0x96c7, 0xe844, 0x2809, 0x8030, 0x98c7, 0x280c, 0x802c, 0x90c0, 0x5011, 0x9ac7, 0x2c0b, 0x8002 }, 16, 0x000ae000, 1},
++	{{0x90c0, 0x3e10, 0x8192, 0x92c3, 0x7c69, 0x92c3, 0x4011, 0x15d0, 0x5714, 0x3b1d, 0x8007, 0xd79d, 0x4714, 0x17d0, 0x5513, 0x3800 }, 16, 0x000ae020, 1},
++	{{0xa200, 0x3f1c, 0x8070, 0x77d1, 0x7e64, 0xd69c, 0x451b, 0x5414, 0x94c0, 0x6e55, 0x9f70, 0x3474, 0x4413, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ae040, 1},
++	{{0x98c0, 0x38c0, 0x22d0, 0x8009, 0x9f71, 0x96c0, 0xf485, 0x10fc, 0x9ff4, 0x666a, 0x2718, 0x8018, 0x2803, 0x800a, 0x9844, 0x90c0 }, 16, 0x000ae060, 1},
++	{{0x5159, 0x92d0, 0x6174, 0x2565, 0x5159, 0x4258, 0x9f71, 0x96c0, 0xf48a, 0x10fc, 0x9ff6, 0x266a, 0x12fc, 0x9fee, 0x2718, 0x802c }, 16, 0x000ae080, 1},
++	{{0x9822, 0x96c0, 0xfbc6, 0x187a, 0x9fe2, 0x96c0, 0x9844, 0x2803, 0x800c, 0x5161, 0x5363, 0x2274, 0x22f5, 0x5161, 0x94d0, 0x6e55 }, 16, 0x000ae0a0, 1},
++	{{0x5363, 0x6665, 0x4458, 0x9823, 0x9f71, 0x1005, 0xa004, 0x3860, 0x3fc0, 0x8004, 0x2341, 0x8000, 0x3c00, 0xa008, 0x74d0, 0x6cd3 }, 16, 0x000ae0c0, 1},
++	{{0x6466, 0x2481, 0x8000, 0x3c00, 0xa805, 0x32c8, 0x87c0, 0x64e1, 0x38cc, 0x8800, 0x1890, 0x0d50, 0xa000, 0x92c2, 0x6c00, 0x3620 }, 16, 0x000ae0e0, 1},
++	{{0xa000, 0x0d50, 0xa000, 0x3606, 0xa04c, 0x6c00, 0x6e93, 0x3600, 0xa08c, 0x66e9, 0x6e13, 0x92c2, 0x7861, 0x3600, 0xa004, 0x6669 }, 16, 0x000ae100, 1},
++	{{0x7550, 0x3606, 0xa004, 0x7861, 0x7d76, 0x3e00, 0xa603, 0x30cc, 0x8580, 0x7550, 0x30cc, 0x8580, 0xc852, 0x3800, 0xa009, 0x7e49 }, 16, 0x000ae120, 1},
++	{{0x7e49, 0x7d76, 0x3620, 0xa100, 0x5f40, 0xc852, 0x3600, 0xa804, 0x6317, 0x5b40, 0x3600, 0xb000, 0x64e8, 0x610c, 0x3607, 0xa00c }, 16, 0x000ae140, 1},
++	{{0x6764, 0x64e8, 0x3607, 0xb000, 0x6564, 0x74ce, 0x344a, 0xf5c1, 0x4952, 0x9f70, 0xc565, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ae160, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3a20, 0xa000, 0x0cc6, 0x38d0, 0x8008, 0xe748, 0x2700, 0x8040, 0x3840, 0xa000 }, 16, 0x000ae180, 1},
++	{{0xf741, 0x2c09, 0x8248, 0x32e4, 0x3c84, 0x8001, 0x38c0, 0x2320, 0x8009, 0x0ac6, 0x38d0, 0x8008, 0x3fe8, 0x3c10, 0xbfff, 0x2a0b }, 16, 0x000ae1a0, 1},
++	{{0x8264, 0x14db, 0x3de8, 0x3c14, 0xbfff, 0x9ac0, 0xdb94, 0x51d3, 0x34f9, 0x3fff, 0xbf00, 0x98c0, 0xdc9f, 0x3ae8, 0x3c14, 0xbfff }, 16, 0x000ae1c0, 1},
++	{{0x0197, 0x3ec0, 0x2336, 0x8009, 0x1195, 0x0bc6, 0x38d0, 0x8008, 0x98c0, 0xde01, 0x38c8, 0x380c, 0xbfff, 0x9ac0, 0x2b0b, 0x8268 }, 16, 0x000ae1e0, 1},
++	{{0x90c0, 0x2e0d, 0x8002, 0x13d3, 0x3bc8, 0x380c, 0xbfff, 0x98c0, 0xdd9c, 0x3f00, 0x2048, 0x8008, 0x4392, 0x16d6, 0x5090, 0x96c0 }, 16, 0x000ae200, 1},
++	{{0x31e8, 0x9fff, 0x51d5, 0x96c0, 0xdc86, 0x26e0, 0x8fef, 0xdc98, 0x4193, 0x10d7, 0x0ac6, 0x38d0, 0x8008, 0x315f, 0x8000, 0x96c0 }, 16, 0x000ae220, 1},
++	{{0x67e9, 0x2a0a, 0x825e, 0x94c0, 0x54d2, 0x800b, 0xdf04, 0x4612, 0x9ac0, 0x6f10, 0x08c6, 0x38d0, 0x8008, 0x9351, 0x3bc8, 0x3810 }, 16, 0x000ae240, 1},
++	{{0xbfff, 0x9ac0, 0x280a, 0x825e, 0x90c0, 0x2b03, 0x803a, 0x12d2, 0x3dc8, 0x3808, 0xbfff, 0x0293, 0x3fc8, 0x3808, 0xbfff, 0x15d6 }, 16, 0x000ae260, 1},
++	{{0x0ac6, 0x38d0, 0x8008, 0x9ac0, 0xd985, 0x5795, 0x38c0, 0x2376, 0x8009, 0x96c0, 0xdf83, 0x2a0c, 0x8262, 0x4714, 0x5297, 0x6560 }, 16, 0x000ae280, 1},
++	{{0x94d0, 0xd50e, 0x7b41, 0x351d, 0x8001, 0x9580, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000ae2a0, 1},
++	{{0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x52d3, 0x351a, 0x8001, 0x6569, 0x90c0, 0x96c3, 0x33e4, 0x3a8c, 0x8001, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000ae2c0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3ec0, 0x2336, 0x8009, 0x3bc8, 0x3808, 0xbfff, 0x96c0, 0x55d6, 0x2e0f, 0x8004 }, 16, 0x000ae2e0, 1},
++	{{0x9ac0, 0xd885, 0x5693, 0x38c8, 0x3808, 0xbfff, 0x98c0, 0xdf01, 0x03c5, 0x2376, 0x8009, 0x4617, 0x50d6, 0x311f, 0x8001, 0x67e9 }, 16, 0x000ae300, 1},
++	{{0x2718, 0x80fe, 0x1590, 0x3cc8, 0x3808, 0xbfff, 0x3b18, 0x8001, 0xdc13, 0x6460, 0x6469, 0x2518, 0x80e8, 0x1794, 0xe8ee, 0x96c0 }, 16, 0x000ae320, 1},
++	{{0x3f1d, 0x8001, 0xe862, 0x26e9, 0x56d0, 0x96c0, 0x3d1d, 0x8001, 0x8055, 0x26e9, 0x07c6, 0x2364, 0x8009, 0x8029, 0x98c0, 0x67e9 }, 16, 0x000ae340, 1},
++	{{0xc947, 0x2f0d, 0x800e, 0x94c0, 0x55dd, 0x801d, 0x52d1, 0xde82, 0x4511, 0x14d5, 0x0ac6, 0x2364, 0x8009, 0x90c0, 0x55d2, 0xde1d }, 16, 0x000ae360, 1},
++	{{0x4412, 0x2f08, 0x8008, 0x50d0, 0x3118, 0x8001, 0x6469, 0x90c0, 0x98c3, 0x6c90, 0x32e4, 0x22c0, 0x800a, 0x92c3, 0xc082, 0x98c0 }, 16, 0x000ae380, 1},
++	{{0x39c8, 0x3808, 0xbfff, 0xe8ee, 0xe862, 0x1291, 0x57d0, 0x9ac0, 0x351e, 0x8001, 0x90c0, 0x3f1c, 0x8002, 0x6769, 0x844f, 0x2669 }, 16, 0x000ae3a0, 1},
++	{{0x05c6, 0x236c, 0x8009, 0x8029, 0x98c0, 0x66e9, 0xc945, 0x2f08, 0x8014, 0x94c0, 0x53d8, 0x801d, 0x54d1, 0xdd84, 0x4311, 0x10d0 }, 16, 0x000ae3c0, 1},
++	{{0x0cc6, 0x236c, 0x8009, 0x90c0, 0x54d4, 0xdc1c, 0x4014, 0x2f0b, 0x800a, 0x51d3, 0x331e, 0x8001, 0x6769, 0x90c0, 0x98c3, 0x6c90 }, 16, 0x000ae3e0, 1},
++	{{0x32e4, 0x22c0, 0x800a, 0x92c3, 0xc083, 0x3ac8, 0x3808, 0xbfff, 0x90c0, 0x5492, 0x391f, 0x8001, 0x07c1, 0x2376, 0x8009, 0x13d6 }, 16, 0x000ae400, 1},
++	{{0x30ca, 0x3808, 0xbfff, 0x371f, 0x8002, 0x27e9, 0x3bc0, 0x2377, 0x8009, 0x2718, 0x8108, 0x3680, 0xa000, 0x5490, 0x97bb, 0x391e }, 16, 0x000ae420, 1},
++	{{0x8002, 0x276e, 0x3cc8, 0x3808, 0xbfff, 0xdf17, 0x6769, 0x2518, 0x80ec, 0x1794, 0xedee, 0x96c0, 0x3f18, 0x8002, 0xed62, 0x2469 }, 16, 0x000ae440, 1},
++	{{0x50d5, 0x96c0, 0x3118, 0x8004, 0x8055, 0x2469, 0x00c6, 0x2368, 0x8009, 0x8029, 0x98c0, 0x6469, 0xcb40, 0x2f09, 0x801a, 0x94c0 }, 16, 0x000ae460, 1},
++	{{0x55d9, 0x801d, 0x53d3, 0xde83, 0x4513, 0x12d1, 0x0ac6, 0x2368, 0x8009, 0x90c0, 0x54d2, 0xdd1c, 0x4212, 0x2f0d, 0x8008, 0x56d5 }, 16, 0x000ae480, 1},
++	{{0x3d1f, 0x8002, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc181, 0xc082, 0x3dc8, 0x3808, 0xbfff, 0x90c0, 0x1295 }, 16, 0x000ae4a0, 1},
++	{{0xedee, 0x96c0, 0x351a, 0x8002, 0xed62, 0x2569, 0x51d5, 0x96c0, 0x331d, 0x8008, 0x8455, 0x26e9, 0x00c6, 0x2360, 0x8009, 0x8029 }, 16, 0x000ae4c0, 1},
++	{{0x98c0, 0x6469, 0xcd40, 0x2f0a, 0x8020, 0x94c0, 0x57da, 0x801d, 0x53d5, 0xdf83, 0x4715, 0x17d2, 0x08c6, 0x2360, 0x8009, 0x90c0 }, 16, 0x000ae4e0, 1},
++	{{0x56d0, 0xdf9e, 0x4710, 0x2f08, 0x800a, 0x57d0, 0x3f1f, 0x8002, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc181 }, 16, 0x000ae500, 1},
++	{{0xc083, 0x31ca, 0x3808, 0xbfff, 0x3bc0, 0x2377, 0x8009, 0x3480, 0xa000, 0x5791, 0x3ecc, 0x8041, 0x949b, 0x11d6, 0x36ca, 0x3808 }, 16, 0x000ae520, 1},
++	{{0xbfff, 0x3318, 0x8004, 0x2469, 0x38c0, 0x2378, 0x8009, 0x84d7, 0x3680, 0xa000, 0x5196, 0x93b8, 0x331c, 0x8004, 0x98c0, 0xde22 }, 16, 0x000ae540, 1},
++	{{0x3bc8, 0x3808, 0xbfff, 0xde13, 0x6669, 0x80bb, 0x1693, 0xedee, 0x96c0, 0x3d1f, 0x8004, 0xed62, 0x27e9, 0x50d5, 0x96c0, 0x311f }, 16, 0x000ae560, 1},
++	{{0x8010, 0x8031, 0x27e9, 0x2e10, 0x0ac6, 0x38d0, 0x8008, 0x801f, 0x2a0c, 0x810a, 0x5114, 0x78e1, 0x4114, 0x0bc6, 0x38d0, 0x8008 }, 16, 0x000ae580, 1},
++	{{0x90c0, 0x2b08, 0x810a, 0x5010, 0x6c7c, 0x4410, 0x3bc8, 0x3808, 0xbfff, 0x2f0d, 0x8008, 0x1693, 0x52d5, 0x9ac0, 0x3d1c, 0x8004 }, 16, 0x000ae5a0, 1},
++	{{0x90c0, 0x351e, 0x8004, 0x6669, 0x8015, 0x6769, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc182, 0xc082, 0x38c8, 0x3808 }, 16, 0x000ae5c0, 1},
++	{{0xbfff, 0x2f0d, 0x800a, 0x1290, 0x55d5, 0x9ac0, 0x351e, 0x8004, 0x90c0, 0x3b1c, 0x8004, 0x6769, 0x8415, 0x6669, 0x90c0, 0x96c3 }, 16, 0x000ae5e0, 1},
++	{{0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc182, 0xc083, 0x32ca, 0x3808, 0xbfff, 0x38c0, 0x2378, 0x8009, 0x3480, 0xa000, 0x5292, 0x34cc }, 16, 0x000ae600, 1},
++	{{0x8042, 0x9498, 0x14d6, 0x33ca, 0x3808, 0xbfff, 0x391f, 0x8008, 0x27e9, 0x3bc0, 0x2379, 0x8009, 0x2718, 0x80da, 0x3680, 0xa000 }, 16, 0x000ae620, 1},
++	{{0x5693, 0x93bb, 0x3d19, 0x8008, 0x98c0, 0xdca3, 0x3dc8, 0x3808, 0xbfff, 0xdc93, 0x64e9, 0x80bd, 0x1195, 0xe9ee, 0x96c0, 0x331d }, 16, 0x000ae640, 1},
++	{{0x8008, 0xe962, 0x26e9, 0x56d1, 0x96c0, 0x3d18, 0x8020, 0x8035, 0x2469, 0x0cc6, 0x38d0, 0x8008, 0x96c0, 0x8025, 0x2400, 0x8078 }, 16, 0x000ae660, 1},
++	{{0x2c0b, 0x810a, 0x5513, 0x7ac1, 0x4513, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c08, 0x810a, 0x5010, 0x6c7d, 0x4410, 0x3dc8, 0x3808 }, 16, 0x000ae680, 1},
++	{{0xbfff, 0x2f0c, 0x8008, 0x5595, 0x3b1b, 0x8008, 0x25e9, 0x53d4, 0x96c0, 0x3718, 0x8008, 0x801b, 0x6469, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000ae6a0, 1},
++	{{0x22c0, 0x800a, 0x94c3, 0xc183, 0xc082, 0x3ac8, 0x3808, 0xbfff, 0x2f0c, 0x800a, 0x1292, 0x54d4, 0x9ac0, 0x3518, 0x8008, 0x90c0 }, 16, 0x000ae6c0, 1},
++	{{0x391e, 0x8008, 0x6469, 0x8415, 0x6769, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc183, 0xc083, 0x34ca, 0x3808, 0xbfff }, 16, 0x000ae6e0, 1},
++	{{0x3bc0, 0x2379, 0x8009, 0x3480, 0xa000, 0x5594, 0x3aca, 0x8043, 0x929b, 0x12d6, 0x37ca, 0x3808, 0xbfff, 0x351c, 0x8010, 0x2669 }, 16, 0x000ae700, 1},
++	{{0x3dc0, 0x237a, 0x8009, 0x2718, 0x80dc, 0x3680, 0xa000, 0x5797, 0x96bd, 0x3f1c, 0x8010, 0x98c0, 0xde24, 0x39c8, 0x3808, 0xbfff }, 16, 0x000ae720, 1},
++	{{0xde16, 0x6669, 0x80bf, 0x1491, 0xedee, 0x96c0, 0x391a, 0x8010, 0xed62, 0x2569, 0x55d5, 0x96c0, 0x3b1c, 0x8040, 0x8037, 0x2669 }, 16, 0x000ae740, 1},
++	{{0x0cc6, 0x38d0, 0x8008, 0x8027, 0x2c0c, 0x8100, 0x57d4, 0x3f1e, 0x8100, 0x6769, 0x90c0, 0x9ac1, 0x20e0, 0x9eff, 0x90c0, 0x0907 }, 16, 0x000ae760, 1},
++	{{0xa100, 0x94c1, 0xdc07, 0x4714, 0x92c3, 0x4014, 0x39c8, 0x3808, 0xbfff, 0x2f0a, 0x8008, 0x5291, 0x351e, 0x8010, 0x2769, 0x56d2 }, 16, 0x000ae780, 1},
++	{{0x96c0, 0x3d1a, 0x8010, 0x801b, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc184, 0xc082, 0x3dc8, 0x3808, 0xbfff }, 16, 0x000ae7a0, 1},
++	{{0x2f0a, 0x800a, 0x1295, 0x57d2, 0x9ac0, 0x3518, 0x8010, 0x90c0, 0x3f1e, 0x8010, 0x6469, 0x8415, 0x6769, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000ae7c0, 1},
++	{{0x22c0, 0x800a, 0x94c3, 0xc184, 0xc083, 0x35ca, 0x3808, 0xbfff, 0x3dc0, 0x237a, 0x8009, 0x3480, 0xa000, 0x5395, 0x36cb, 0x8044 }, 16, 0x000ae7e0, 1},
++	{{0x939d, 0x15d6, 0x30ca, 0x3808, 0xbfff, 0x96c0, 0x3b19, 0x8020, 0xecee, 0x9ac0, 0x64e9, 0x39c0, 0x237b, 0x8009, 0xec62, 0x94c0 }, 16, 0x000ae800, 1},
++	{{0x51d4, 0x84a1, 0x3680, 0xa000, 0x5790, 0x94b9, 0x3f1a, 0x8020, 0x98c0, 0xdd25, 0x38c8, 0x3808, 0xbfff, 0xdd14, 0x6569, 0x2518 }, 16, 0x000ae820, 1},
++	{{0x80f2, 0x96c0, 0x5690, 0x2f08, 0x8008, 0x96c0, 0x3d1b, 0x8020, 0x50d0, 0x96c0, 0x65e9, 0x311b, 0x8020, 0x8015, 0x65e9, 0x90c0 }, 16, 0x000ae840, 1},
++	{{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc185, 0xc082, 0x3bc8, 0x3808, 0xbfff, 0x2f0a, 0x800a, 0x1693, 0x51d2, 0x9ac0, 0x3d1b }, 16, 0x000ae860, 1},
++	{{0x8020, 0x90c0, 0x3318, 0x8020, 0x65e9, 0x8415, 0x6469, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc185, 0xc083, 0x31ca }, 16, 0x000ae880, 1},
++	{{0x3808, 0xbfff, 0x39c0, 0x237b, 0x8009, 0x3480, 0xa000, 0x5491, 0x38cb, 0x8045, 0x98c0, 0x9399, 0x31e4, 0x2930, 0x800a, 0x331d }, 16, 0x000ae8a0, 1},
++	{{0x8080, 0x26e9, 0x09c6, 0x38d0, 0x8008, 0x8067, 0x290c, 0x8100, 0x14d4, 0x3cc8, 0x380c, 0xbfff, 0x391c, 0x8100, 0x6669, 0x8027 }, 16, 0x000ae8c0, 1},
++	{{0x5394, 0x3719, 0x8020, 0x64e9, 0x90c0, 0x96c2, 0x3ac8, 0x380c, 0xbfff, 0x90c0, 0x92c2, 0x5192, 0x96c6, 0x8038, 0x0901, 0xa020 }, 16, 0x000ae8e0, 1},
++	{{0x92c2, 0x4192, 0x2669, 0x3cc8, 0x380c, 0xbfff, 0x8425, 0x5194, 0x331f, 0x8020, 0x67e9, 0x90c0, 0x98c3, 0x3bc8, 0x380c, 0xbfff }, 16, 0x000ae900, 1},
++	{{0xc7df, 0x90c0, 0x92c3, 0x5093, 0x92c3, 0xdf80, 0x92c3, 0x4793, 0x15d6, 0x36ca, 0x3808, 0xbfff, 0x3b1e, 0x8040, 0x2769, 0x3bc0 }, 16, 0x000ae920, 1},
++	{{0x237c, 0x8009, 0x84bf, 0x3680, 0xa000, 0x5296, 0x94bb, 0x351d, 0x8040, 0x98c0, 0xdea6, 0x39c8, 0x3808, 0xbfff, 0xde94, 0x66e9 }, 16, 0x000ae940, 1},
++	{{0x80a3, 0x1491, 0xe8ee, 0x96c0, 0x391a, 0x8040, 0xe862, 0x2569, 0x56d0, 0x96c0, 0x3d1e, 0x8100, 0x8019, 0x6769, 0x90c0, 0x96c3 }, 16, 0x000ae960, 1},
++	{{0x3204, 0x33b0, 0x800b, 0x92c3, 0xc081, 0x3ac8, 0x3808, 0xbfff, 0x2f08, 0x8008, 0x5292, 0x96c0, 0x351e, 0x8040, 0x52d0, 0x96c0 }, 16, 0x000ae980, 1},
++	{{0x6769, 0x3518, 0x8040, 0x8015, 0x6469, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc186, 0xc082, 0x3bc8, 0x3808, 0xbfff }, 16, 0x000ae9a0, 1},
++	{{0x2f09, 0x800a, 0x1493, 0x51d1, 0x9ac0, 0x391e, 0x8040, 0x90c0, 0x3318, 0x8040, 0x6769, 0x8415, 0x6469, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000ae9c0, 1},
++	{{0x22c0, 0x800a, 0x94c3, 0xc186, 0xc083, 0x32ca, 0x3808, 0xbfff, 0x3bc0, 0x237c, 0x8009, 0x3480, 0xa000, 0x5292, 0x34ca, 0x8046 }, 16, 0x000ae9e0, 1},
++	{{0x929b, 0x17d6, 0x3ac8, 0x3808, 0xbfff, 0x3f1d, 0x8080, 0x66e9, 0x2718, 0x8116, 0x1392, 0xeaee, 0x96c0, 0x371c, 0x8080, 0xea62 }, 16, 0x000aea00, 1},
++	{{0x2669, 0x54d2, 0x96c0, 0x391e, 0x8200, 0x8067, 0x2769, 0x6c10, 0x805b, 0x33e4, 0x39e4, 0x8001, 0x98c0, 0x3be8, 0x2004, 0xbfff }, 16, 0x000aea20, 1},
++	{{0xc081, 0x90c0, 0x5293, 0x0912, 0xa080, 0x3204, 0x34a0, 0x800b, 0x4293, 0x98c0, 0x39e8, 0x2004, 0xbfff, 0xee74, 0x37f9, 0x3fff }, 16, 0x000aea40, 1},
++	{{0xbf7f, 0x5291, 0xdf82, 0x4791, 0x11d6, 0x04c7, 0x2320, 0x8009, 0x6669, 0x2718, 0x85da, 0x64e9, 0x92c2, 0x6c10, 0x96c2, 0x33e4 }, 16, 0x000aea60, 1},
++	{{0x39ea, 0x8001, 0x31e4, 0x304c, 0x800a, 0x33ca, 0x3808, 0xbfff, 0x38c0, 0x237d, 0x8009, 0x3a80, 0xa000, 0x5293, 0x3cc8, 0x3808 }, 16, 0x000aea80, 1},
++	{{0xbfff, 0x96c0, 0x351a, 0x8080, 0x94b8, 0xdd27, 0xdd14, 0x6569, 0x8077, 0x96c0, 0x5094, 0x2f0d, 0x8008, 0x96c0, 0x311a, 0x8080 }, 16, 0x000aeaa0, 1},
++	{{0x57d5, 0x96c0, 0x6569, 0x3f1a, 0x8080, 0x8015, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc187, 0xc082, 0x3cc8 }, 16, 0x000aeac0, 1},
++	{{0x3808, 0xbfff, 0x2f09, 0x800a, 0x1694, 0x53d1, 0x9ac0, 0x3d1f, 0x8080, 0x90c0, 0x371d, 0x8080, 0x67e9, 0x8415, 0x66e9, 0x90c0 }, 16, 0x000aeae0, 1},
++	{{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc187, 0xc083, 0x34ca, 0x3808, 0xbfff, 0x38c0, 0x237d, 0x8009, 0x3480, 0xa000, 0x5194 }, 16, 0x000aeb00, 1},
++	{{0x32c9, 0x8047, 0x9198, 0x15d6, 0x37ca, 0x3808, 0xbfff, 0x3b19, 0x8100, 0x24e9, 0x3ac0, 0x237e, 0x8009, 0x8491, 0x3680, 0xa000 }, 16, 0x000aeb20, 1},
++	{{0x5197, 0x95ba, 0x331e, 0x8100, 0x98c0, 0xdf28, 0x3bc8, 0x3808, 0xbfff, 0xdf15, 0x6769, 0x8075, 0x96c0, 0x5693, 0x2f09, 0x8008 }, 16, 0x000aeb40, 1},
++	{{0x96c0, 0x3d19, 0x8100, 0x55d1, 0x96c0, 0x64e9, 0x3b1d, 0x8100, 0x8015, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3 }, 16, 0x000aeb60, 1},
++	{{0xc188, 0xc082, 0x3ac8, 0x3808, 0xbfff, 0x2f0d, 0x800a, 0x5692, 0x3d1e, 0x8100, 0x2769, 0x56d5, 0x96c0, 0x3d1e, 0x8100, 0x841b }, 16, 0x000aeb80, 1},
++	{{0x6769, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc188, 0xc083, 0x35ca, 0x3808, 0xbfff, 0x3ac0, 0x237e, 0x8009, 0x3480 }, 16, 0x000aeba0, 1},
++	{{0xa000, 0x5695, 0x3ccc, 0x8048, 0x949a, 0x10d6, 0x30ca, 0x3808, 0xbfff, 0x3119, 0x8200, 0x24e9, 0x3cc0, 0x237f, 0x8009, 0x8495 }, 16, 0x000aebc0, 1},
++	{{0x3680, 0xa000, 0x5190, 0x95bc, 0x331c, 0x8200, 0x98c0, 0xde29, 0x39c8, 0x3808, 0xbfff, 0xde15, 0x6669, 0x8079, 0x96c0, 0x5291 }, 16, 0x000aebe0, 1},
++	{{0x2f0c, 0x8008, 0x351d, 0x8200, 0x26e9, 0x55d4, 0x96c0, 0x3b1a, 0x8200, 0x801b, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a }, 16, 0x000aec00, 1},
++	{{0x94c3, 0xc189, 0xc082, 0x3bc8, 0x3808, 0xbfff, 0x90c0, 0x96c0, 0x5193, 0x2f0b, 0x800a, 0x96c0, 0x331a, 0x8200, 0x51d3, 0x96c0 }, 16, 0x000aec20, 1},
++	{{0x6569, 0x331c, 0x8200, 0x8415, 0x6669, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc189, 0xc083, 0x31ca, 0x3808, 0xbfff }, 16, 0x000aec40, 1},
++	{{0x3cc0, 0x237f, 0x8009, 0x3480, 0xa000, 0x5691, 0x3ccd, 0x8049, 0x959c, 0x11d6, 0x36ca, 0x3808, 0xbfff, 0x3318, 0x8400, 0x2469 }, 16, 0x000aec60, 1},
++	{{0x39c0, 0x2380, 0x8009, 0x8495, 0x3680, 0xa000, 0x5396, 0x92b9, 0x371c, 0x8400, 0x98c0, 0xde2a, 0x38c8, 0x3808, 0xbfff, 0xde12 }, 16, 0x000aec80, 1},
++	{{0x6669, 0x8079, 0x96c0, 0x5690, 0x2f0d, 0x8008, 0x3d1d, 0x8400, 0x26e9, 0x55d5, 0x96c0, 0x3b19, 0x8400, 0x801b, 0x64e9, 0x90c0 }, 16, 0x000aeca0, 1},
++	{{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18a, 0xc082, 0x39c8, 0x3808, 0xbfff, 0x90c0, 0x96c0, 0x5791, 0x2f09, 0x800a, 0x96c0 }, 16, 0x000aecc0, 1},
++	{{0x3f18, 0x8400, 0x55d1, 0x96c0, 0x6469, 0x3b1b, 0x8400, 0x8415, 0x65e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18a }, 16, 0x000aece0, 1},
++	{{0xc083, 0x32ca, 0x3808, 0xbfff, 0x39c0, 0x2380, 0x8009, 0x3480, 0xa000, 0x5192, 0x32c9, 0x804a, 0x9199, 0x17d6, 0x32ca, 0x3808 }, 16, 0x000aed00, 1},
++	{{0xbfff, 0x3f19, 0x8800, 0x24e9, 0x3cc0, 0x2381, 0x8009, 0x8493, 0x3680, 0xa000, 0x5692, 0x90bc, 0x3d1e, 0x8800, 0x98c0, 0xdf2b }, 16, 0x000aed20, 1},
++	{{0x3dc8, 0x3808, 0xbfff, 0xdf10, 0x6769, 0x8077, 0x96c0, 0x5495, 0x2f0b, 0x8008, 0x96c0, 0x391a, 0x8800, 0x50d3, 0x96c0, 0x6569 }, 16, 0x000aed40, 1},
++	{{0x311d, 0x8800, 0x8015, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18b, 0xc082, 0x39c8, 0x3808, 0xbfff, 0x2f0b }, 16, 0x000aed60, 1},
++	{{0x800a, 0x1091, 0x56d3, 0x9ac0, 0x311a, 0x8800, 0x90c0, 0x3d1f, 0x8800, 0x6569, 0x8415, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0 }, 16, 0x000aed80, 1},
++	{{0x800a, 0x94c3, 0xc18b, 0xc083, 0x36ca, 0x3808, 0xbfff, 0x3cc0, 0x2381, 0x8009, 0x3480, 0xa000, 0x5696, 0x3ccd, 0x804b, 0x959c }, 16, 0x000aeda0, 1},
++	{{0x17d6, 0x31ca, 0x3808, 0xbfff, 0x3f1d, 0x9000, 0x26e9, 0x3cc0, 0x2382, 0x8009, 0x8493, 0x3680, 0xa000, 0x5191, 0x95bc, 0x331b }, 16, 0x000aedc0, 1},
++	{{0x9000, 0x98c0, 0xddac, 0x3bc8, 0x3808, 0xbfff, 0xdd95, 0x65e9, 0x8077, 0x96c0, 0x5693, 0x2f0a, 0x8008, 0x96c0, 0x3d1d, 0x9000 }, 16, 0x000aede0, 1},
++	{{0x54d2, 0x96c0, 0x66e9, 0x391d, 0x9000, 0x8015, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18c, 0xc082, 0x3bc8 }, 16, 0x000aee00, 1},
++	{{0x3808, 0xbfff, 0x2f08, 0x800a, 0x1493, 0x55d0, 0x9ac0, 0x391b, 0x9000, 0x90c0, 0x3b1d, 0x9000, 0x65e9, 0x8415, 0x66e9, 0x90c0 }, 16, 0x000aee20, 1},
++	{{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18c, 0xc083, 0x30ca, 0x3808, 0xbfff, 0x3cc0, 0x2382, 0x8009, 0x3480, 0xa000, 0x5690 }, 16, 0x000aee40, 1},
++	{{0x3ccb, 0x804c, 0x939c, 0x17d6, 0x35ca, 0x3808, 0xbfff, 0x3f3f, 0x8000, 0x27e9, 0x3cc0, 0x2383, 0x8009, 0x8493, 0x3680, 0xa000 }, 16, 0x000aee60, 1},
++	{{0x5195, 0x97bc, 0x333d, 0x8000, 0x98c0, 0xdead, 0x3dc8, 0x3808, 0xbfff, 0xde97, 0x66e9, 0x8077, 0x96c0, 0x5395, 0x2f0c, 0x8008 }, 16, 0x000aee80, 1},
++	{{0x96c0, 0x373d, 0x8000, 0x50d4, 0x96c0, 0x66e9, 0x313a, 0x8000, 0x8015, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3 }, 16, 0x000aeea0, 1},
++	{{0xc18d, 0xc082, 0x3cc8, 0x3808, 0xbfff, 0x2f0d, 0x800a, 0x1094, 0x52d5, 0x9ac0, 0x3139, 0x8000, 0x90c0, 0x353b, 0x8000, 0x64e9 }, 16, 0x000aeec0, 1},
++	{{0x8415, 0x65e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18d, 0xc083, 0x37ca, 0x3808, 0xbfff, 0x3cc0, 0x2383, 0x8009 }, 16, 0x000aeee0, 1},
++	{{0x3480, 0xa000, 0x5297, 0x34cb, 0x804d, 0x939c, 0x13d6, 0x34ca, 0x3808, 0xbfff, 0x375b, 0x8000, 0x25e9, 0x3dc0, 0x2384, 0x8009 }, 16, 0x000aef00, 1},
++	{{0x8493, 0x3a80, 0xa000, 0x5694, 0x39c8, 0x3808, 0xbfff, 0x96c0, 0x3d59, 0x8000, 0x96bd, 0xdcae, 0xdc96, 0x64e9, 0x8077, 0x96c0 }, 16, 0x000aef20, 1},
++	{{0x5091, 0x2f0b, 0x8008, 0x96c0, 0x315c, 0x8000, 0x52d3, 0x96c0, 0x6669, 0x355c, 0x8000, 0x8015, 0x6669, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000aef40, 1},
++	{{0x22c0, 0x800a, 0x94c3, 0xc18e, 0xc082, 0x39c8, 0x3808, 0xbfff, 0x2f08, 0x800a, 0x5791, 0x96c0, 0x3f5a, 0x8000, 0x57d0, 0x96c0 }, 16, 0x000aef60, 1},
++	{{0x6569, 0x3f5f, 0x8000, 0x8415, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18e, 0xc083, 0x33ca, 0x3808, 0xbfff }, 16, 0x000aef80, 1},
++	{{0x3dc0, 0x2384, 0x8009, 0x3480, 0xa000, 0x5693, 0x3ccd, 0x804e, 0x959d, 0x14d6, 0x39c8, 0x3808, 0xbfff, 0x399d, 0x8000, 0x26e9 }, 16, 0x000aefa0, 1},
++	{{0x3ec0, 0x2385, 0x8009, 0x8487, 0x94c0, 0x5591, 0x97be, 0x3b98, 0x8000, 0x98c0, 0xdc2f, 0x3dc8, 0x3808, 0xbfff, 0xdc17, 0x6469 }, 16, 0x000aefc0, 1},
++	{{0x806d, 0x96c0, 0x5195, 0x2f0a, 0x8008, 0x96c0, 0x339a, 0x8000, 0x57d2, 0x96c0, 0x6569, 0x3f9d, 0x8000, 0x8015, 0x66e9, 0x90c0 }, 16, 0x000aefe0, 1},
++	{{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18f, 0xc082, 0x98c0, 0x38c8, 0x3808, 0xbfff, 0xef4a, 0x52d7, 0x5490, 0x399d, 0x8000 }, 16, 0x000af000, 1},
++	{{0x96c0, 0x66e9, 0x359d, 0x8000, 0x8415, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18f, 0xc083, 0x3cc8, 0x3808 }, 16, 0x000af020, 1},
++	{{0xbfff, 0x90c0, 0x5094, 0x30cc, 0x804f, 0x949e, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000af040, 1},
++	{{0x3e00, 0xa10c, 0x7556, 0x75d7, 0x09c6, 0x38d0, 0x8008, 0xcf49, 0x3c80, 0xa000, 0x6e90, 0x3fc0, 0x2334, 0x8009, 0xce48, 0x3680 }, 16, 0x000af060, 1},
++	{{0xa000, 0x290d, 0x825c, 0x3680, 0xa000, 0x53d5, 0x50d7, 0x96c0, 0x71e0, 0x371c, 0x8001, 0x2518, 0x857e, 0x98c0, 0x6669, 0x371b }, 16, 0x000af080, 1},
++	{{0x8002, 0x4317, 0x8431, 0x65e9, 0x90c0, 0x98c2, 0xc0fe, 0x04c7, 0x2372, 0x8009, 0x9ac2, 0xdc04, 0xc6fc, 0x03c7, 0x2374, 0x8009 }, 16, 0x000af0a0, 1},
++	{{0x98c2, 0xdf03, 0x00c0, 0x2372, 0x8009, 0x807c, 0x96c2, 0x06c0, 0x2374, 0x8009, 0x3680, 0xa000, 0xed42, 0xc4fe, 0x3680, 0xa000 }, 16, 0x000af0c0, 1},
++	{{0x52d5, 0xc7fc, 0x98c0, 0x2f0c, 0x800a, 0xde02, 0xc2fc, 0x3480, 0xa000, 0x4415, 0x0ec6, 0x38d0, 0x8008, 0x03c7, 0x2374, 0x8009 }, 16, 0x000af0e0, 1},
++	{{0x06c7, 0x2372, 0x8009, 0x9ac0, 0x0906, 0xa001, 0x90c0, 0x2e09, 0x8266, 0x0903, 0xa003, 0x06c0, 0x2372, 0x8009, 0x03c0, 0x2374 }, 16, 0x000af100, 1},
++	{{0x8009, 0x54d1, 0xdf84, 0x4711, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x280a, 0x8266, 0x50d2, 0x0900, 0xa001, 0x4012, 0x54d4, 0xdd04 }, 16, 0x000af120, 1},
++	{{0x0902, 0xa001, 0x4214, 0x57d7, 0x9ac0, 0x3f18, 0x8004, 0x90c0, 0x3f1a, 0x8008, 0x6469, 0x8431, 0x6569, 0x90c0, 0x98c2, 0xc7fd }, 16, 0x000af140, 1},
++	{{0x01c7, 0x2372, 0x8009, 0x9ac2, 0xdf81, 0xc3f3, 0x06c7, 0x2374, 0x8009, 0x98c2, 0xdd86, 0x07c0, 0x2372, 0x8009, 0x807c, 0x96c2 }, 16, 0x000af160, 1},
++	{{0x03c0, 0x2374, 0x8009, 0x98c0, 0x0ec6, 0x38d0, 0x8008, 0xc0fd, 0x96c0, 0xc3f3, 0x2f09, 0x800a, 0x96c0, 0xc7f3, 0x2e0e, 0x825e }, 16, 0x000af180, 1},
++	{{0x54d6, 0xdc04, 0x4016, 0x0ac6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009, 0x04c7, 0x2372, 0x8009, 0x9ac0, 0x0904, 0xa002, 0x90c0 }, 16, 0x000af1a0, 1},
++	{{0x2a0e, 0x8266, 0x0901, 0xa00c, 0x04c0, 0x2372, 0x8009, 0x01c0, 0x2374, 0x8009, 0x50d6, 0xdd80, 0x4316, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000af1c0, 1},
++	{{0x90c0, 0x2a0b, 0x8266, 0x52d3, 0x0902, 0xa004, 0x4213, 0x52d1, 0xdf82, 0x0907, 0xa004, 0x4711, 0x13d7, 0x08c6, 0x38d0, 0x8008 }, 16, 0x000af1e0, 1},
++	{{0x9ac0, 0x371a, 0x8010, 0xc6fb, 0x2f0b, 0x800a, 0x98c0, 0x6569, 0xc2cf, 0x2809, 0x825e, 0x94c0, 0xc0cf, 0x8065, 0x57d1, 0xdf07 }, 16, 0x000af200, 1},
++	{{0x4611, 0x08c6, 0x38d0, 0x8008, 0x04c7, 0x2372, 0x8009, 0x03c7, 0x2374, 0x8009, 0x9ac0, 0x0904, 0xa004, 0x90c0, 0x2808, 0x8266 }, 16, 0x000af220, 1},
++	{{0x0903, 0xa030, 0x03c0, 0x2374, 0x8009, 0x04c0, 0x2372, 0x8009, 0x54d0, 0xdd04, 0x4210, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0e }, 16, 0x000af240, 1},
++	{{0x8266, 0x51d6, 0x0901, 0xa010, 0x4116, 0x51d3, 0xdc01, 0x0900, 0xa010, 0x0013, 0x31e4, 0x32a0, 0x800a, 0x98c0, 0xc4fb, 0x03c7 }, 16, 0x000af260, 1},
++	{{0x2372, 0x8009, 0x9ac0, 0xde03, 0xc0cf, 0x01c7, 0x2374, 0x8009, 0x98c0, 0xdc01, 0x04c0, 0x2372, 0x8009, 0x00c0, 0x2374, 0x8009 }, 16, 0x000af280, 1},
++	{{0x10d7, 0x0ac6, 0x38d0, 0x8008, 0x9ac0, 0x311b, 0x8020, 0xc6f7, 0x20e0, 0x9f3f, 0x9ac0, 0x2f0d, 0x800a, 0x65e9, 0x2a0a, 0x825e }, 16, 0x000af2a0, 1},
++	{{0x96c0, 0x8067, 0x27e0, 0x9f3f, 0x52d2, 0xdf02, 0x4612, 0x0bc6, 0x38d0, 0x8008, 0x06c7, 0x2374, 0x8009, 0x03c7, 0x2372, 0x8009 }, 16, 0x000af2c0, 1},
++	{{0x9ac0, 0x0903, 0xa008, 0x90c0, 0x2b08, 0x8266, 0x0906, 0xa0c0, 0x03c0, 0x2372, 0x8009, 0x06c0, 0x2374, 0x8009, 0x54d0, 0xdc04 }, 16, 0x000af2e0, 1},
++	{{0x4010, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290e, 0x8266, 0x51d6, 0x0901, 0xa040, 0x4116, 0x52d5, 0xdf82, 0x0907, 0xa040, 0x0715 }, 16, 0x000af300, 1},
++	{{0x31e4, 0x334e, 0x800a, 0x98c0, 0x02c7, 0x2372, 0x8009, 0xc0f7, 0x96c0, 0xdc02, 0x22e0, 0x9f3f, 0x04c7, 0x2374, 0x8009, 0x98c0 }, 16, 0x000af320, 1},
++	{{0xdd04, 0x00c0, 0x2372, 0x8009, 0x02c0, 0x2374, 0x8009, 0x12d7, 0x09c6, 0x38d0, 0x8008, 0x9ac0, 0x3518, 0x8040, 0xc1ef, 0x2f0e }, 16, 0x000af340, 1},
++	{{0x800a, 0x9ac0, 0x20e0, 0x9cff, 0x6469, 0x290c, 0x825e, 0x96c0, 0x8067, 0x23e0, 0x9cff, 0x57d4, 0xdc87, 0x4114, 0x0cc6, 0x38d0 }, 16, 0x000af360, 1},
++	{{0x8008, 0x07c7, 0x2374, 0x8009, 0x06c7, 0x2372, 0x8009, 0x9ac0, 0x0906, 0xa010, 0x90c0, 0x2c0d, 0x8266, 0x0907, 0xa300, 0x06c0 }, 16, 0x000af380, 1},
++	{{0x2372, 0x8009, 0x07c0, 0x2374, 0x8009, 0x51d5, 0xdc01, 0x4015, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290d, 0x8266, 0x50d5, 0x0900 }, 16, 0x000af3a0, 1},
++	{{0xa100, 0x4015, 0x51d6, 0xdd81, 0x0903, 0xa100, 0x0316, 0x31e4, 0x33fc, 0x800a, 0x98c0, 0xc0ef, 0x01c7, 0x2372, 0x8009, 0x96c0 }, 16, 0x000af3c0, 1},
++	{{0xdc01, 0x24e0, 0x9cff, 0x06c7, 0x2374, 0x8009, 0x98c0, 0xde06, 0x00c0, 0x2372, 0x8009, 0x04c0, 0x2374, 0x8009, 0x17d7, 0x0ac6 }, 16, 0x000af3e0, 1},
++	{{0x38d0, 0x8008, 0x9ac0, 0x3f18, 0x8080, 0xc7df, 0x2f0d, 0x800a, 0x9ac0, 0x20e0, 0x93ff, 0x6469, 0x2a0b, 0x825e, 0x96c0, 0x8073 }, 16, 0x000af400, 1},
++	{{0x24e0, 0x93ff, 0x13d3, 0xc581, 0x0903, 0xa020, 0x4313, 0x09c6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009, 0x9ac0, 0x0901, 0xac00 }, 16, 0x000af420, 1},
++	{{0x90c0, 0x290a, 0x8266, 0x01c0, 0x2374, 0x8009, 0x51d2, 0xdc01, 0x4012, 0x16d5, 0x0cc6, 0x38d0, 0x8008, 0xde06, 0x96c0, 0x4415 }, 16, 0x000af440, 1},
++	{{0x2c08, 0x8100, 0x16d0, 0xed66, 0x96c0, 0x3d1e, 0x8100, 0x52d5, 0x6769, 0x90c0, 0x98c1, 0x0902, 0xa020, 0x90c0, 0xc6df, 0x94c1 }, 16, 0x000af460, 1},
++	{{0x4215, 0xdf02, 0x98c6, 0x31e4, 0x34b2, 0x800a, 0x4615, 0x00c7, 0x2372, 0x8009, 0x96c0, 0xdf80, 0x22e0, 0x93ff, 0x04c7, 0x2374 }, 16, 0x000af480, 1},
++	{{0x8009, 0x98c0, 0xdd04, 0x07c0, 0x2372, 0x8009, 0x02c0, 0x2374, 0x8009, 0x11d7, 0x0cc6, 0x38d0, 0x8008, 0x9ac0, 0x26e0, 0x9fbf }, 16, 0x000af4a0, 1},
++	{{0x90c0, 0x331a, 0x8100, 0x9ac0, 0x23c0, 0x8fff, 0x6569, 0x2c0c, 0x825e, 0x96c0, 0x806d, 0x2f08, 0x800a, 0x96c0, 0x51d4, 0x20c0 }, 16, 0x000af4c0, 1},
++	{{0x8fff, 0xdf01, 0x4614, 0x09c6, 0x38d0, 0x8008, 0x06c7, 0x2372, 0x8009, 0x02c7, 0x2374, 0x8009, 0x9ac0, 0x0906, 0xa040, 0x90c0 }, 16, 0x000af4e0, 1},
++	{{0x290c, 0x8266, 0x0922, 0xb000, 0x02c0, 0x2374, 0x8009, 0x06c0, 0x2372, 0x8009, 0x56d4, 0xdd86, 0x4314, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000af500, 1},
++	{{0x90c0, 0x2a09, 0x8266, 0x51d1, 0x0901, 0xa100, 0x4111, 0x53d0, 0xdc03, 0x0900, 0xa100, 0x0010, 0x31e4, 0x356a, 0x800a, 0x9ac0 }, 16, 0x000af520, 1},
++	{{0x24e0, 0x9fbf, 0x90c0, 0x27c0, 0x8fff, 0x00c7, 0x2372, 0x8009, 0x98c0, 0xde00, 0x03c7, 0x2374, 0x8009, 0x98c0, 0xdf83, 0x04c0 }, 16, 0x000af540, 1},
++	{{0x2372, 0x8009, 0x07c0, 0x2374, 0x8009, 0x16d7, 0x0dc6, 0x38d0, 0x8008, 0x9ac0, 0x21e0, 0x9f7f, 0x90c0, 0x3d1e, 0x8200, 0x9ac0 }, 16, 0x000af560, 1},
++	{{0x2f0c, 0x800a, 0x6769, 0x2d0e, 0x825e, 0x94c0, 0x57d6, 0x8067, 0xdc87, 0x4116, 0x0ec6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009 }, 16, 0x000af580, 1},
++	{{0x06c7, 0x2372, 0x8009, 0x9ac0, 0x09c1, 0xa000, 0x90c0, 0x2e0a, 0x8266, 0x0906, 0xa080, 0x01c0, 0x2374, 0x8009, 0x06c0, 0x2372 }, 16, 0x000af5a0, 1},
++	{{0x8009, 0x56d2, 0x3d39, 0x9fff, 0x4112, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290e, 0x8266, 0x57d6, 0x0907, 0xa100, 0x4716, 0x51d4 }, 16, 0x000af5c0, 1},
++	{{0x333f, 0x9fff, 0x0907, 0xa100, 0x0714, 0x31e4, 0x3614, 0x800a, 0x22e0, 0x9f7f, 0x06c7, 0x2372, 0x8009, 0x98c0, 0xdd06, 0x07c7 }, 16, 0x000af5e0, 1},
++	{{0x2374, 0x8009, 0x3f3b, 0x9fff, 0x02c0, 0x2372, 0x8009, 0x03c0, 0x2374, 0x8009, 0x0cc6, 0x38d0, 0x8008, 0x06c7, 0x2372, 0x8009 }, 16, 0x000af600, 1},
++	{{0x96c0, 0xd806, 0x2c09, 0x825e, 0x16d1, 0x3c00, 0x2048, 0x8008, 0xdc06, 0x4011, 0x54d7, 0x9ac0, 0x24e0, 0x8fef, 0x90c0, 0x3918 }, 16, 0x000af620, 1},
++	{{0x8080, 0x6469, 0x90c0, 0x96c3, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x94c3, 0x2d0e, 0x825e, 0x92c3, 0x52d6, 0x94c3, 0x0902, 0xa020 }, 16, 0x000af640, 1},
++	{{0x92c3, 0x4216, 0x11d4, 0x0bc6, 0x38d0, 0x8008, 0x335b, 0x8000, 0x96c0, 0x65e9, 0x2b0b, 0x825e, 0x94c0, 0x50d3, 0x800b, 0xde00 }, 16, 0x000af660, 1},
++	{{0x4413, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xef42, 0x96c0, 0x52d7, 0x2f0b, 0x8002, 0x9ac0, 0x2d08, 0x825e, 0x90c0, 0x2f0c, 0x8004 }, 16, 0x000af680, 1},
++	{{0x11d0, 0xe842, 0x96c0, 0x70e2, 0x2f09, 0x8006, 0x90c0, 0x92c3, 0x4117, 0x14d3, 0x53d0, 0x31e4, 0xe842, 0x90c0, 0x94c3, 0x4313 }, 16, 0x000af6a0, 1},
++	{{0xc581, 0x14d4, 0x53d0, 0x71e4, 0x90c0, 0x92c3, 0x4410, 0x17d1, 0x0cc6, 0x38d0, 0x8008, 0x04c7, 0x2370, 0x8009, 0x2c0a, 0x8264 }, 16, 0x000af6c0, 1},
++	{{0x11d2, 0x52d2, 0x30e7, 0x3452, 0xdf84, 0x94c0, 0xdc04, 0x8089, 0x3067, 0xdb84, 0x94c0, 0xdf82, 0x8025, 0x4712, 0x10d1, 0x0ec6 }, 16, 0x000af6e0, 1},
++	{{0x38d0, 0x8008, 0x01c7, 0x2370, 0x8009, 0x96c0, 0xdc80, 0x2e0c, 0x8264, 0x54d4, 0xdc9c, 0x4114, 0x12d1, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000af700, 1},
++	{{0x00c7, 0x2370, 0x8009, 0x96c0, 0xda00, 0x2e08, 0x8264, 0x9ac0, 0xdd04, 0x56d0, 0x3de8, 0x3c10, 0xbfff, 0x9ac0, 0xdf04, 0x6561 }, 16, 0x000af720, 1},
++	{{0x3ae8, 0x3c10, 0xbfff, 0x6761, 0x7362, 0x90c0, 0x92c3, 0x56d0, 0x92c3, 0x4611, 0x5695, 0x3dfb, 0x9fff, 0x4395, 0x1092, 0x0dc6 }, 16, 0x000af740, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8264, 0x54d5, 0xd994, 0xdd98, 0x4392, 0x0cc6, 0x38d0, 0x8008, 0x2f0e, 0x8008, 0x96c0, 0x50d6 }, 16, 0x000af760, 1},
++	{{0x2c0d, 0x8266, 0x16d5, 0x53d5, 0x3360, 0x34d3, 0x07c7, 0x2374, 0x8009, 0x96c0, 0xdc07, 0xdc87, 0x8089, 0x30e0, 0xd907, 0x94c0 }, 16, 0x000af780, 1},
++	{{0xdd03, 0x8025, 0x4215, 0x10d6, 0x0dc6, 0x38d0, 0x8008, 0x04c7, 0x2374, 0x8009, 0x96c0, 0xde00, 0x2d0d, 0x8266, 0x56d5, 0xde1e }, 16, 0x000af7a0, 1},
++	{{0x4415, 0x10d6, 0x0cc6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009, 0x96c0, 0xd881, 0x2c0d, 0x8266, 0x9ac0, 0xdc01, 0x52d5, 0x3ae8 }, 16, 0x000af7c0, 1},
++	{{0x3c10, 0xbfff, 0x9ac0, 0xdd01, 0x6461, 0x38e8, 0x3c10, 0xbfff, 0x6561, 0x7160, 0x90c0, 0x92c3, 0x51d5, 0x92c3, 0x4116, 0x5192 }, 16, 0x000af7e0, 1},
++	{{0x33ec, 0x9fff, 0x4492, 0x1790, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a09, 0x8266, 0x52d1, 0xdd1f, 0x4290, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000af800, 1},
++	{{0x2f0a, 0x800a, 0x96c0, 0x54d2, 0x2e0c, 0x8268, 0x11d4, 0x3de8, 0x3c14, 0xbfff, 0x30e4, 0x32f9, 0x3fff, 0xbf00, 0x8027, 0x0112 }, 16, 0x000af820, 1},
++	{{0x3ce8, 0x3c14, 0xbfff, 0x5195, 0xdd01, 0x4295, 0x1294, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x8268, 0x57d0, 0xdb17, 0xdf1a }, 16, 0x000af840, 1},
++	{{0x4694, 0x0ec6, 0x38d0, 0x8008, 0x9ac0, 0x2f08, 0x800c, 0x90c0, 0x2f0a, 0x800e, 0x96c0, 0x50d0, 0x2e0d, 0x826a, 0x11d5, 0xed42 }, 16, 0x000af860, 1},
++	{{0x9ac0, 0x2f0c, 0x8010, 0x70e0, 0x2d0e, 0x8002, 0x3c80, 0xa100, 0x2f0f, 0x8012, 0x90c0, 0x2f0c, 0x8014, 0x3807, 0xa100, 0x4110 }, 16, 0x000af880, 1},
++	{{0x2d0b, 0x8006, 0x16d5, 0x51d2, 0x3c00, 0xa100, 0x2d08, 0x8004, 0x7361, 0x2d0d, 0x8008, 0x3c80, 0xa100, 0x2f0e, 0x8016, 0x90c0 }, 16, 0x000af8a0, 1},
++	{{0x2d0a, 0x800a, 0x3807, 0xa100, 0x4612, 0x2d09, 0x800c, 0x17d4, 0x56d6, 0x3c80, 0xa000, 0x2f08, 0x801c, 0x7367, 0x2f09, 0x801e }, 16, 0x000af8c0, 1},
++	{{0x2d0a, 0x8014, 0x98c3, 0x4614, 0x3000, 0x2000, 0x8008, 0x3607, 0xa100, 0x56d6, 0x52d7, 0x9ac7, 0x2f0e, 0x8020, 0x90c0, 0x3d1f }, 16, 0x000af8e0, 1},
++	{{0x8ffe, 0x98c7, 0x2f0c, 0x8022, 0x90c0, 0x6dc3, 0x96c3, 0x03c2, 0x2364, 0x8009, 0x96c0, 0x56d0, 0x2d08, 0x8012, 0x7362, 0x90c0 }, 16, 0x000af900, 1},
++	{{0x3483, 0xa000, 0x4617, 0x3680, 0xa100, 0x54d4, 0x51d3, 0x3800, 0xa100, 0x70e4, 0x2f0f, 0x8024, 0x33ca, 0x3810, 0xbfff, 0x3483 }, 16, 0x000af920, 1},
++	{{0xa000, 0x4114, 0x3680, 0xa100, 0x53d6, 0x51d5, 0x3800, 0xa100, 0x70e3, 0x2f0c, 0x801a, 0x90c0, 0x3a83, 0xa000, 0x4116, 0x3400 }, 16, 0x000af940, 1},
++	{{0x2000, 0x8008, 0x3887, 0xa100, 0x57d5, 0x2f0d, 0x8018, 0x3a07, 0xa100, 0x90c0, 0x56d5, 0x3f19, 0x8ffe, 0x3807, 0xa100, 0x6dc4 }, 16, 0x000af960, 1},
++	{{0x2f0e, 0x8026, 0x96c3, 0x03c2, 0x236c, 0x8009, 0x3880, 0xa100, 0x50d2, 0x2d0a, 0x800e, 0x7066, 0x90c0, 0x3483, 0xa000, 0x4015 }, 16, 0x000af980, 1},
++	{{0x3680, 0xa100, 0x54d4, 0x52d1, 0x3800, 0xa100, 0x7164, 0x2d09, 0x8016, 0x90c0, 0x3483, 0xa000, 0x4214, 0x3680, 0xa100, 0x54d0 }, 16, 0x000af9a0, 1},
++	{{0x52d2, 0x7164, 0x90c0, 0x3a83, 0xa000, 0x4210, 0x3100, 0x2000, 0x8008, 0x3887, 0xa100, 0x54d2, 0x2d08, 0x8010, 0x96c7, 0x56d1 }, 16, 0x000af9c0, 1},
++	{{0x391a, 0x8ffe, 0x94c7, 0xed58, 0x6dd8, 0x96c3, 0x03c2, 0x2368, 0x8009, 0x3480, 0xa000, 0x54d0, 0x7266, 0x90c0, 0x98c7, 0x39c8 }, 16, 0x000af9e0, 1},
++	{{0x3810, 0xbfff, 0x4411, 0x13d0, 0x56d6, 0x71e6, 0x90c0, 0x92c3, 0x4316, 0x14d4, 0x53d2, 0x71e4, 0x90c0, 0x98c3, 0x4314, 0x3400 }, 16, 0x000afa00, 1},
++	{{0x2000, 0x8008, 0x3607, 0xa100, 0x53d2, 0x50d7, 0x94c3, 0x371f, 0x8ffe, 0x98c7, 0x3cc8, 0x3810, 0xbfff, 0x6d57, 0x96c3, 0x02c2 }, 16, 0x000afa20, 1},
++	{{0x2360, 0x8009, 0x3480, 0xa000, 0x51d1, 0x70e0, 0x90c0, 0x3483, 0xa000, 0x4117, 0x3680, 0xa000, 0x53d6, 0x54d5, 0x7263, 0x90c0 }, 16, 0x000afa40, 1},
++	{{0x3483, 0xa000, 0x4416, 0x3680, 0xa000, 0x5193, 0x53d7, 0x33fc, 0x9fff, 0x71e4, 0x800d, 0x5094, 0x31ef, 0x9fff, 0xdd9f, 0x4391 }, 16, 0x000afa60, 1},
++	{{0x26e9, 0x15d3, 0x3ec8, 0x380c, 0xbfff, 0x94c0, 0x53d7, 0x801b, 0x9ac0, 0xde83, 0x5796, 0x3cc8, 0x380c, 0xbfff, 0x3feb, 0x9fff }, 16, 0x000afa80, 1},
++	{{0xde9b, 0x4594, 0x3a80, 0xb900, 0x77d3, 0x7752, 0xcf41, 0xce40, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000afaa0, 1},
++	{{0x24e8, 0x75d0, 0x96c7, 0x7453, 0x64e4, 0x8017, 0x32e4, 0x3ac0, 0x800a, 0x74f1, 0x31e4, 0x3afe, 0x800a, 0x64e9, 0x8021, 0x65e9 }, 16, 0x000afac0, 1},
++	{{0x801d, 0x98c0, 0xd4af, 0x36ca, 0x83c1, 0x78e1, 0x94c6, 0x8013, 0x6c10, 0x3472, 0x30e4, 0x3afe, 0x800a, 0xd419, 0x7453, 0x94c0 }, 16, 0x000afae0, 1},
++	{{0x7470, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6c90, 0x5310, 0x280c, 0x800a, 0x9ac0, 0x65e9, 0x7def }, 16, 0x000afb00, 1},
++	{{0xe84c, 0x2401, 0x8080, 0x94c6, 0xeae8, 0x6e10, 0x2ea4, 0x120a, 0xe94c, 0x96c0, 0x7d6f, 0x5051, 0x9345, 0x96c0, 0x7163, 0x2b03 }, 16, 0x000afb20, 1},
++	{{0x8016, 0x92c2, 0x6ec4, 0x3175, 0x9f80, 0x94c0, 0x4549, 0x90c0, 0x2d24, 0x100a, 0x550c, 0x3c6f, 0x4508, 0x3063, 0x5551, 0x92d2 }, 16, 0x000afb40, 1},
++	{{0x6d44, 0x3b72, 0x9f80, 0x4249, 0x94c0, 0x5114, 0x9f70, 0x4110, 0x2c10, 0x1219, 0xe842, 0x3d6f, 0x1519, 0x5350, 0x9ac0, 0x7eef }, 16, 0x000afb60, 1},
++	{{0x7dc2, 0x5111, 0x24e1, 0x9f80, 0x3e20, 0xa000, 0x7165, 0x75db, 0x7cef, 0xe842, 0x2521, 0x9000, 0x3a06, 0xa002, 0x90c0, 0x5050 }, 16, 0x000afb80, 1},
++	{{0x6e90, 0x6d53, 0x3a46, 0xa004, 0x6d0d, 0x27c1, 0x9000, 0x7161, 0x3600, 0xa804, 0x35ea, 0x9fff, 0x3a06, 0xa008, 0x90c0, 0x7d67 }, 16, 0x000afba0, 1},
++	{{0x2401, 0x8080, 0x3400, 0xa040, 0x6ec8, 0x3bed, 0x9fff, 0x3175, 0x9f00, 0x3400, 0xa040, 0x60e6, 0x33e9, 0x9fff, 0x64ea, 0x3400 }, 16, 0x000afbc0, 1},
++	{{0xa800, 0xd2d5, 0x3400, 0xa040, 0x6dbb, 0x37eb, 0x9fff, 0x65e8, 0x3600, 0xa800, 0xd2df, 0x9f70, 0x4550, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000afbe0, 1},
++	{{0x96c0, 0x5211, 0x290c, 0x8002, 0x3d6f, 0x1514, 0xe842, 0x9ac0, 0x3ac9, 0x904f, 0x5350, 0x280d, 0x8002, 0x9ac0, 0x24e1, 0x9f40 }, 16, 0x000afc00, 1},
++	{{0x7161, 0x2021, 0x9c00, 0x5255, 0x96c6, 0x6c32, 0x2401, 0x80c0, 0x9ac0, 0x3774, 0x9f80, 0x90c0, 0x31e8, 0x9fff, 0x6d80, 0x37eb }, 16, 0x000afc20, 1},
++	{{0x9fff, 0x65ea, 0x94c0, 0xd250, 0x8015, 0x6dc0, 0x37eb, 0x9fff, 0x65e8, 0xd258, 0x92c3, 0x6664, 0x96c0, 0x5211, 0x2c0d, 0x8002 }, 16, 0x000afc40, 1},
++	{{0x0515, 0x4214, 0x9f70, 0x4450, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x5250, 0x280b, 0x8004, 0x96c0, 0x6c5c, 0xeceb, 0xe942 }, 16, 0x000afc60, 1},
++	{{0xec62, 0x1314, 0x4254, 0x4313, 0x1159, 0x5553, 0x21e2, 0x5251, 0x613d, 0x35ea, 0x9fff, 0x94c0, 0x6111, 0x9f70, 0xd81a, 0x90c0 }, 16, 0x000afc80, 1},
++	{{0x3e00, 0xa004, 0x2601, 0x8001, 0xd911, 0x6c90, 0x7656, 0xcc57, 0x3880, 0xa100, 0x6f2a, 0xce48, 0xcf4b, 0x96c0, 0xfbc3, 0x0cf6 }, 16, 0x000afca0, 1},
++	{{0xbfff, 0x96c0, 0xc7a0, 0x2718, 0x814c, 0x98c0, 0x6c10, 0xeb54, 0x2f00, 0x8062, 0x96c0, 0x4713, 0x2900, 0x8064, 0x96c0, 0xeb50 }, 16, 0x000afcc0, 1},
++	{{0x2a00, 0x8054, 0x96c0, 0x4013, 0x2b0d, 0x8042, 0x3680, 0xa000, 0xe9ed, 0x4015, 0x3600, 0xa100, 0xeced, 0xe962, 0x3680, 0xa000 }, 16, 0x000afce0, 1},
++	{{0x4011, 0xebed, 0x94c0, 0xec64, 0xeb3f, 0x3600, 0xa100, 0x4014, 0xe9ed, 0x96c0, 0x4013, 0x2800, 0x8056, 0x3600, 0xa100, 0xeced }, 16, 0x000afd00, 1},
++	{{0xe939, 0x96c0, 0xec3a, 0x2e00, 0x8058, 0x3680, 0xa000, 0x4011, 0xe9ed, 0x96c0, 0x4014, 0x2a00, 0x805a, 0x94c0, 0xe938, 0xebed }, 16, 0x000afd20, 1},
++	{{0x96c0, 0x4011, 0x2900, 0x805c, 0x94c0, 0xeb3e, 0xefed, 0x96c0, 0x4013, 0x2e00, 0x805e, 0x94c0, 0xef3a, 0xe8ed, 0x96c0, 0x4017 }, 16, 0x000afd40, 1},
++	{{0x2f00, 0x8044, 0x94c0, 0xe839, 0xebed, 0x96c0, 0x4010, 0x2900, 0x8046, 0x94c0, 0xeb3e, 0xeced, 0x96c0, 0x4013, 0x2b00, 0x8048 }, 16, 0x000afd60, 1},
++	{{0x94c0, 0xec3f, 0xeaed, 0x96c0, 0x4014, 0x2f00, 0x804a, 0x94c0, 0xea39, 0xeeed, 0x96c0, 0x4012, 0x2a00, 0x804c, 0x94c0, 0xee3b }, 16, 0x000afd80, 1},
++	{{0xeced, 0x96c0, 0x4016, 0x2800, 0x804e, 0x94c0, 0xec3f, 0xe9ed, 0x96c0, 0x4014, 0x2f00, 0x8050, 0x94c0, 0xe93a, 0xebed, 0x0011 }, 16, 0x000afda0, 1},
++	{{0xcabc, 0x94c0, 0xeb38, 0xeced, 0x0013, 0xcebe, 0x94c0, 0xec3f, 0xe9ed, 0x96c0, 0x4014, 0x2c00, 0x8040, 0x94c0, 0xe93a, 0xe8ed }, 16, 0x000afdc0, 1},
++	{{0x0011, 0xc9b6, 0x94c0, 0xebed, 0xe83e, 0x0010, 0xceb8, 0x94c0, 0xeaed, 0xeb3c, 0x0013, 0xccba, 0x94c0, 0xefed, 0xea39, 0x0012 }, 16, 0x000afde0, 1},
++	{{0xef3e, 0x0017, 0xed3c, 0x0015, 0x3104, 0x2078, 0x800b, 0x9ac0, 0xd910, 0x6c10, 0xfbc3, 0x2461, 0x9fff, 0x9ac0, 0x2561, 0x9fff }, 16, 0x000afe00, 1},
++	{{0x90c0, 0x2900, 0x804e, 0x2b0e, 0x8062, 0x1356, 0xecee, 0x9ac0, 0x6dbd, 0xec39, 0x38c0, 0x28d0, 0x8009, 0x96c0, 0xdb1b, 0xde03 }, 16, 0x000afe20, 1},
++	{{0x5254, 0x96c0, 0xdb16, 0x39ec, 0x9fff, 0x3f6f, 0x6e95, 0x0cf6, 0xbfff, 0xd2d3, 0x3bed, 0x9fff, 0x6fa1, 0x3fef, 0x9fff, 0x27ea }, 16, 0x000afe40, 1},
++	{{0xc79e, 0x8023, 0x70e7, 0x801f, 0x78c1, 0xc941, 0x90c0, 0xe9fc, 0xe918, 0x5351, 0x7dc3, 0x75db, 0x603d, 0x6c21, 0x31e8, 0x9fff }, 16, 0x000afe60, 1},
++	{{0x646a, 0x85e3, 0x9ec0, 0x6767, 0x7cc1, 0x6c10, 0x33c1, 0x2692, 0x8009, 0xc8be, 0x98c0, 0x2700, 0x8040, 0xda1e, 0xcd41, 0x9cc0 }, 16, 0x000afe80, 1},
++	{{0x6997, 0xd897, 0x39c0, 0x296e, 0x8009, 0xeaee, 0x98c0, 0xcf43, 0x30c2, 0x298e, 0x8009, 0x98c0, 0x31c2, 0x29ce, 0x8009, 0xea38 }, 16, 0x000afea0, 1},
++	{{0x98c0, 0xed1f, 0x33c2, 0x29ee, 0x8009, 0x1655, 0x32c2, 0x29ae, 0x8009, 0x3c20, 0xa000, 0x7656, 0x75d6, 0x5552, 0x2402, 0x804c }, 16, 0x000afec0, 1},
++	{{0x9ac0, 0x7e62, 0x2541, 0x8800, 0x7de2, 0xe8ee, 0x3c20, 0xa000, 0xda1c, 0xd99b, 0xe83c, 0x2602, 0x8040, 0x90c0, 0x3e00, 0xa100 }, 16, 0x000afee0, 1},
++	{{0x7e41, 0x2e0d, 0x8004, 0x7dc1, 0x2701, 0x81ff, 0x94c0, 0xc754, 0xcf43, 0x3aa0, 0xa000, 0x5655, 0x3dc0, 0x23d0, 0x8009, 0x3640 }, 16, 0x000aff00, 1},
++	{{0xa100, 0xe91f, 0xef18, 0x3620, 0xa100, 0x5f11, 0x5917, 0x90c0, 0x3660, 0xa000, 0xef1a, 0xccba, 0x3600, 0xa100, 0xe9fc, 0xeffc }, 16, 0x000aff20, 1},
++	{{0x3660, 0xa100, 0xe919, 0xef1b, 0x3600, 0xa100, 0x5451, 0x5357, 0x3ce0, 0xa800, 0x3b74, 0x9f00, 0x7dc3, 0x5117, 0xeaed, 0x3ee0 }, 16, 0x000aff40, 1},
++	{{0xa102, 0x39ec, 0x9fff, 0x75db, 0x64e9, 0xea3e, 0xe8ed, 0x3c20, 0xa000, 0x6c7c, 0x2f00, 0x8060, 0x7453, 0x5156, 0x38e0, 0xa000 }, 16, 0x000aff60, 1},
++	{{0x6464, 0xe9ed, 0xe83c, 0x96c0, 0xd053, 0x7275, 0xe93f, 0x2132, 0xd255, 0x3e66, 0x0452, 0x4250, 0x1050, 0x1450, 0xdf84, 0x3600 }, 16, 0x000aff80, 1},
++	{{0xa800, 0x6ec2, 0x6d47, 0x3600, 0xa100, 0xda9a, 0x4552, 0x7ec1, 0xca45, 0x90c0, 0xea1d, 0x5052, 0x6467, 0x31e8, 0x9fff, 0x7c42 }, 16, 0x000affa0, 1},
++	{{0x3c00, 0xa040, 0x6e44, 0x7458, 0x32e4, 0x3b10, 0x800a, 0x3600, 0xa100, 0x4054, 0x4450, 0x32e4, 0x3b70, 0x800a, 0x3620, 0xa000 }, 16, 0x000affc0, 1},
++	{{0xe9ea, 0xe8eb, 0x32e4, 0x3c00, 0x800a, 0x3620, 0xa000, 0xe9ea, 0xe8eb, 0x9ac0, 0x2be2, 0x9ffe, 0x6c90, 0x2b0f, 0x8022, 0x9ac0 }, 16, 0x000affe0, 1},
++	{{0x33e9, 0x9fff, 0x9342, 0x2b0c, 0x8012, 0x96c0, 0x527f, 0x2b08, 0x8020, 0x98c0, 0x6e5c, 0x537c, 0x2b03, 0x801e, 0x98c0, 0x608c }, 16, 0x000b0000, 1},
++	{{0x5278, 0x2b0d, 0x8010, 0x98c0, 0x6edc, 0x33e9, 0x9fff, 0x577d, 0x209b, 0x137f, 0x507c, 0x9ad0, 0x61e1, 0x33e9, 0x9fff, 0x5278 }, 16, 0x000b0020, 1},
++	{{0x577d, 0x2093, 0x6edc, 0x33e9, 0x9fff, 0x3820, 0xa000, 0x609b, 0xe9eb, 0xe8e8, 0x32e4, 0x3c70, 0x800a, 0x3480, 0xa000, 0x4155 }, 16, 0x000b0040, 1},
++	{{0x3a80, 0xa100, 0x76d0, 0xd81e, 0x5155, 0xed62, 0xdb95, 0x3600, 0xa100, 0x6ec7, 0x4755, 0x4556, 0x3880, 0xa800, 0x7754, 0xcc5f }, 16, 0x000b0060, 1},
++	{{0xcf43, 0x3680, 0xa000, 0xce40, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0xdb11, 0xcc56, 0x2501, 0x8001, 0x98c0, 0x6d1a, 0xda1d }, 16, 0x000b0080, 1},
++	{{0xcd57, 0xc788, 0x96c0, 0xc8b8, 0x0cf2, 0xbfff, 0x2618, 0x810a, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x6c10, 0xfec5, 0xccba, 0x94c0 }, 16, 0x000b00a0, 1},
++	{{0xcaaa, 0xcbac, 0x3820, 0xa000, 0xc9ae, 0x2e0f, 0x8046, 0x96c0, 0x4717, 0x2f0e, 0x8022, 0x3640, 0xa000, 0x4016, 0xcaa0, 0xee46 }, 16, 0x000b00c0, 1},
++	{{0x3680, 0xa000, 0xecee, 0x4016, 0x3600, 0xa100, 0xedee, 0xec62, 0x3680, 0xa000, 0x4014, 0xefee, 0x94c0, 0xed64, 0xef38, 0x3600 }, 16, 0x000b00e0, 1},
++	{{0xa100, 0x4015, 0xedee, 0x0017, 0xe8ee, 0x3680, 0xa000, 0xed3c, 0xe83a, 0x3680, 0xa000, 0x4015, 0xefee, 0x0010, 0xef3b, 0x94c0 }, 16, 0x000b0100, 1},
++	{{0xc8b0, 0xecee, 0x0017, 0xcdb2, 0x3640, 0xa000, 0xeaee, 0xec39, 0x0014, 0xcbb4, 0x94c0, 0xea38, 0xefee, 0x0012, 0xef3d, 0x0017 }, 16, 0x000b0120, 1},
++	{{0xecee, 0x94c0, 0xec3b, 0xeaee, 0x0014, 0xebee, 0x94c0, 0xea7a, 0xeb7c, 0x0012, 0xecee, 0x0013, 0xc8a2, 0x3600, 0xa100, 0xec7e }, 16, 0x000b0140, 1},
++	{{0xebee, 0x0014, 0xcda4, 0x3640, 0xa100, 0xefee, 0xeb3a, 0x3600, 0xa100, 0xcca6, 0x4013, 0x94c0, 0xef38, 0xebee, 0x0017, 0xeb3d }, 16, 0x000b0160, 1},
++	{{0x0013, 0xeaee, 0x94c0, 0xea3c, 0xe8ee, 0x0012, 0xedee, 0x94c0, 0xe874, 0xebee, 0x0010, 0xed76, 0x0015, 0xeaee, 0x94c0, 0xeb78 }, 16, 0x000b0180, 1},
++	{{0xefee, 0x0013, 0xea6e, 0x0012, 0xef70, 0x0017, 0xee72, 0x0016, 0x3104, 0x2408, 0x800b, 0x98c0, 0xda90, 0x6c10, 0xfbc5, 0xcda4 }, 16, 0x000b01a0, 1},
++	{{0x9ac0, 0x2161, 0x9fff, 0x90c0, 0x2201, 0x91a0, 0x3c40, 0xa000, 0x2b0e, 0x806a, 0x90c0, 0x2161, 0x9fff, 0x1756, 0xecee, 0x3c20 }, 16, 0x000b01c0, 1},
++	{{0xa004, 0x6dbb, 0xec3d, 0x34c1, 0x29fe, 0x8009, 0x3a40, 0xb800, 0xdb9b, 0xdc83, 0x5354, 0xc286, 0x3e20, 0xa006, 0xda97, 0x33e9 }, 16, 0x000b01e0, 1},
++	{{0x9fff, 0x603d, 0xcda2, 0xe8ee, 0x3e40, 0xb20d, 0x7eef, 0x6364, 0x31e8, 0x9fff, 0xedee, 0xcab6, 0x3a20, 0xa001, 0x0cf5, 0xbfff }, 16, 0x000b0200, 1},
++	{{0x66e7, 0xed62, 0x3e00, 0xb80c, 0xd353, 0xdb9d, 0x30c2, 0x2a1a, 0x8009, 0x5655, 0x3e40, 0xb8cc, 0x6d82, 0x6a0b, 0x34c2, 0x2a12 }, 16, 0x000b0220, 1},
++	{{0x8009, 0x5656, 0x3ac0, 0xa804, 0x37eb, 0x9fff, 0xca44, 0xe83d, 0x3a00, 0xa004, 0x65e8, 0x35c2, 0x2a0a, 0x8009, 0x31c2, 0x2a22 }, 16, 0x000b0240, 1},
++	{{0x8009, 0x98c6, 0x2541, 0x9800, 0x90c0, 0xc482, 0x3c00, 0xa100, 0x2101, 0x81ff, 0x7e41, 0x2e0f, 0x8004, 0x3640, 0xa000, 0xc654 }, 16, 0x000b0260, 1},
++	{{0xe9ef, 0x3660, 0xa100, 0xe93a, 0x5757, 0x36c0, 0xa000, 0xee1a, 0xefef, 0x3a80, 0xa000, 0x5716, 0x3ac0, 0x23d0, 0x8009, 0x3640 }, 16, 0x000b0280, 1},
++	{{0xa100, 0xc657, 0xebef, 0x3680, 0xa000, 0xeb72, 0xef78, 0x3480, 0xa000, 0xeefc, 0x36e0, 0xa100, 0xe81e, 0xec1e, 0x36e0, 0xa100 }, 16, 0x000b02a0, 1},
++	{{0x5810, 0xee1d, 0x36c0, 0xa100, 0x5414, 0x5c16, 0x3600, 0xa100, 0x6669, 0xe8fc, 0x36a0, 0xa100, 0xe819, 0xecfc, 0x3a00, 0xa100 }, 16, 0x000b02c0, 1},
++	{{0x31c2, 0x2a28, 0x8009, 0x5250, 0x7d43, 0x3640, 0xa100, 0x755a, 0xec19, 0x3480, 0xa000, 0x5454, 0x96c0, 0x3d74, 0x9f00, 0x7752 }, 16, 0x000b02e0, 1},
++	{{0x96c0, 0x39ec, 0x9fff, 0x6764, 0x2c7c, 0xd352, 0x3275, 0x612e, 0x0250, 0xd255, 0x3e66, 0x0455, 0x5250, 0x3800, 0xb000, 0xdc84 }, 16, 0x000b0300, 1},
++	{{0x6ecb, 0x5050, 0x0557, 0xdb19, 0x7f41, 0xc256, 0x90c0, 0x3480, 0xa000, 0xea1a, 0x3480, 0xa000, 0x5152, 0x64e7, 0x33e9, 0x9fff }, 16, 0x000b0320, 1},
++	{{0x7cc2, 0x3c00, 0xa800, 0x6f42, 0x74d9, 0x32e4, 0x3b10, 0x800a, 0x3680, 0xa000, 0x4653, 0x4154, 0x3640, 0xa100, 0xccbc, 0xe9ef }, 16, 0x000b0340, 1},
++	{{0xe9ef, 0x3a80, 0xa000, 0xe93c, 0x32e4, 0x3b70, 0x800a, 0x3420, 0xa000, 0xe8e9, 0x32e4, 0x3c00, 0x800a, 0x3640, 0xa000, 0xe9ef }, 16, 0x000b0360, 1},
++	{{0xe8e9, 0x9ac0, 0x2be2, 0x9ffe, 0x6d10, 0x2b09, 0x8054, 0x9ac0, 0x35ea, 0x9fff, 0x9342, 0x2b0c, 0x8044, 0x96c0, 0x5679, 0x2b0f }, 16, 0x000b0380, 1},
++	{{0x8052, 0x98c0, 0x6dde, 0x557c, 0x2b03, 0x801e, 0x98c0, 0x610d, 0x567f, 0x2b08, 0x8042, 0x98c0, 0x6e5e, 0x35ea, 0x9fff, 0x5678 }, 16, 0x000b03a0, 1},
++	{{0x2116, 0x1179, 0x557c, 0x9ad0, 0x6260, 0x35ea, 0x9fff, 0x537f, 0x5678, 0x2115, 0x6261, 0x35ea, 0x9fff, 0x3860, 0xa000, 0x6116 }, 16, 0x000b03c0, 1},
++	{{0xe9e9, 0xe8eb, 0x32e4, 0x3c70, 0x800a, 0x3480, 0xa000, 0x4257, 0x3a80, 0xa100, 0x75d0, 0x7457, 0x5157, 0xef62, 0xd913, 0x3600 }, 16, 0x000b03e0, 1},
++	{{0xa100, 0x6fd8, 0x4257, 0x4756, 0x94c0, 0x9e21, 0x9f21, 0x9f70, 0x94c0, 0xcd5f, 0xcc5e, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b0400, 1},
++	{{0x98c0, 0x7650, 0x6c10, 0xe748, 0xcc56, 0x9ac0, 0x02fc, 0x9fee, 0x90c0, 0x2601, 0x8001, 0x3880, 0xa000, 0x6eaa, 0xcd57, 0xcf4b }, 16, 0x000b0420, 1},
++	{{0x3880, 0xa000, 0xce49, 0x0cf5, 0xbfff, 0x96c0, 0xf9c6, 0x2718, 0x817e, 0x96c0, 0xc7a0, 0x2102, 0x8054, 0x90c0, 0x96c0, 0xe954 }, 16, 0x000b0440, 1},
++	{{0x2c00, 0x8062, 0x96c0, 0x4711, 0x2f00, 0x8064, 0x96c0, 0xe950, 0x2002, 0x8048, 0x96c0, 0x4011, 0x290d, 0x8042, 0x0015, 0xe9ed }, 16, 0x000b0460, 1},
++	{{0x94c0, 0xeeed, 0xe962, 0x0011, 0xe8ed, 0x94c0, 0xee64, 0xe83c, 0x0016, 0xebed, 0x96c0, 0x4010, 0x2202, 0x8056, 0x3680, 0xa000 }, 16, 0x000b0480, 1},
++	{{0xebed, 0xeb3f, 0x3640, 0xa100, 0x4013, 0xeb39, 0x3600, 0xa100, 0xe8ed, 0x4013, 0x3820, 0xa000, 0xe83a, 0x2c00, 0x805a, 0x3640 }, 16, 0x000b04a0, 1},
++	{{0xa000, 0x4010, 0xcbb8, 0x96c0, 0xe8ed, 0x2b00, 0x805e, 0x3680, 0xa000, 0xeced, 0xe83c, 0x38a0, 0xa000, 0xec3b, 0x2e00, 0x805c }, 16, 0x000b04c0, 1},
++	{{0x96c0, 0xeced, 0x2f00, 0x8046, 0x3680, 0xa000, 0xebed, 0xec3b, 0x9ac0, 0x2602, 0x804c, 0x90c0, 0x2900, 0x8044, 0x3680, 0xa000 }, 16, 0x000b04e0, 1},
++	{{0xeb3e, 0xebed, 0x9ac0, 0x2702, 0x804e, 0x90c0, 0x2102, 0x804a, 0x94c0, 0xeb3f, 0xeeed, 0x94c0, 0xefed, 0xee39, 0x3620, 0xa000 }, 16, 0x000b0500, 1},
++	{{0xef39, 0xe9ed, 0x3660, 0xa000, 0xcab6, 0xe938, 0x3680, 0xa000, 0xe9ed, 0x4010, 0x38a0, 0xa000, 0xe93f, 0x2a00, 0x8058, 0x3600 }, 16, 0x000b0520, 1},
++	{{0xa100, 0xe8ed, 0xe8ed, 0x3880, 0xa000, 0xeded, 0x2702, 0x8050, 0x36c0, 0xa000, 0x4014, 0xccbe, 0x36e0, 0xa000, 0xe83e, 0xe83a }, 16, 0x000b0540, 1},
++	{{0x3680, 0xa100, 0xed3a, 0xeeed, 0x3680, 0xa000, 0xeaed, 0xcaba, 0x36e0, 0xa100, 0xea3c, 0xee3f, 0x3880, 0xa000, 0x4015, 0x2502 }, 16, 0x000b0560, 1},
++	{{0x8040, 0x36c0, 0xa000, 0x4013, 0xcbbc, 0x3680, 0xa100, 0xefed, 0xeced, 0x36e0, 0xa100, 0xef3b, 0xec3d, 0x0014, 0xed3a, 0x0016 }, 16, 0x000b0580, 1},
++	{{0x4013, 0x0011, 0x4017, 0x3680, 0xa100, 0x4010, 0x4011, 0x3680, 0xa100, 0x4016, 0x4017, 0x3680, 0xa100, 0x4012, 0x4014, 0x3004 }, 16, 0x000b05a0, 1},
++	{{0x292a, 0x800b, 0x0010, 0x4015, 0x3c20, 0xa000, 0x38cf, 0x9382, 0x6d90, 0xcd41, 0xcd83, 0x9ac0, 0x7fc1, 0xfbc6, 0x3ec0, 0x292e }, 16, 0x000b05c0, 1},
++	{{0x8009, 0x3a20, 0xa000, 0xed8d, 0x3cc0, 0x290e, 0x8009, 0x96c0, 0xedfe, 0x2b0a, 0x8014, 0x96c0, 0x5152, 0x2518, 0x8108, 0x2f90 }, 16, 0x000b05e0, 1},
++	{{0x3544, 0x2e90, 0x35c2, 0x23c0, 0x8009, 0x3d41, 0x3ec0, 0x2712, 0x8009, 0x3a20, 0xa000, 0xed1d, 0x3cc0, 0x2792, 0x8009, 0x1d95 }, 16, 0x000b0600, 1},
++	{{0x35c2, 0x2892, 0x8009, 0x38ce, 0x9382, 0x94c0, 0x7f41, 0x9d61, 0xcd44, 0x90c0, 0xedfc, 0xee1d, 0xed1c, 0x1c16, 0x5215, 0x6569 }, 16, 0x000b0620, 1},
++	{{0xecfc, 0x3420, 0xa000, 0xec1d, 0x5554, 0x7ec3, 0x76dd, 0x98c0, 0x6f1b, 0x6f90, 0x2618, 0x80ea, 0x2d5b, 0x06fe, 0x9ff8, 0x3004 }, 16, 0x000b0640, 1},
++	{{0x2738, 0x800b, 0x02fe, 0x9ff8, 0x9cc0, 0x6f90, 0x6d90, 0xcd42, 0x3ec0, 0x2852, 0x8009, 0x3cc0, 0x2812, 0x8009, 0x98c0, 0x35c2 }, 16, 0x000b0660, 1},
++	{{0x294e, 0x8009, 0xee1d, 0x90c0, 0xed1c, 0x1c16, 0x5215, 0x6569, 0xecfc, 0x3420, 0xa000, 0xec1d, 0x5554, 0x7ec3, 0x76dd, 0x96c0 }, 16, 0x000b0680, 1},
++	{{0x6f9b, 0x6c4d, 0x849a, 0x07fe, 0x9ff8, 0x3004, 0x2738, 0x800b, 0x00fe, 0x9ff8, 0x98c0, 0xcd46, 0x3ec0, 0x292e, 0x8009, 0x3cc0 }, 16, 0x000b06a0, 1},
++	{{0x290e, 0x8009, 0x98c0, 0x35c2, 0x29de, 0x8009, 0xee1d, 0x90c0, 0xed1c, 0x1c16, 0x5215, 0x6569, 0xecfc, 0x3420, 0xa000, 0xec1d }, 16, 0x000b06c0, 1},
++	{{0x5054, 0x7c43, 0x7458, 0x96c0, 0x6d81, 0x6e90, 0x8452, 0x2c41, 0x03fe, 0x9ff8, 0x3004, 0x2738, 0x800b, 0x00fe, 0x9ff8, 0x98c0 }, 16, 0x000b06e0, 1},
++	{{0xcd47, 0x35c2, 0x29de, 0x8009, 0x90c0, 0xee1d, 0xed1c, 0x1c16, 0x5215, 0x6569, 0xecfc, 0x3420, 0xa000, 0xec1d, 0x5554, 0x7ec3 }, 16, 0x000b0700, 1},
++	{{0x76dd, 0x6d2d, 0x98c6, 0x02fe, 0x9ff8, 0x90c0, 0x6d10, 0x92c2, 0x6fc9, 0x94c2, 0x07fe, 0x9ff8, 0x3e40, 0xa000, 0x7e62, 0x6c10 }, 16, 0x000b0720, 1},
++	{{0x3dc0, 0x296e, 0x8009, 0xc9ba, 0x3e41, 0x3ec0, 0x29ae, 0x8009, 0x98c0, 0xcc44, 0x39c0, 0x298e, 0x8009, 0x3c80, 0xa000, 0x2a0d }, 16, 0x000b0740, 1},
++	{{0x804e, 0x90c0, 0x05fc, 0x9ff8, 0x3800, 0xa100, 0x6225, 0x5255, 0xed1c, 0x3800, 0xa004, 0x6f48, 0xee1c, 0x5d15, 0x96c0, 0xec19 }, 16, 0x000b0760, 1},
++	{{0x2621, 0x9fff, 0x3c00, 0xa800, 0x6d3e, 0x5914, 0x30c2, 0x29ce, 0x8009, 0x98c0, 0x36c2, 0x29ee, 0x8009, 0xedfc, 0x3c20, 0xa000 }, 16, 0x000b0780, 1},
++	{{0x35ea, 0x9fff, 0xe8ed, 0x2f00, 0x804c, 0x3840, 0xa000, 0x656a, 0xed1e, 0xe9fc, 0x3800, 0xa004, 0xd356, 0xe83f, 0x5255, 0x3a40 }, 16, 0x000b07a0, 1},
++	{{0xa000, 0x7d43, 0xe918, 0x27c1, 0x8000, 0x3c00, 0xa402, 0x755a, 0x280c, 0x800e, 0x6c3f, 0x5451, 0x3a00, 0xa804, 0x31e8, 0x9fff }, 16, 0x000b07c0, 1},
++	{{0x5354, 0x5516, 0x3e20, 0xa004, 0x6468, 0x3774, 0x9f00, 0x75d2, 0x2441, 0x8800, 0x3e00, 0xa108, 0x65e4, 0xd35f, 0x66e9, 0x39ec }, 16, 0x000b07e0, 1},
++	{{0x9fff, 0x5655, 0x9cc0, 0x6c7c, 0x2001, 0x81ff, 0xd1d2, 0x2201, 0x8040, 0x3c00, 0xa800, 0x7274, 0x60b9, 0x3fc0, 0x23d0, 0x8009 }, 16, 0x000b0800, 1},
++	{{0x3a20, 0xa800, 0xd254, 0x4150, 0x2d0d, 0x8004, 0x98c0, 0x7e66, 0x4454, 0x2602, 0x8060, 0x98c0, 0x2702, 0x8040, 0xdc04, 0x5755 }, 16, 0x000b0820, 1},
++	{{0x3880, 0xa000, 0x6d52, 0x5350, 0xe8ed, 0x98c0, 0xd81a, 0x6dcf, 0xeeed, 0x5250, 0x3820, 0xa000, 0x7c41, 0xe9ed, 0xee3f, 0x3640 }, 16, 0x000b0840, 1},
++	{{0xa100, 0xcc40, 0xe839, 0x3620, 0xa000, 0xe93e, 0x4356, 0xec1f, 0x5154, 0x64e7, 0x33e9, 0x9fff, 0x7cc2, 0x2fca, 0x34d9, 0x32e4 }, 16, 0x000b0860, 1},
++	{{0x3b10, 0x800a, 0x3600, 0xa100, 0x4152, 0x4750, 0x32e4, 0x3b70, 0x800a, 0x94c0, 0xe9ee, 0xe8eb, 0x98c0, 0xcd4e, 0x32e4, 0x3c00 }, 16, 0x000b0880, 1},
++	{{0x800a, 0x94c0, 0xe9ee, 0xe8eb, 0x9ac0, 0x2be2, 0x9ffe, 0x6f90, 0x2b0f, 0x8022, 0x9ac0, 0x3fef, 0x9fff, 0x9342, 0x2b0c, 0x8012 }, 16, 0x000b08a0, 1},
++	{{0x137f, 0x547c, 0x9ac0, 0x2b09, 0x8020, 0x6061, 0x2b03, 0x8022, 0x98c0, 0x2b0a, 0x8010, 0x6380, 0x5379, 0x9ac0, 0x6261, 0x3fef }, 16, 0x000b08c0, 1},
++	{{0x9fff, 0xcd46, 0x567a, 0x2396, 0x127f, 0x537c, 0x9ad0, 0x6edc, 0x3fef, 0x9fff, 0x5079, 0x567a, 0x238d, 0x6e50, 0x3fef, 0x9fff }, 16, 0x000b08e0, 1},
++	{{0x3820, 0xa000, 0x6396, 0xe9eb, 0xe8e8, 0x32e4, 0x3c70, 0x800a, 0x4755, 0x3a00, 0xb000, 0x76d0, 0xd81e, 0x5655, 0xed62, 0xda95 }, 16, 0x000b0900, 1},
++	{{0x2dda, 0x4555, 0x3480, 0xa000, 0x4355, 0x94c0, 0xe768, 0xcd5f, 0x3600, 0xa100, 0xcc5e, 0xcf43, 0x3680, 0xa000, 0xce41, 0x9f71 }, 16, 0x000b0920, 1},
++	{{0x3e00, 0xa005, 0x2201, 0x8001, 0x7757, 0xdb91, 0x7656, 0xc150, 0x3a80, 0xa100, 0x6f0b, 0x6c10, 0xce49, 0xcf4b, 0x96c0, 0xffc3 }, 16, 0x000b0940, 1},
++	{{0x0cf6, 0xbfff, 0x96c0, 0xc488, 0x2718, 0x813e, 0x3660, 0xa000, 0xcfb8, 0xceba, 0x3660, 0xa000, 0xcaa2, 0xc8a6, 0x96c0, 0xccaa }, 16, 0x000b0960, 1},
++	{{0x2f0e, 0x8046, 0x96c0, 0x4416, 0x2e0b, 0x8022, 0x0013, 0xcfae, 0x94c0, 0xeb46, 0xceb2, 0x94c0, 0xeaeb, 0xe8eb, 0x3640, 0xa000 }, 16, 0x000b0980, 1},
++	{{0xea64, 0xe83f, 0x0012, 0x4010, 0x94c0, 0xeaeb, 0xe8eb, 0x3640, 0xa000, 0xea3c, 0xe83e, 0x3640, 0xa000, 0x4012, 0xccac, 0x94c0 }, 16, 0x000b09a0, 1},
++	{{0xeaeb, 0xc9b0, 0x0010, 0xea3f, 0x94c0, 0xefeb, 0xcdb4, 0x94c0, 0xe8eb, 0xeceb, 0x94c0, 0xef3e, 0xe839, 0x3620, 0xa000, 0xec3c }, 16, 0x000b09c0, 1},
++	{{0xeeeb, 0x3620, 0xa100, 0xcba4, 0xedeb, 0x0014, 0xee3d, 0x3600, 0xa100, 0x4010, 0xed62, 0x94c0, 0xeceb, 0xe8eb, 0x3640, 0xa000 }, 16, 0x000b09e0, 1},
++	{{0xedeb, 0xc9a0, 0x3660, 0xa000, 0xec38, 0xe83a, 0x3620, 0xa000, 0xed3b, 0x4012, 0x3680, 0xa100, 0x4015, 0xeeeb, 0x3680, 0xa100 }, 16, 0x000b0a00, 1},
++	{{0xefeb, 0xedeb, 0x3680, 0xa100, 0xeaeb, 0xeceb, 0x3600, 0xa100, 0xeaeb, 0xebeb, 0x3600, 0xa100, 0xe9eb, 0xe8eb, 0x3600, 0xa100 }, 16, 0x000b0a20, 1},
++	{{0x4013, 0xed6e, 0x3680, 0xa100, 0xee78, 0xec76, 0x3680, 0xa000, 0xef70, 0xe974, 0x3600, 0xa100, 0xea7a, 0xeb7c, 0x36c0, 0xa100 }, 16, 0x000b0a40, 1},
++	{{0xe87e, 0xea39, 0x0017, 0xeb72, 0x3600, 0xa100, 0x4012, 0x4013, 0x3600, 0xa100, 0x4016, 0x4010, 0x3680, 0xa000, 0x4012, 0x4010 }, 16, 0x000b0a60, 1},
++	{{0x0015, 0x4014, 0x3600, 0xa100, 0x4011, 0x4014, 0x3680, 0xa100, 0x4016, 0x4015, 0x3004, 0x2c82, 0x800b, 0x3680, 0xa000, 0x4017 }, 16, 0x000b0a80, 1},
++	{{0x4013, 0x3c80, 0xa000, 0x6c10, 0x3dc0, 0x2a1a, 0x8009, 0xe9fc, 0x98c0, 0x3ec0, 0x2a12, 0x8009, 0xfbc3, 0x3a40, 0xa000, 0x3cc0 }, 16, 0x000b0aa0, 1},
++	{{0x2a0a, 0x8009, 0xed19, 0x3660, 0xa000, 0xee19, 0x5c15, 0x3a80, 0xa000, 0xe91c, 0x32c2, 0x2a22, 0x8009, 0x3a80, 0xa000, 0x5d11 }, 16, 0x000b0ac0, 1},
++	{{0x31c2, 0x2a28, 0x8009, 0x3880, 0xa000, 0xecfc, 0x2b0a, 0x8046, 0x96c0, 0xedfc, 0x2a08, 0x8002, 0x38a0, 0xa000, 0xec1a, 0x2809 }, 16, 0x000b0ae0, 1},
++	{{0x8020, 0x36c0, 0xa000, 0x5154, 0xed19, 0x3cc3, 0x1455, 0x5351, 0x9cc0, 0x74d9, 0x3774, 0x9f00, 0x5616, 0x2341, 0x9800, 0x9ec0 }, 16, 0x000b0b00, 1},
++	{{0x39ec, 0x9fff, 0x6769, 0x2201, 0x81ff, 0x7751, 0x5752, 0x9cc0, 0x6764, 0x6c7c, 0x3cc0, 0x23d0, 0x8009, 0xceb6, 0x3c80, 0xa000 }, 16, 0x000b0b20, 1},
++	{{0xd351, 0x290f, 0x8006, 0x7273, 0xc948, 0x3a80, 0xa000, 0xd253, 0x62bf, 0xe8ef, 0x5057, 0x3e66, 0x0451, 0x4550, 0x3880, 0xa000 }, 16, 0x000b0b40, 1},
++	{{0xdd04, 0x5150, 0xe864, 0x3a80, 0xa100, 0xdb1a, 0x6ed1, 0xefef, 0x5450, 0x96c0, 0x7f41, 0xedef, 0xe9ef, 0x1650, 0xc656, 0x3680 }, 16, 0x000b0b60, 1},
++	{{0xa000, 0xef72, 0xed78, 0x3680, 0xa000, 0xee1c, 0x4555, 0x3680, 0xa000, 0x5256, 0xe93e, 0x6567, 0x35ea, 0x9fff, 0x7d42, 0x2f56 }, 16, 0x000b0b80, 1},
++	{{0x355a, 0x32e4, 0x3b10, 0x800a, 0x3600, 0xa100, 0x4252, 0x4657, 0x3600, 0xa100, 0xcabc, 0xedef, 0xe9ed, 0x3a80, 0xa000, 0xed3a }, 16, 0x000b0ba0, 1},
++	{{0x32e4, 0x3b70, 0x800a, 0x3420, 0xa000, 0xe8ed, 0x32e4, 0x3c00, 0x800a, 0x3640, 0xa000, 0xe9ed, 0xe8ed, 0x9ac0, 0x2be2, 0x9ffe }, 16, 0x000b0bc0, 1},
++	{{0x6c90, 0x2b0a, 0x8054, 0x9ac0, 0x33e9, 0x9fff, 0x9342, 0x2b0e, 0x8044, 0x96c0, 0x537a, 0x2b0c, 0x8052, 0x98c0, 0x62e1, 0x537e }, 16, 0x000b0be0, 1},
++	{{0x2b03, 0x801e, 0x98c0, 0x2b09, 0x8042, 0x608d, 0x527c, 0x98c0, 0x6f5c, 0x33e9, 0x9fff, 0x5479, 0x2096, 0x147a, 0x577e, 0x9ad0 }, 16, 0x000b0c00, 1},
++	{{0x33e9, 0x9fff, 0x6ed4, 0x567c, 0x5479, 0x209b, 0x6f5e, 0x33e9, 0x9fff, 0x3860, 0xa000, 0x6096, 0xe9ed, 0xe8ef, 0x32e4, 0x3c70 }, 16, 0x000b0c20, 1},
++	{{0x800a, 0x4157, 0x3a00, 0xa100, 0xdb90, 0x5657, 0x2121, 0x9fff, 0x98c0, 0x6d86, 0x5057, 0x24c1, 0x8000, 0x3a00, 0xa100, 0x37eb }, 16, 0x000b0c40, 1},
++	{{0x9fff, 0x6d43, 0xc940, 0x3600, 0xa100, 0x65ea, 0x4250, 0x94c0, 0xd351, 0xe944, 0x2c16, 0x4751, 0x31e8, 0x9fff, 0x6468, 0xd35c }, 16, 0x000b0c60, 1},
++	{{0xd81e, 0x3a80, 0xb900, 0x77d6, 0x7754, 0xcf43, 0xce41, 0x9f71, 0x98c0, 0x75d1, 0x74d0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b0c80, 1},
++	{{0x94c0, 0xe750, 0xc086, 0x98c0, 0xffcd, 0x3ec0, 0x2392, 0x8009, 0x90c0, 0x2f09, 0x8072, 0x0311, 0xece9, 0x94c0, 0xec62, 0xc94e }, 16, 0x000b0ca0, 1},
++	{{0x3204, 0x3090, 0x800b, 0x4114, 0x3750, 0x101e, 0xc946, 0x90c0, 0x96c0, 0x5111, 0x290c, 0x8002, 0x3204, 0x3090, 0x800b, 0xfc43 }, 16, 0x000b0cc0, 1},
++	{{0x96c0, 0x7650, 0xc28b, 0xfcc3, 0xf244, 0x3456, 0x111c, 0x5e56, 0x3204, 0x30a0, 0x800b, 0x98c0, 0x74d6, 0x7754, 0xf101, 0xfc43 }, 16, 0x000b0ce0, 1},
++	{{0x9ac0, 0x7656, 0x7750, 0x74d7, 0xfcc3, 0xee44, 0x7454, 0x121c, 0x3204, 0x30a0, 0x800b, 0x94c0, 0xf201, 0xfc43, 0x96c0, 0x7650 }, 16, 0x000b0d00, 1},
++	{{0xf1c4, 0xfcc3, 0x78e1, 0x24ea, 0xf144, 0x81c1, 0x94c0, 0x7454, 0x9756, 0x9ac0, 0x2f0e, 0x809e, 0x90c0, 0x2f0c, 0x809a, 0x92d0 }, 16, 0x000b0d20, 1},
++	{{0x5f0c, 0x4f0e, 0x9cc0, 0x6ec2, 0x2321, 0x9fff, 0x6f02, 0x21c1, 0x8000, 0x98c0, 0x6062, 0x6d5e, 0xfacb, 0xf9cc, 0x3c70, 0x3d70 }, 16, 0x000b0d40, 1},
++	{{0xe770, 0x9cc0, 0xdb90, 0xda10, 0xdb12, 0xd912, 0x9e21, 0x9f21, 0x2e8f, 0x6f0e, 0x9ac0, 0x3bed, 0x9fff, 0x90c0, 0x3dee, 0x9fff }, 16, 0x000b0d60, 1},
++	{{0x66ea, 0xd253, 0x6661, 0x6e84, 0x3bed, 0x9fff, 0x66e8, 0x276a, 0xd259, 0x0452, 0xd153, 0x6561, 0x6f18, 0x3dee, 0x9fff, 0x96c0 }, 16, 0x000b0d80, 1},
++	{{0x6768, 0x9621, 0x9721, 0x94c0, 0xd159, 0x9f70, 0x4251, 0x90c0, 0x98c0, 0xd910, 0xdb91, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b0da0, 1},
++	{{0x94c0, 0xe750, 0xc086, 0x98c0, 0xfecd, 0x3fc0, 0x2392, 0x8009, 0x90c0, 0x98c0, 0x6d4b, 0x6fab, 0x2e0d, 0x80a2, 0x96c0, 0xd89f }, 16, 0x000b0dc0, 1},
++	{{0xe9ed, 0x4255, 0x94c0, 0xe962, 0xcd4e, 0x3204, 0x3090, 0x800b, 0x4751, 0x3750, 0x101f, 0xcd46, 0x90c0, 0x96c0, 0x5115, 0x2d0a }, 16, 0x000b0de0, 1},
++	{{0x8002, 0x3204, 0x3090, 0x800b, 0xfa43, 0x96c0, 0x76d0, 0xc28b, 0xfac3, 0xf244, 0x3456, 0x131a, 0x5e57, 0x3204, 0x30a0, 0x800b }, 16, 0x000b0e00, 1},
++	{{0x98c0, 0x74d6, 0x7755, 0xf301, 0xfa43, 0x9ac0, 0x76d6, 0x7750, 0x74d7, 0xfac3, 0xef44, 0x7455, 0x141a, 0x3204, 0x30a0, 0x800b }, 16, 0x000b0e20, 1},
++	{{0x94c0, 0xf401, 0xfa43, 0x96c0, 0x76d0, 0xf3c4, 0xfac3, 0x79e1, 0x25ea, 0xf344, 0x81c1, 0x94c0, 0x7455, 0x9756, 0x9ac0, 0x2e0b }, 16, 0x000b0e40, 1},
++	{{0x80ce, 0x90c0, 0x2e0f, 0x80ca, 0x92d0, 0x5e0f, 0x4e0b, 0x98c0, 0x7f44, 0x7c44, 0xfacb, 0xf9cc, 0x2765, 0x2465, 0xe770, 0x94c0 }, 16, 0x000b0e60, 1},
++	{{0x9e21, 0x9f21, 0x4652, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4051, 0x94c0, 0x6c10, 0x974c, 0x96c0, 0x9620, 0x2b02, 0x8002, 0x96c0 }, 16, 0x000b0e80, 1},
++	{{0xe748, 0x280b, 0x8070, 0x2809, 0x8072, 0x94c8, 0x403b, 0x4039, 0x98c0, 0xc84e, 0x32e4, 0x3ca0, 0x800a, 0x94c0, 0xf841, 0xc181 }, 16, 0x000b0ea0, 1},
++	{{0x96c0, 0x6c10, 0xc846, 0xc181, 0x3204, 0x2090, 0x800b, 0xf841, 0xe768, 0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b0ec0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0xe758, 0x94c0, 0xf0cd, 0xf7ce, 0x7440, 0x246a, 0x7750, 0x8473, 0x92c0, 0xf045 }, 16, 0x000b0ee0, 1},
++	{{0x96c0, 0x5118, 0x27ed, 0x9ff2, 0x96c0, 0x5018, 0x27eb, 0x9ff0, 0x94c0, 0xf743, 0xfd42, 0x98c0, 0xefe8, 0x3204, 0x2c90, 0x800b }, 16, 0x000b0f00, 1},
++	{{0x94c0, 0xfb41, 0xeee9, 0x32e4, 0x3ca0, 0x800a, 0x96c0, 0x6c90, 0xf741, 0xf088, 0x98c0, 0x76d0, 0x6c90, 0xf741, 0xf087, 0x3204 }, 16, 0x000b0f20, 1},
++	{{0x2090, 0x800b, 0xf546, 0x9ac0, 0xd910, 0x7b61, 0xf5c6, 0x2401, 0x80ff, 0x9ac0, 0x7d46, 0xda95, 0x676a, 0xe9ee, 0xe8ef, 0x755a }, 16, 0x000b0f40, 1},
++	{{0x6dc9, 0x94c0, 0xde03, 0x819e, 0x4459, 0xf0c5, 0xe778, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000b0f60, 1},
++	{{0x94c0, 0x6d10, 0x974c, 0x96c0, 0x9620, 0x2b02, 0x8002, 0x96c0, 0xe748, 0x280c, 0x80a0, 0x280b, 0x80a2, 0x94c8, 0x423c, 0x423b }, 16, 0x000b0f80, 1},
++	{{0x96c0, 0x6c90, 0xc581, 0xf842, 0x3204, 0x2420, 0x800b, 0x96c0, 0x6c10, 0xf501, 0xc84e, 0x96c0, 0x6c10, 0xc846, 0xc181, 0x3204 }, 16, 0x000b0fa0, 1},
++	{{0x2940, 0x800b, 0xf841, 0xe768, 0x9621, 0x9f71, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x270c, 0x8020 }, 16, 0x000b0fc0, 1},
++	{{0xe7ec, 0x94c0, 0xf19e, 0xf6d0, 0x24ea, 0x77d1, 0x8483, 0xf145, 0x1018, 0xc186, 0x98c0, 0x311d, 0x803f, 0xefe8, 0xeee9, 0x32e4 }, 16, 0x000b0fe0, 1},
++	{{0x3ac0, 0x800a, 0xf546, 0x98c0, 0x6e10, 0x7550, 0xf5c6, 0xf642, 0x9ac0, 0x351c, 0x8003, 0x7455, 0xf401, 0xf19d, 0x3204, 0x2420 }, 16, 0x000b1000, 1},
++	{{0x800b, 0xf447, 0xf4c7, 0x3650, 0x2c90, 0x3454, 0xf641, 0x3204, 0x2940, 0x800b, 0xf448, 0x98c0, 0x74d0, 0xf4c8, 0x27ea, 0x9ff2 }, 16, 0x000b1020, 1},
++	{{0x98c0, 0x27ed, 0x9ff0, 0x7454, 0xf643, 0x3204, 0x2db0, 0x800b, 0x94c0, 0xfa42, 0xfd41, 0x96c0, 0x7be1, 0xe9ee, 0xf588, 0x27ea }, 16, 0x000b1040, 1},
++	{{0x0519, 0xe8ef, 0x94c0, 0xf387, 0x818c, 0x4319, 0xf1c5, 0x96c0, 0xda11, 0x27eb, 0x9fe0, 0x2d54, 0xe7eb, 0x96c0, 0xd81a, 0x9e21 }, 16, 0x000b1060, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x6831, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b1080, 1},
++	{{0xf385, 0x94c0, 0x69b9, 0x9f70, 0x6c53, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b10a0, 1},
++	{{0x3e00, 0xa008, 0x7656, 0x7457, 0x3ac8, 0x3c18, 0xbfff, 0xe8ee, 0x94c0, 0xce40, 0xe9ef, 0x1192, 0xce48, 0x9ac0, 0x331b, 0x8003 }, 16, 0x000b10c0, 1},
++	{{0x6460, 0x2100, 0x9770, 0x65e9, 0x844f, 0x33e4, 0x3c4e, 0x8001, 0x96c0, 0xc5fe, 0x2300, 0x9770, 0x96c0, 0xde80, 0x2100, 0x87d0 }, 16, 0x000b10e0, 1},
++	{{0x9ac0, 0x36a7, 0x8003, 0x90c0, 0x34a3, 0x8003, 0xdb13, 0xd747, 0xcc46, 0x90c0, 0xee3c, 0xce48, 0x7c48, 0x6461, 0x2468, 0x32e4 }, 16, 0x000b1100, 1},
++	{{0x3c48, 0x8001, 0x9ac1, 0x3c10, 0x83e8, 0x90c0, 0x3100, 0x83e8, 0x3104, 0x314a, 0x800b, 0x96c0, 0xce48, 0x2100, 0x9800, 0x32e4 }, 16, 0x000b1120, 1},
++	{{0x3c4e, 0x8001, 0x6460, 0x36d0, 0x6c10, 0x96c0, 0x7ed8, 0x3118, 0x87ff, 0x3b2b, 0x9f00, 0xc56e, 0x9f7d, 0x3de8, 0x3c00, 0xbfff }, 16, 0x000b1140, 1},
++	{{0x32f9, 0x3800, 0x80ff, 0x1595, 0x3ce8, 0x3c00, 0xbfff, 0xdd05, 0xdd9a, 0xdd98, 0x4394, 0xc566, 0x90c0, 0x90c0, 0x9f70, 0x3a00 }, 16, 0x000b1160, 1},
++	{{0xa800, 0x77d0, 0x7754, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0xd422, 0x7750, 0x77d1, 0x9620, 0x9720, 0x94c0, 0x9e20 }, 16, 0x000b1180, 1},
++	{{0x80be, 0x92c2, 0xc0ff, 0x32e4, 0x394e, 0x8001, 0x7456, 0x34d7, 0x2760, 0x3dc0, 0x2a30, 0x8009, 0x24e0, 0xc946, 0x64e9, 0x94c0 }, 16, 0x000b11a0, 1},
++	{{0xe9fe, 0x809c, 0x92c2, 0xc0ff, 0x9ac0, 0x6f90, 0xe91d, 0x3601, 0x2000, 0x8008, 0x30fe, 0x1d91, 0x34e1, 0x3fff, 0x80ff, 0x98c0 }, 16, 0x000b11c0, 1},
++	{{0x3ce8, 0x3c1c, 0xbfff, 0xc941, 0x94c6, 0x9d61, 0xc0ff, 0x98c0, 0x147c, 0x9fe7, 0x7cc5, 0x806d, 0x9ac0, 0xd221, 0x78e1, 0x38e8 }, 16, 0x000b11e0, 1},
++	{{0x3c18, 0xbfff, 0x0991, 0xa000, 0x94c2, 0x0911, 0xb000, 0x0190, 0x3104, 0x3258, 0x800b, 0x96c0, 0xdc84, 0x147c, 0x9fe7, 0x96c0 }, 16, 0x000b1200, 1},
++	{{0xd221, 0x09d1, 0xa000, 0x90c0, 0x94c2, 0x0911, 0xb000, 0x0194, 0x3104, 0x3258, 0x800b, 0x98c0, 0x3d00, 0x3556, 0x8008, 0xe949 }, 16, 0x000b1220, 1},
++	{{0x94c0, 0xc948, 0xc18a, 0x32e4, 0x3c4e, 0x8001, 0x94c0, 0x6460, 0x979d, 0x0002, 0x3550, 0x8008, 0x6c10, 0x9e21, 0x94c0, 0x9621 }, 16, 0x000b1240, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0xd421, 0xda10, 0x3bc8, 0x3c08, 0xbfff, 0x8443, 0x4493 }, 16, 0x000b1260, 1},
++	{{0x1493, 0x3bc8, 0x3c08, 0xbfff, 0x39fc, 0x9fff, 0x7064, 0x800d, 0x5293, 0x35fb, 0x9fff, 0x7063, 0x85f9, 0x32e4, 0x39e4, 0x8001 }, 16, 0x000b1280, 1},
++	{{0xc08b, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3900, 0x32c0, 0x800b, 0xc09c, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc181, 0xc09c, 0x9f71 }, 16, 0x000b12a0, 1},
++	{{0x98c0, 0x3aa8, 0x3c20, 0xbfff, 0xc09c, 0x0dc6, 0x2a3c, 0x8009, 0x1992, 0x3800, 0x20f0, 0x8008, 0x94c0, 0x9620, 0x9f20, 0xebe9 }, 16, 0x000b12c0, 1},
++	{{0xeb3d, 0x0b90, 0x32e4, 0x3a68, 0x8001, 0x09c2, 0x2a3c, 0x8009, 0x0b06, 0x354c, 0x8008, 0x3c00, 0x2036, 0x8008, 0xeb41, 0x0b02 }, 16, 0x000b12e0, 1},
++	{{0x354c, 0x8008, 0x0007, 0x354e, 0x8008, 0x4014, 0x0506, 0x3550, 0x8008, 0x26e9, 0xcc45, 0x8021, 0xec61, 0x98c0, 0xecf1, 0x0c02 }, 16, 0x000b1300, 1},
++	{{0x3550, 0x8008, 0x90c0, 0x98c2, 0x3f00, 0x3556, 0x8008, 0xc381, 0x90c0, 0x92c2, 0x939f, 0x01c5, 0x38b8, 0x8008, 0x3761, 0x0024 }, 16, 0x000b1320, 1},
++	{{0x3364, 0x8009, 0x2769, 0x3cc8, 0x3c10, 0xbfff, 0x801b, 0xd422, 0x8407, 0xd428, 0x8445, 0x98c0, 0xc581, 0x3004, 0x3398, 0x800b }, 16, 0x000b1340, 1},
++	{{0x05c1, 0x38d5, 0x8008, 0x1294, 0x3681, 0x2000, 0x8000, 0x377e, 0x0006, 0x354c, 0x8008, 0x9ac0, 0x311c, 0x803f, 0x90c0, 0x34cd }, 16, 0x000b1360, 1},
++	{{0x8410, 0x347d, 0xd220, 0x8413, 0x7360, 0x90c0, 0x92c3, 0xc281, 0x96c3, 0x02c1, 0x38d5, 0x8008, 0x96c0, 0x6d10, 0x9621, 0x9f21 }, 16, 0x000b1380, 1},
++	{{0x9f70, 0x0220, 0x3364, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x77d0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32e4 }, 16, 0x000b13a0, 1},
++	{{0x38ac, 0x8001, 0xe750, 0x32e4, 0x3a7a, 0x8001, 0xc09e, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc183, 0xc09e, 0x33e4, 0x3b3a, 0x8001 }, 16, 0x000b13c0, 1},
++	{{0x27e0, 0x0307, 0x39c0, 0x8008, 0x25e9, 0x36d7, 0x3c00, 0x2026, 0x8008, 0x3ae1, 0x3e00, 0x38a8, 0x8008, 0x96c6, 0x7ec1, 0xc086 }, 16, 0x000b13e0, 1},
++	{{0x8093, 0x14d4, 0xc845, 0x73fc, 0x94c0, 0xe81e, 0x8082, 0x56d0, 0xd720, 0x8479, 0x9ac0, 0x2000, 0x83e8, 0x90c0, 0x3656, 0x8000 }, 16, 0x000b1400, 1},
++	{{0x806b, 0x33e4, 0x39f6, 0x8001, 0x9ac0, 0x6760, 0x3a00, 0x2114, 0x8008, 0xc082, 0x27eb, 0x9ff0, 0x14d2, 0xfb41, 0x7e48, 0x9ac0 }, 16, 0x000b1420, 1},
++	{{0x3681, 0x8006, 0x90c0, 0x3484, 0x8006, 0xda14, 0xd641, 0x2661, 0x6d10, 0x9ac0, 0x027c, 0x9ffb, 0x90c0, 0x3901, 0x800e, 0x32e4 }, 16, 0x000b1440, 1},
++	{{0x3b76, 0x8001, 0x64e0, 0x2760, 0x11fc, 0x9ff0, 0x98c0, 0xd4c6, 0x3f00, 0x21f2, 0x8008, 0x78e1, 0x2f90, 0x3479, 0x32e4, 0x3b58 }, 16, 0x000b1460, 1},
++	{{0x8001, 0x4717, 0x3104, 0x348c, 0x800b, 0xc081, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000b1480, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x270c, 0x8028, 0xe7ec, 0x270c, 0x8000, 0xc9a8, 0x7450, 0xf014, 0x3aa8, 0x3c20 }, 16, 0x000b14a0, 1},
++	{{0xbfff, 0xfa48, 0xfbc8, 0x90c0, 0x5193, 0xf149, 0x9f7d, 0xc781, 0x07c0, 0x2a40, 0x8009, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea46 }, 16, 0x000b14c0, 1},
++	{{0xfa48, 0xfbc8, 0x90c0, 0x5b13, 0xfb10, 0xf690, 0x3d18, 0x8008, 0xf048, 0xf0c8, 0x6469, 0x3704, 0x3540, 0x800b, 0x3bc8, 0x2428 }, 16, 0x000b14e0, 1},
++	{{0xbfff, 0xfb48, 0xfec8, 0x90c0, 0x5196, 0xf142, 0xf3c2, 0x3719, 0x8080, 0xf148, 0xf5c8, 0xf542, 0x18fc, 0x9ffa, 0xf807, 0x34c9 }, 16, 0x000b1500, 1},
++	{{0x2428, 0xbfff, 0xf448, 0xfcc8, 0x90c0, 0x5394, 0xf342, 0x24e0, 0x9f7f, 0xf0c2, 0xde00, 0xf442, 0xf5c2, 0xfac8, 0x90c0, 0x4592 }, 16, 0x000b1520, 1},
++	{{0x3ce8, 0x3c2c, 0xbfff, 0xfc48, 0xffc8, 0x90c0, 0x5597, 0xf542, 0xf0c2, 0x3119, 0x8f00, 0xf148, 0xf5c8, 0x3ace, 0x8608, 0xf648 }, 16, 0x000b1540, 1},
++	{{0xf4c8, 0xf442, 0x1afc, 0x9ffa, 0xfa09, 0x35c9, 0x2418, 0xbfff, 0xf548, 0xffc8, 0x90c0, 0x5597, 0xf542, 0xf4c2, 0x3909, 0x8030 }, 16, 0x000b1560, 1},
++	{{0xf148, 0xf3c8, 0x36ce, 0x8410, 0xf642, 0xf2c2, 0xf248, 0x1ffc, 0x9fe2, 0xff08, 0x30c9, 0x2418, 0xbfff, 0xf048, 0xfec8, 0x90c0 }, 16, 0x000b1580, 1},
++	{{0x5396, 0xf342, 0xf2c2, 0x350a, 0x8f00, 0xf248, 0xf4c8, 0x38cc, 0x8218, 0xf442, 0xf3c2, 0xf348, 0x1dfc, 0x9fe2, 0xfd06, 0x33e9 }, 16, 0x000b15a0, 1},
++	{{0x3c2c, 0xbfff, 0xf348, 0xfcc8, 0x90c0, 0x5194, 0xf142, 0x22e0, 0x90ff, 0xf4c2, 0xdd04, 0xf242, 0xf2c2, 0xfdc8, 0x90c0, 0x4295 }, 16, 0x000b15c0, 1},
++	{{0x30c9, 0x2418, 0xbfff, 0xf048, 0xfdc8, 0x90c0, 0x5095, 0xf042, 0x32f9, 0x3fff, 0xbfcf, 0xf4c2, 0xdd04, 0xf242, 0xf1c2, 0xf9c8 }, 16, 0x000b15e0, 1},
++	{{0x90c0, 0x4191, 0x33c9, 0x2418, 0xbfff, 0xf348, 0xfac8, 0x90c0, 0x5392, 0xf342, 0x31f9, 0x3fff, 0xb0ff, 0xf6c2, 0xdc86, 0xf141 }, 16, 0x000b1600, 1},
++	{{0xf5c1, 0xffc8, 0x90c0, 0x4597, 0x32e9, 0x3c0c, 0xbfff, 0xf248, 0xfdc8, 0x90c0, 0x5395, 0xf342, 0xf1c2, 0x3389, 0x8000, 0xf148 }, 16, 0x000b1620, 1},
++	{{0xf0c8, 0x30cd, 0x805f, 0xf542, 0xf1c2, 0xf148, 0x11fc, 0x9fe2, 0xf10a, 0x36e9, 0x3c0c, 0xbfff, 0xf648, 0xfcc8, 0x90c0, 0x5494 }, 16, 0x000b1640, 1},
++	{{0xf442, 0x31e9, 0x3fff, 0xbfff, 0xf2c2, 0xdc82, 0xf142, 0xf0c2, 0xfdc8, 0x90c0, 0x4095, 0x13fc, 0x9fd8, 0x73e3, 0x3504, 0x36a2 }, 16, 0x000b1660, 1},
++	{{0x800b, 0x32a9, 0x3c4c, 0xbfff, 0xf248, 0xfac8, 0x90c0, 0x5292, 0xf242, 0xf4c2, 0x0914, 0xa800, 0xf442, 0xf3c2, 0xfdc8, 0x90c0 }, 16, 0x000b1680, 1},
++	{{0x4395, 0x31e9, 0x3c00, 0xbfff, 0xf148, 0xf8c8, 0x90c0, 0x5790, 0xf747, 0xc090, 0x3304, 0x31b0, 0x800a, 0xc08b, 0x33e4, 0x39ea }, 16, 0x000b16a0, 1},
++	{{0x8001, 0xc08a, 0x33e4, 0x39ea, 0x8001, 0xc087, 0x33e4, 0x39ea, 0x8001, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b16c0, 1},
++	{{0x90c0, 0x90c0, 0x9f79, 0x2000, 0x83e8, 0x33e4, 0x39f6, 0x8001, 0xc08b, 0x33e4, 0x39e4, 0x8001, 0xc08a, 0x33e4, 0x39e4, 0x8001 }, 16, 0x000b16e0, 1},
++	{{0x2000, 0x83e8, 0x33e4, 0x39f6, 0x8001, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0xec44, 0xfc48, 0xfcc8, 0x90c0, 0x5614, 0xf605, 0xf285 }, 16, 0x000b1700, 1},
++	{{0xd128, 0x3704, 0x3736, 0x800b, 0xc09a, 0x3304, 0x31b0, 0x800a, 0x3104, 0x373e, 0x800b, 0xc0ae, 0x3304, 0x31b0, 0x800a, 0x35e9 }, 16, 0x000b1720, 1},
++	{{0x3c2c, 0xbfff, 0xf548, 0x1efc, 0x9fee, 0xfe05, 0x10fc, 0x9ff6, 0x7c48, 0xf042, 0xfec8, 0x90c0, 0x5296, 0xf241, 0xf7c2, 0xf4c1 }, 16, 0x000b1740, 1},
++	{{0xdf9c, 0xf741, 0xf4c1, 0xfec8, 0x90c0, 0x4496, 0x3bc8, 0x2418, 0xbfff, 0xfb48, 0x1afc, 0x9ff0, 0xfa05, 0x15fc, 0x9ff6, 0xdb95 }, 16, 0x000b1760, 1},
++	{{0xf742, 0xfdc8, 0x90c0, 0x5695, 0xf641, 0xf5c2, 0xf2c1, 0xde9a, 0xf541, 0xf5c1, 0xffc8, 0x90c0, 0x4597, 0x3cc8, 0x2418, 0xbfff }, 16, 0x000b1780, 1},
++	{{0xfc48, 0x1cfc, 0x9ff4, 0xfc05, 0x10fc, 0x9ff6, 0x7c58, 0xf042, 0xfbc8, 0x90c0, 0x5293, 0xf241, 0xf6c2, 0xf0c1, 0xdf18, 0xf642 }, 16, 0x000b17a0, 1},
++	{{0xf7c2, 0xfec8, 0x90c0, 0x4796, 0x38e8, 0x3c0c, 0xbfff, 0xf848, 0x1dfc, 0x9fec, 0xfd05, 0x11fc, 0x9ff6, 0x7cdf, 0xf142, 0xfec8 }, 16, 0x000b17c0, 1},
++	{{0x90c0, 0x5296, 0xf241, 0xf5c2, 0xf6c1, 0xde9e, 0xf542, 0xf4c2, 0xf8c8, 0x90c0, 0x4490, 0x16fc, 0x9fd8, 0xd321, 0x3504, 0x3826 }, 16, 0x000b17e0, 1},
++	{{0x800b, 0x33a9, 0x3c4c, 0xbfff, 0xf348, 0xfdc8, 0x90c0, 0x5495, 0xf442, 0x32f9, 0x3fff, 0xb7ff, 0xf0c2, 0xdd00, 0xf242, 0xf5c2 }, 16, 0x000b1800, 1},
++	{{0xfec8, 0x90c0, 0x4596, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea46, 0xfa48, 0xf9c8, 0x90c0, 0x5411, 0xf405, 0xf685, 0x3d1e, 0x8008 }, 16, 0x000b1820, 1},
++	{{0xf648, 0xf2c8, 0x6569, 0x3704, 0x3874, 0x800b, 0x33c9, 0x2428, 0xbfff, 0xf348, 0x1ffc, 0x9ff2, 0xff05, 0xfcc8, 0x90c0, 0x5094 }, 16, 0x000b1840, 1},
++	{{0xf042, 0x17fc, 0x9ff6, 0xf0c2, 0xdf98, 0xf742, 0xf5c2, 0xffc8, 0x90c0, 0x4597, 0x9f7c, 0x33a9, 0x3c20, 0xbfff, 0xf348, 0xfcc8 }, 16, 0x000b1860, 1},
++	{{0x90c0, 0x5194, 0xf146, 0xc9a8, 0x270b, 0x8000, 0x27eb, 0x9fd8, 0xe7eb, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000b1880, 1},
++	{{0x98c0, 0x3a00, 0x2032, 0x8008, 0xe748, 0x3b00, 0x2034, 0x8008, 0x1dd2, 0x3c00, 0x203e, 0x8008, 0x96c0, 0x50d3, 0x2980, 0x8001 }, 16, 0x000b18a0, 1},
++	{{0x11d4, 0x3800, 0x203e, 0x8008, 0x9ac0, 0x78c1, 0xe9f8, 0x3a00, 0x2032, 0x8008, 0x0110, 0xe9ad, 0x94c6, 0xcbff, 0x6d10, 0x8048 }, 16, 0x000b18c0, 1},
++	{{0x94c6, 0x4b12, 0xf204, 0x9ac0, 0x2c80, 0x8002, 0x90c0, 0x2b80, 0x8005, 0x90c0, 0x94c0, 0xecf8, 0xebf8, 0xecad, 0x8413, 0x3304 }, 16, 0x000b18e0, 1},
++	{{0x33b0, 0x800b, 0x98c0, 0xf004, 0x3104, 0x3926, 0x800b, 0x96c0, 0x6c10, 0xebad, 0xc588, 0x840f, 0x3304, 0x34a0, 0x800b, 0x3104 }, 16, 0x000b1900, 1},
++	{{0x3926, 0x800b, 0xf504, 0x2d10, 0x3b00, 0x2034, 0x8008, 0x3c00, 0x2032, 0x8008, 0x15fc, 0x9ff8, 0x0513, 0xe768, 0x9f70, 0x4214 }, 16, 0x000b1920, 1},
++	{{0x96c0, 0x6e90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0xcb8b, 0x94c0, 0xce40, 0xe748, 0x3dc0, 0x2a88, 0x8009, 0xee8b, 0x96c0, 0xeefe }, 16, 0x000b1940, 1},
++	{{0x2518, 0x80f8, 0x94c0, 0xee1d, 0xc488, 0x5e96, 0x90c0, 0x94c0, 0xf293, 0x9e61, 0x35db, 0x8000, 0x65e9, 0x98c7, 0x2618, 0x80da }, 16, 0x000b1960, 1},
++	{{0x90c0, 0x6f90, 0x92c3, 0xf704, 0x98c0, 0xc581, 0x3104, 0x3a54, 0x800b, 0xf691, 0x6769, 0x2418, 0x80be, 0x92c2, 0xc581, 0xd321 }, 16, 0x000b1980, 1},
++	{{0x90c0, 0x98c6, 0x2418, 0x80b2, 0x90c0, 0xc081, 0x92c2, 0xf004, 0xd322, 0x90c0, 0x94c6, 0x80a0, 0xc782, 0x92c2, 0xf704, 0xd323 }, 16, 0x000b19a0, 1},
++	{{0x8094, 0x92c2, 0xc588, 0xd324, 0x808c, 0x92c2, 0xc588, 0xd325, 0x8084, 0x92c2, 0xc588, 0xd326, 0x90c0, 0x94c6, 0x807a, 0xc783 }, 16, 0x000b19c0, 1},
++	{{0x92c2, 0xf704, 0xd327, 0x846f, 0x98c0, 0xc588, 0x3104, 0x3a54, 0x800b, 0xf292, 0x6569, 0x805e, 0x92c2, 0xc581, 0xd121, 0x90c0 }, 16, 0x000b19e0, 1},
++	{{0x94c6, 0x8054, 0xc084, 0x92c2, 0xf004, 0xd122, 0x90c0, 0x94c6, 0x8046, 0xc685, 0x92c2, 0xf604, 0xd123, 0x803a, 0x92c2, 0xc590 }, 16, 0x000b1a00, 1},
++	{{0xd124, 0x8032, 0x92c2, 0xc590, 0xd125, 0x90c0, 0x94c6, 0x8028, 0xc086, 0x92c2, 0xf004, 0xd126, 0x90c0, 0x94c6, 0x801a, 0xc787 }, 16, 0x000b1a20, 1},
++	{{0x92c2, 0xf704, 0xd127, 0x840f, 0x98c0, 0xc590, 0x3104, 0x3a54, 0x800b, 0xf404, 0x94c0, 0xcd41, 0xc990, 0x90c0, 0xed89, 0x96c0 }, 16, 0x000b1a40, 1},
++	{{0xedfe, 0x2518, 0x81be, 0x39c0, 0x2a44, 0x8009, 0x3cc0, 0x2abc, 0x8009, 0xed19, 0x1d95, 0x39c0, 0x2abc, 0x8009, 0x90c0, 0x94c0 }, 16, 0x000b1a60, 1},
++	{{0xf094, 0x9d61, 0x311b, 0x8001, 0x65e9, 0x98c7, 0x2618, 0x8192, 0x90c0, 0x6e10, 0x92c3, 0xf403, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1a80, 1},
++	{{0xa002, 0xf794, 0x3f1e, 0x8002, 0x6769, 0x98c7, 0x2618, 0x8172, 0x90c0, 0x6e10, 0x92c3, 0xf403, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1aa0, 1},
++	{{0xa002, 0xf294, 0x351e, 0x8004, 0x6769, 0x98c7, 0x2618, 0x8152, 0x90c0, 0x6d10, 0x92c3, 0xf203, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1ac0, 1},
++	{{0xa002, 0xf394, 0x371a, 0x8008, 0x6569, 0x98c7, 0x2618, 0x8132, 0x90c0, 0x6e10, 0x92c3, 0xf403, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1ae0, 1},
++	{{0xa002, 0x94c0, 0xc385, 0xf691, 0x6fb9, 0x7fc1, 0xcd47, 0x90c0, 0xed19, 0x5315, 0x65e9, 0x90c0, 0x96c6, 0x6769, 0x0905, 0xa002 }, 16, 0x000b1b00, 1},
++	{{0x2418, 0x80fc, 0x94c2, 0x0905, 0xa002, 0xd321, 0x90c0, 0x98c6, 0x2418, 0x80ee, 0x90c0, 0xc481, 0x92c2, 0xf403, 0xd322, 0x90c0 }, 16, 0x000b1b20, 1},
++	{{0x98c6, 0x2418, 0x80dc, 0x90c0, 0xc282, 0x92c2, 0xf203, 0xd323, 0x2418, 0x80cc, 0x94c2, 0x0905, 0xa008, 0xd324, 0x2418, 0x80c0 }, 16, 0x000b1b40, 1},
++	{{0x94c2, 0x0905, 0xa008, 0xd325, 0x2418, 0x80b4, 0x94c2, 0x0905, 0xa008, 0xd326, 0x90c0, 0x94c6, 0x80a6, 0xc483, 0x92c2, 0xf403 }, 16, 0x000b1b60, 1},
++	{{0xd327, 0x849b, 0x3004, 0x3c1c, 0x800b, 0x0905, 0xa008, 0xc685, 0x2da6, 0xf692, 0x7dc1, 0xc843, 0x90c0, 0xe81c, 0x5710, 0x67e9 }, 16, 0x000b1b80, 1},
++	{{0x90c0, 0x96c6, 0x6769, 0x0905, 0xa002, 0x8072, 0x94c2, 0x0905, 0xa002, 0xd321, 0x90c0, 0x94c6, 0x8066, 0xc484, 0x92c2, 0xf403 }, 16, 0x000b1ba0, 1},
++	{{0xd322, 0x90c0, 0x94c6, 0x8058, 0xc785, 0x92c2, 0xf703, 0xd323, 0x804c, 0x94c2, 0x0905, 0xa010, 0xd324, 0x8042, 0x94c2, 0x0905 }, 16, 0x000b1bc0, 1},
++	{{0xa010, 0xd325, 0x90c0, 0x94c6, 0x8036, 0xc386, 0x92c2, 0xf303, 0xd326, 0x90c0, 0x94c6, 0x8028, 0xc287, 0x92c2, 0xf203, 0xd327 }, 16, 0x000b1be0, 1},
++	{{0x841d, 0x3004, 0x3c1c, 0x800b, 0x0905, 0xa010, 0x98c0, 0xc488, 0x3004, 0x3c1c, 0x800b, 0xf403, 0xc689, 0xf603, 0x64e9, 0x92c2 }, 16, 0x000b1c00, 1},
++	{{0x6e90, 0x77f5, 0x67e9, 0x8425, 0x24e9, 0x06c6, 0x2ab8, 0x8009, 0x94c0, 0xf583, 0x801b, 0x94c0, 0xc789, 0xfd84, 0x6b1b, 0xcc46 }, 16, 0x000b1c20, 1},
++	{{0x90c0, 0xed1c, 0x94fd, 0x391f, 0x80ff, 0x3477, 0xe768, 0x9e21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b1c40, 1},
++	{{0x3e00, 0xa004, 0x6e10, 0x6e10, 0x36ca, 0x3c14, 0xbfff, 0x9744, 0x2e90, 0x2c10, 0x2d10, 0x0ac6, 0x38d0, 0x8008, 0x3480, 0xa000 }, 16, 0x000b1c60, 1},
++	{{0x5196, 0x9ac0, 0x3399, 0x8000, 0xe0ea, 0x2a0b, 0x8062, 0x96c0, 0x64e9, 0x9620, 0x9720, 0x96c0, 0x56d3, 0x2b0a, 0x8018, 0x98c6 }, 16, 0x000b1c80, 1},
++	{{0x3d99, 0x8000, 0x57d2, 0x6f10, 0x9ac7, 0x64e9, 0xc681, 0x3f9f, 0x8000, 0xeb62, 0x94c0, 0x9e20, 0x9f20, 0x3606, 0xa004, 0x6c10 }, 16, 0x000b1ca0, 1},
++	{{0x51d3, 0x3e27, 0xa002, 0x90c0, 0xea62, 0xc081, 0x339d, 0x8000, 0x67e9, 0x3820, 0xa000, 0x57d2, 0x270d, 0x8058, 0x3a06, 0xb000 }, 16, 0x000b1cc0, 1},
++	{{0x6d90, 0x3f99, 0x8000, 0xe7ed, 0x3a07, 0xa002, 0xc381, 0x27ef, 0x9fe8, 0x66e9, 0x3a46, 0xb004, 0x6e90, 0x3f5f, 0x8000, 0x4497 }, 16, 0x000b1ce0, 1},
++	{{0x3a27, 0xa000, 0xc581, 0x2f0a, 0x8004, 0x64e9, 0x3820, 0xa000, 0x4492, 0x27e8, 0x9ff0, 0x98c1, 0x67e9, 0x67e9, 0xc181, 0x6c90 }, 16, 0x000b1d00, 1},
++	{{0x3820, 0xa000, 0x4490, 0x280e, 0x8004, 0x3820, 0xa000, 0x4496, 0x27e9, 0x9fd8, 0x94c6, 0xf151, 0x6c90, 0x92c3, 0xc181, 0x92c8 }, 16, 0x000b1d20, 1},
++	{{0x4299, 0x94c0, 0x6f90, 0x9746, 0x27ea, 0x9fc0, 0x92c8, 0x479a, 0x3c00, 0xa004, 0x6469, 0xeae0, 0x3cc0, 0x2abe, 0x8009, 0x3c00 }, 16, 0x000b1d40, 1},
++	{{0xa100, 0x2a08, 0x8068, 0x90c0, 0x27eb, 0x9fea, 0x3800, 0xa100, 0x57d0, 0x280a, 0x8002, 0x3c20, 0xa000, 0x2a0a, 0x8002, 0x90c0 }, 16, 0x000b1d60, 1},
++	{{0x3f1a, 0x8700, 0x02c0, 0x2abc, 0x8009, 0x3880, 0xa000, 0x57d2, 0x2c0d, 0x8002, 0x3c80, 0xa000, 0x2a0e, 0x8002, 0x90c0, 0x3f1a }, 16, 0x000b1d80, 1},
++	{{0x8700, 0x96c0, 0x4214, 0x2d09, 0x8002, 0x3840, 0xa100, 0x57d2, 0x2e0f, 0x8012, 0x3ca0, 0xa000, 0x2f08, 0x8002, 0x90c0, 0x3f1a }, 16, 0x000b1da0, 1},
++	{{0x8700, 0x0215, 0x3fc0, 0x2ac4, 0x8009, 0x3a80, 0xa000, 0x52d6, 0x34c2, 0x2ac6, 0x8009, 0x3ca0, 0xa000, 0x280d, 0x8002, 0x90c0 }, 16, 0x000b1dc0, 1},
++	{{0x351a, 0x8700, 0x3840, 0xa000, 0x4211, 0x2c0b, 0x8002, 0x38c0, 0xa100, 0x57d7, 0x2d09, 0x8002, 0x3f1a, 0x8700, 0x0217, 0x3ec0 }, 16, 0x000b1de0, 1},
++	{{0x2aca, 0x8009, 0x3480, 0xa000, 0x57d0, 0x3f1f, 0x8700, 0x3480, 0xa000, 0x4714, 0x38c0, 0xa100, 0x52d5, 0x2b0c, 0x8002, 0x351f }, 16, 0x000b1e00, 1},
++	{{0x8700, 0x4713, 0x3480, 0xa000, 0x57d1, 0x3f1a, 0x8700, 0x4216, 0x96c0, 0x57d0, 0x27ee, 0x9ff2, 0x9ac0, 0x2e0f, 0x8002, 0x90c0 }, 16, 0x000b1e20, 1},
++	{{0x3f1a, 0x80ff, 0x98c6, 0xf20c, 0x3800, 0x20e0, 0x8008, 0x3a06, 0xa100, 0x3202, 0x20e0, 0x8008, 0x52d2, 0x98c7, 0x351a, 0x80ff }, 16, 0x000b1e40, 1},
++	{{0x90c0, 0xe866, 0x3480, 0xa000, 0x4213, 0x96c0, 0x52d2, 0x27ea, 0x9fee, 0x351f, 0x80ff, 0x3480, 0xa000, 0x4714, 0x3880, 0xa100 }, 16, 0x000b1e60, 1},
++	{{0x52d6, 0x27ee, 0x9ff6, 0x351a, 0x80ff, 0x4212, 0x3480, 0xa000, 0x52d7, 0x351f, 0x80ff, 0xf708, 0x3480, 0xa000, 0x52d0, 0x351f }, 16, 0x000b1e80, 1},
++	{{0x80ff, 0x4716, 0x3480, 0xa000, 0x52d5, 0x351f, 0x80ff, 0x4717, 0x3480, 0xa000, 0x52d1, 0x351a, 0x80ff, 0x3480, 0xa000, 0x4216 }, 16, 0x000b1ea0, 1},
++	{{0x3a86, 0xa002, 0x90c0, 0x52d0, 0x57d2, 0x6469, 0x3c00, 0xa002, 0x357f, 0x9ff0, 0x90c0, 0x351b, 0x8007, 0x7fe4, 0x3c00, 0xa002 }, 16, 0x000b1ec0, 1},
++	{{0x2418, 0x80e4, 0x90c0, 0x3f04, 0x8001, 0x3400, 0xa004, 0x7e63, 0x3600, 0xb000, 0x6769, 0x7773, 0x90c0, 0x98c6, 0xd321, 0x3501 }, 16, 0x000b1ee0, 1},
++	{{0x2000, 0x8010, 0x8433, 0xd3af, 0x8083, 0xd3bf, 0x807f, 0x3417, 0x803f, 0x8079, 0x3417, 0x807f, 0x8073, 0x3417, 0x80ff, 0x806d }, 16, 0x000b1f00, 1},
++	{{0x3417, 0x81ff, 0x8067, 0x3417, 0x83ff, 0x8061, 0x3004, 0x3f8a, 0x800b, 0x0905, 0xa040, 0xd322, 0x8431, 0xd3a7, 0x804f, 0xd3af }, 16, 0x000b1f20, 1},
++	{{0x804b, 0xd3bf, 0x8047, 0x3417, 0x803f, 0x8041, 0x3417, 0x807f, 0x803b, 0x3417, 0x80ff, 0x8035, 0x3417, 0x81ff, 0x802f, 0x3004 }, 16, 0x000b1f40, 1},
++	{{0x3f8a, 0x800b, 0x0905, 0xa040, 0xd326, 0x8417, 0xd3bf, 0x801d, 0x3417, 0x803f, 0x8017, 0x3004, 0x3f8a, 0x800b, 0x0905, 0xa040 }, 16, 0x000b1f60, 1},
++	{{0x6769, 0x90c0, 0x94c3, 0x0905, 0xa008, 0xd321, 0x8409, 0x3417, 0x83ff, 0x8011, 0xd322, 0x2718, 0x8126, 0x3417, 0x81ff, 0x2718 }, 16, 0x000b1f80, 1},
++	{{0x811e, 0x38e8, 0x3c00, 0xbfff, 0x90c0, 0x5790, 0x3f0f, 0x8300, 0x67e9, 0x2518, 0x810a, 0x3024, 0x20bc, 0x800b, 0x0915, 0xa020 }, 16, 0x000b1fa0, 1},
++	{{0x3600, 0xb000, 0x6769, 0x7773, 0x809b, 0xd321, 0x843f, 0xd3af, 0x2518, 0x80ec, 0xd3bf, 0x2518, 0x80e6, 0x3417, 0x803f, 0x2518 }, 16, 0x000b1fc0, 1},
++	{{0x80de, 0x3417, 0x807f, 0x2518, 0x80d6, 0x3417, 0x80ff, 0x2518, 0x80ce, 0x3417, 0x81ff, 0x2518, 0x80c6, 0x3417, 0x83ff, 0x80bf }, 16, 0x000b1fe0, 1},
++	{{0x3024, 0x20bc, 0x800b, 0x2500, 0x8040, 0xd322, 0x8431, 0xd3a7, 0x80ad, 0xd3af, 0x80a9, 0xd3bf, 0x80a5, 0x3417, 0x803f, 0x809f }, 16, 0x000b2000, 1},
++	{{0x3417, 0x807f, 0x8099, 0x3417, 0x80ff, 0x8093, 0x3417, 0x81ff, 0x808d, 0x3024, 0x20bc, 0x800b, 0x2500, 0x8040, 0xd326, 0x8417 }, 16, 0x000b2020, 1},
++	{{0xd3bf, 0x807b, 0x3417, 0x803f, 0x8075, 0x3024, 0x20bc, 0x800b, 0x2500, 0x8040, 0x6769, 0x8067, 0x98c0, 0xc588, 0x3124, 0x20bc }, 16, 0x000b2040, 1},
++	{{0x800b, 0x3400, 0xa800, 0x7773, 0xd321, 0x841f, 0x3417, 0x80ff, 0x804d, 0x3417, 0x81ff, 0x8047, 0x3417, 0x83ff, 0x8041, 0x3024 }, 16, 0x000b2060, 1},
++	{{0x20bc, 0x800b, 0x2500, 0x8040, 0xd322, 0x841f, 0x3417, 0x807f, 0x802d, 0x3417, 0x80ff, 0x8027, 0x3417, 0x81ff, 0x8021, 0x3024 }, 16, 0x000b2080, 1},
++	{{0x20bc, 0x800b, 0x2500, 0x8040, 0xd326, 0x8012, 0x96c2, 0x3501, 0x2000, 0x8010, 0x6769, 0x90c0, 0x92c3, 0xc588, 0x65e9, 0x3420 }, 16, 0x000b20a0, 1},
++	{{0xa000, 0x9a59, 0x96c2, 0x3a00, 0x20e2, 0x8008, 0x90c0, 0x98c1, 0xea6c, 0x3800, 0x20e2, 0x8008, 0x56d2, 0x3a26, 0xa008, 0x57d0 }, 16, 0x000b20c0, 1},
++	{{0x3d79, 0x9ff0, 0x65e9, 0x3800, 0xa00c, 0x7ce4, 0x3d1e, 0x8007, 0x3c00, 0xaa00, 0x3307, 0x8001, 0x7776, 0x2418, 0x8102, 0x7fe3 }, 16, 0x000b20e0, 1},
++	{{0xd321, 0x844f, 0x3400, 0xa004, 0xd0af, 0x809f, 0x3400, 0xa004, 0xd0bf, 0x8097, 0x3600, 0xa004, 0x3411, 0x803f, 0x808d, 0x3600 }, 16, 0x000b2100, 1},
++	{{0xa004, 0x3411, 0x807f, 0x8083, 0x3600, 0xa004, 0x3411, 0x80ff, 0x8079, 0x3600, 0xa004, 0x3411, 0x81ff, 0x806f, 0x3600, 0xa004 }, 16, 0x000b2120, 1},
++	{{0x3411, 0x83ff, 0x8065, 0x3024, 0x21a8, 0x800b, 0x0905, 0xa080, 0xd322, 0x844d, 0x3400, 0xa004, 0xd0a7, 0x804f, 0x3400, 0xa004 }, 16, 0x000b2140, 1},
++	{{0xd0af, 0x8047, 0x3400, 0xa004, 0xd0bf, 0x803f, 0x3600, 0xa004, 0x3411, 0x803f, 0x8035, 0x3600, 0xa004, 0x3411, 0x807f, 0x802b }, 16, 0x000b2160, 1},
++	{{0x3600, 0xa004, 0x3411, 0x80ff, 0x8021, 0x3600, 0xa004, 0x3411, 0x81ff, 0x8017, 0x3024, 0x21a8, 0x800b, 0x0905, 0xa080, 0x6769 }, 16, 0x000b2180, 1},
++	{{0x90c0, 0x94c3, 0x0905, 0xa010, 0xd321, 0x840d, 0x3600, 0xa004, 0x3411, 0x83ff, 0x8015, 0xd322, 0x2718, 0x813a, 0x3600, 0xa004 }, 16, 0x000b21a0, 1},
++	{{0x3411, 0x81ff, 0x2718, 0x812e, 0x38e8, 0x3c00, 0xbfff, 0x90c0, 0x3420, 0xa000, 0x5190, 0x3600, 0xa804, 0x330a, 0x8300, 0x3400 }, 16, 0x000b21c0, 1},
++	{{0xa004, 0x6569, 0x2518, 0x810e, 0x3024, 0x22f2, 0x800b, 0x0915, 0xa020, 0x3400, 0xa800, 0x7776, 0xd321, 0x8457, 0x3400, 0xa004 }, 16, 0x000b21e0, 1},
++	{{0xd0af, 0x2518, 0x80f0, 0x3400, 0xa004, 0xd0bf, 0x2518, 0x80e6, 0x3600, 0xa004, 0x3411, 0x803f, 0x2518, 0x80da, 0x3600, 0xa004 }, 16, 0x000b2200, 1},
++	{{0x3411, 0x807f, 0x2518, 0x80ce, 0x3600, 0xa004, 0x3411, 0x80ff, 0x80c3, 0x3600, 0xa004, 0x3411, 0x81ff, 0x80b9, 0x3600, 0xa004 }, 16, 0x000b2220, 1},
++	{{0x3411, 0x83ff, 0x80af, 0x3024, 0x22f2, 0x800b, 0x0905, 0xa080, 0xd322, 0x844d, 0x3400, 0xa004, 0xd0a7, 0x8099, 0x3400, 0xa004 }, 16, 0x000b2240, 1},
++	{{0xd0af, 0x8091, 0x3400, 0xa004, 0xd0bf, 0x8089, 0x3600, 0xa004, 0x3411, 0x803f, 0x807f, 0x3600, 0xa004, 0x3411, 0x807f, 0x8075 }, 16, 0x000b2260, 1},
++	{{0x3600, 0xa004, 0x3411, 0x80ff, 0x806b, 0x3600, 0xa004, 0x3411, 0x81ff, 0x8061, 0x3024, 0x22f2, 0x800b, 0x0905, 0xa080, 0xd326 }, 16, 0x000b2280, 1},
++	{{0x841f, 0x3400, 0xa004, 0xd0bf, 0x804b, 0x3600, 0xa004, 0x3411, 0x803f, 0x8041, 0x3024, 0x22f2, 0x800b, 0x0905, 0xa080, 0xd325 }, 16, 0x000b22a0, 1},
++	{{0x8429, 0x3400, 0xa004, 0xd0bf, 0x802b, 0x3600, 0xa004, 0x3411, 0x803f, 0x8021, 0x3600, 0xa004, 0x3411, 0x807f, 0x8017, 0x3024 }, 16, 0x000b22c0, 1},
++	{{0x22f2, 0x800b, 0x0905, 0xa080, 0x6769, 0x90c0, 0x94c3, 0x0905, 0xa010, 0x3600, 0xa100, 0x65e9, 0xe96c, 0x90c0, 0x96c3, 0x33c1 }, 16, 0x000b22e0, 1},
++	{{0x2bdc, 0x8009, 0x8456, 0x96c3, 0x03c2, 0x2ab8, 0x8009, 0x3480, 0xa000, 0x53d1, 0x371b, 0x8007, 0x96c0, 0x65e9, 0x3d1b, 0x8007 }, 16, 0x000b2300, 1},
++	{{0x802f, 0x65e9, 0x802b, 0x64e9, 0x90c0, 0x96c3, 0x33c1, 0x2b82, 0x8009, 0x8428, 0x96c3, 0x03c2, 0x2ab8, 0x8009, 0x33c1, 0x2b28 }, 16, 0x000b2320, 1},
++	{{0x8009, 0x3024, 0x235a, 0x800b, 0x03c2, 0x2ab8, 0x8009, 0x33c1, 0x2ace, 0x8009, 0x03c2, 0x2ab8, 0x8009, 0x98c0, 0x6d90, 0xeae0 }, 16, 0x000b2340, 1},
++	{{0x27e8, 0x9fc0, 0x3820, 0xa000, 0xc28c, 0x2a0a, 0x8010, 0x94c0, 0xf552, 0xf053, 0x3a20, 0xa000, 0xf554, 0xcd51, 0x90c0, 0x90c0 }, 16, 0x000b2360, 1},
++	{{0x3e80, 0xa000, 0xcc56, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3e20, 0xa008, 0x7453, 0x74d3, 0x09c6, 0x38d0, 0x8008, 0xc181 }, 16, 0x000b2380, 1},
++	{{0x96c0, 0xd493, 0x52d2, 0xe0e8, 0x3ca0, 0xa002, 0x290a, 0x8002, 0x90c0, 0x34cd, 0x8208, 0x38c0, 0xa100, 0x55d2, 0x2a0f, 0x80ae }, 16, 0x000b23a0, 1},
++	{{0x94c0, 0xdc85, 0xcc5d, 0x64e1, 0x96c0, 0x64e9, 0x3519, 0x80ff, 0x3800, 0xa004, 0x7451, 0x2518, 0x816a, 0x3880, 0xa000, 0x65e9 }, 16, 0x000b23c0, 1},
++	{{0xf502, 0x55d7, 0x3620, 0xa000, 0xf301, 0xf455, 0x9ac1, 0x2502, 0x80a0, 0x90c0, 0x2502, 0x809e, 0xf504, 0x34a0, 0xa000, 0xed1a }, 16, 0x000b23e0, 1},
++	{{0x3aa0, 0xa000, 0x56d5, 0x3204, 0x3940, 0x800b, 0x3420, 0xa000, 0xf603, 0x3e40, 0xb000, 0x7550, 0x74f5, 0xe8e0, 0x08c6, 0x38d0 }, 16, 0x000b2400, 1},
++	{{0x8008, 0x3860, 0xa800, 0x7451, 0x5710, 0xf603, 0x3aa0, 0xa200, 0x280e, 0x80b0, 0xdd1f, 0xcc5d, 0x3640, 0xa000, 0x4210, 0xf301 }, 16, 0x000b2420, 1},
++	{{0x36a0, 0xa000, 0x56d6, 0xf502, 0x3204, 0x3940, 0x800b, 0x3420, 0xa000, 0xf604, 0x3a00, 0xb808, 0x75d1, 0x7470, 0xe8e0, 0xf5d2 }, 16, 0x000b2440, 1},
++	{{0x3840, 0xa004, 0x6469, 0x5710, 0xf4d5, 0x3400, 0xa800, 0xdc1f, 0x3600, 0xa004, 0x74f0, 0x4010, 0x3600, 0xa800, 0xde99, 0x805a }, 16, 0x000b2460, 1},
++	{{0xf552, 0x3400, 0xa004, 0xd029, 0x800f, 0x3400, 0xa004, 0xd02a, 0x94c7, 0x8409, 0x6d10, 0xc281, 0x6569, 0x840f, 0x3400, 0xa004 }, 16, 0x000b2480, 1},
++	{{0xd02b, 0x94c7, 0x8409, 0x6c90, 0xc181, 0x64e9, 0x8411, 0x3400, 0xa004, 0xd02c, 0x3607, 0xa004, 0x6c10, 0x840f, 0x3420, 0xa000 }, 16, 0x000b24a0, 1},
++	{{0xc081, 0x3600, 0xa004, 0x6469, 0xcd5a, 0x8009, 0x6569, 0x92c3, 0x7a41, 0x3400, 0xa804, 0x7475, 0x3400, 0xa004, 0x6469, 0x805d }, 16, 0x000b24c0, 1},
++	{{0x3400, 0xa004, 0xd029, 0x8011, 0x3400, 0xa004, 0xd02a, 0x3607, 0xa004, 0x6c90, 0x840f, 0x3420, 0xa000, 0xc181, 0x3400, 0xa004 }, 16, 0x000b24e0, 1},
++	{{0x64e9, 0x840f, 0x3400, 0xa004, 0xd02b, 0x94c7, 0x8409, 0x6e90, 0xc581, 0x66e9, 0x8411, 0x3400, 0xa004, 0xd02c, 0x3607, 0xa004 }, 16, 0x000b2500, 1},
++	{{0x6c10, 0x840f, 0x3420, 0xa000, 0xc081, 0x3600, 0xa004, 0x6469, 0xcd5a, 0x8009, 0x6569, 0x92c3, 0x7a41, 0x3a00, 0xa004, 0x7961 }, 16, 0x000b2520, 1},
++	{{0x79c1, 0xea42, 0xe842, 0x3400, 0xa004, 0x656a, 0x2dff, 0x9e45, 0x3a60, 0xa000, 0x03c4, 0x2abc, 0x8009, 0xf5d4, 0x3a00, 0xa005 }, 16, 0x000b2540, 1},
++	{{0x3413, 0x8500, 0x66e0, 0xf5d2, 0x3dc0, 0x2ac0, 0x8009, 0x3cc0, 0x2abe, 0x8009, 0x39c0, 0x2ac2, 0x8009, 0x8012, 0x3bc0, 0x2ac8 }, 16, 0x000b2560, 1},
++	{{0x8009, 0x3600, 0xa004, 0x3413, 0x8700, 0x8407, 0x0905, 0xa100, 0x5314, 0x3413, 0x8500, 0x8009, 0x3413, 0x8700, 0x8407, 0x0905 }, 16, 0x000b2580, 1},
++	{{0xa200, 0x5115, 0x3411, 0x8500, 0x8009, 0x3411, 0x8700, 0x8407, 0x0905, 0xa400, 0x5211, 0x3412, 0x8500, 0x8009, 0x3412, 0x8700 }, 16, 0x000b25a0, 1},
++	{{0x8407, 0x0905, 0xa800, 0x3400, 0xa004, 0x77d3, 0x3400, 0xa804, 0xdf9b, 0x3400, 0xa004, 0xdf99, 0x3400, 0xa004, 0xdf9a, 0x3400 }, 16, 0x000b25c0, 1},
++	{{0xa004, 0x67e9, 0x804f, 0x3400, 0xa004, 0x65e9, 0x8011, 0x3400, 0xa804, 0x73e3, 0x843e, 0x94c3, 0x0915, 0xa001, 0x65e9, 0x8011 }, 16, 0x000b25e0, 1},
++	{{0x3400, 0xa004, 0x73e3, 0x842c, 0x94c3, 0x0915, 0xa001, 0x64e9, 0x8011, 0x3400, 0xa004, 0x73e1, 0x841a, 0x94c3, 0x0915, 0xa001 }, 16, 0x000b2600, 1},
++	{{0x6569, 0x8011, 0x3400, 0xa004, 0x73e2, 0x90c0, 0x94c3, 0x0915, 0xa001, 0x3ac0, 0x2ac4, 0x8009, 0x90c0, 0x3420, 0xa000, 0x5312 }, 16, 0x000b2620, 1},
++	{{0x3600, 0xa004, 0x3413, 0x8500, 0x800d, 0x3600, 0xa004, 0x3413, 0x8700, 0x8407, 0x0905, 0xb000, 0x38c0, 0x2ac6, 0x8009, 0x90c0 }, 16, 0x000b2640, 1},
++	{{0x5110, 0x3411, 0x8500, 0x8009, 0x3411, 0x8700, 0x8407, 0x0925, 0xa000, 0x5313, 0x3413, 0x8500, 0x8009, 0x3413, 0x8700, 0x8407 }, 16, 0x000b2660, 1},
++	{{0x0945, 0xa000, 0x38c0, 0x2aca, 0x8009, 0x90c0, 0x5210, 0x3412, 0x8500, 0x8009, 0x3412, 0x8700, 0x8407, 0x0985, 0xa000, 0x3400 }, 16, 0x000b2680, 1},
++	{{0xa004, 0x7751, 0x3400, 0xa804, 0xdf1b, 0x3400, 0xa004, 0xdf1b, 0x3400, 0xa004, 0xdf1a, 0x3a40, 0xa004, 0x6769, 0x06c0, 0x2acc }, 16, 0x000b26a0, 1},
++	{{0x8009, 0x804f, 0x3400, 0xa004, 0x65e9, 0x8011, 0x3400, 0xa804, 0x7363, 0x843e, 0x94c3, 0x0915, 0xa002, 0x64e9, 0x8011, 0x3400 }, 16, 0x000b26c0, 1},
++	{{0xa004, 0x7361, 0x842c, 0x94c3, 0x0915, 0xa002, 0x65e9, 0x8011, 0x3400, 0xa004, 0x7363, 0x841a, 0x94c3, 0x0915, 0xa002, 0x6569 }, 16, 0x000b26e0, 1},
++	{{0x8011, 0x3400, 0xa004, 0x7362, 0x90c0, 0x94c3, 0x0915, 0xa002, 0x98c0, 0x6c90, 0xc290, 0x27e8, 0x9fd8, 0x94c0, 0xf241, 0xf552 }, 16, 0x000b2700, 1},
++	{{0x3620, 0xa000, 0xf554, 0xf455, 0x32e4, 0x3c8a, 0x8001, 0x3420, 0xa000, 0xf456, 0x3a20, 0xa000, 0xf5d4, 0x3cc0, 0x2abe, 0x8009 }, 16, 0x000b2720, 1},
++	{{0x3c00, 0xa004, 0x66e0, 0xf5d2, 0x3dc0, 0x2ac0, 0x8009, 0x3c80, 0xa101, 0x27eb, 0x9fea, 0x66e9, 0x27ec, 0x9fec, 0x80a4, 0x3a20 }, 16, 0x000b2740, 1},
++	{{0xa000, 0xf4d6, 0x39c0, 0x2ac2, 0x8009, 0xf28c, 0xd121, 0x90c0, 0x94c6, 0x8020, 0xc382, 0x92c2, 0xf30c, 0x98c0, 0xd521, 0x01c4 }, 16, 0x000b2760, 1},
++	{{0x2abc, 0x8009, 0x840d, 0x64e9, 0x90c0, 0x94c3, 0x0915, 0xa040, 0x3480, 0xa000, 0x5113, 0xd0a1, 0x90c0, 0x94c6, 0x801c, 0xc282 }, 16, 0x000b2780, 1},
++	{{0x3482, 0xa000, 0x4213, 0x1314, 0xd4a1, 0x840d, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa080, 0x3480, 0xa000, 0x5314, 0xd1a1, 0x90c0 }, 16, 0x000b27a0, 1},
++	{{0x94c6, 0x801c, 0xc182, 0x3482, 0xa000, 0x4114, 0x1115, 0xd5a1, 0x840d, 0x64e9, 0x90c0, 0x94c3, 0x0915, 0xa100, 0x27ea, 0x9fee }, 16, 0x000b27c0, 1},
++	{{0x5112, 0xd0a1, 0x90c0, 0x94c6, 0x801a, 0xc282, 0x92c2, 0x4212, 0x1311, 0xd4a1, 0x840d, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa200 }, 16, 0x000b27e0, 1},
++	{{0x3c00, 0xa800, 0x75d4, 0x3dc0, 0x2abc, 0x8009, 0xc284, 0x96c0, 0x75c3, 0x27e9, 0x9fe8, 0x3640, 0xa000, 0x511d, 0x5311, 0x3ec0 }, 16, 0x000b2800, 1},
++	{{0xa402, 0x3411, 0x8100, 0xc843, 0x3701, 0x8001, 0xc581, 0x3840, 0xa804, 0xd691, 0xf6ca, 0x8483, 0x3640, 0xa000, 0xc181, 0xf2ca }, 16, 0x000b2820, 1},
++	{{0x3a00, 0xa800, 0xd493, 0xe8fe, 0x27ea, 0x9fd8, 0x3800, 0xa004, 0xdf01, 0x64e0, 0xe81a, 0x3600, 0xa00c, 0xdd19, 0x6760, 0x3640 }, 16, 0x000b2840, 1},
++	{{0xa004, 0x7361, 0xf24a, 0x3647, 0xa000, 0x6c90, 0x5290, 0x3606, 0xb008, 0xc181, 0x75d2, 0x3800, 0xb009, 0x64e9, 0xdd85, 0x66e0 }, 16, 0x000b2860, 1},
++	{{0x3400, 0xa004, 0x65e0, 0x3e07, 0xb40a, 0x90c0, 0x71e5, 0x90c0, 0xde9a, 0x0915, 0xa004, 0x3647, 0xa000, 0x6c90, 0x4590, 0x92c2 }, 16, 0x000b2880, 1},
++	{{0xc181, 0x64e9, 0x3024, 0x2a54, 0x800b, 0x94c3, 0x0915, 0xa004, 0x3411, 0x8200, 0x2518, 0x8142, 0x3411, 0x8300, 0x2518, 0x813a }, 16, 0x000b28a0, 1},
++	{{0x3411, 0x8400, 0x2518, 0x8132, 0x3411, 0x8500, 0x80c9, 0x3411, 0x8700, 0x80c3, 0x3a40, 0xa200, 0x3411, 0x8600, 0x74d4, 0x5011 }, 16, 0x000b28c0, 1},
++	{{0x3800, 0xa040, 0x6c53, 0x2718, 0x8174, 0x33a4, 0x35b0, 0x800b, 0x3e00, 0xa207, 0x27e8, 0x9fd8, 0x77d0, 0x7c65, 0x76d0, 0xc181 }, 16, 0x000b28e0, 1},
++	{{0x3c20, 0xa904, 0x3f1b, 0x801f, 0x7c65, 0xca40, 0xc781, 0x3a00, 0xb808, 0xd493, 0x3b1d, 0x801f, 0xcc40, 0x3600, 0xa804, 0xd795 }, 16, 0x000b2900, 1},
++	{{0xeafe, 0x94c0, 0xea18, 0xecfe, 0x3620, 0xa000, 0x5692, 0xec18, 0x3400, 0xa804, 0x7456, 0x3600, 0xa004, 0xdc01, 0x64e0, 0x3400 }, 16, 0x000b2920, 1},
++	{{0xa004, 0x6460, 0x3600, 0xb004, 0x7061, 0xdc9e, 0x94c7, 0x4192, 0x6c90, 0x3646, 0xa000, 0xc181, 0x5294, 0x3600, 0xb000, 0x64e9 }, 16, 0x000b2940, 1},
++	{{0x74d2, 0x3600, 0xa808, 0xdc87, 0x67e0, 0x96c7, 0x64e0, 0x0915, 0xa004, 0x3600, 0xb808, 0x70e7, 0xdf9a, 0x3647, 0xa000, 0x6c90 }, 16, 0x000b2960, 1},
++	{{0x4794, 0x92c2, 0xc181, 0x64e9, 0x3024, 0x2a54, 0x800b, 0x94c3, 0x0915, 0xa004, 0x3820, 0xa000, 0x5611, 0x27ec, 0x9fd8, 0x3800 }, 16, 0x000b2980, 1},
++	{{0xa80c, 0x75d6, 0x7f65, 0xc181, 0x3880, 0xa804, 0x3718, 0x801f, 0xc846, 0x3400, 0xa800, 0xd490, 0xe8fe, 0xe81c, 0x3420, 0xa000 }, 16, 0x000b29a0, 1},
++	{{0x5090, 0x3400, 0xa804, 0x74d0, 0x3600, 0xa004, 0xdc81, 0x64e0, 0x3400, 0xa004, 0x64e0, 0x3600, 0xb004, 0x70e1, 0xdc98, 0x94c7 }, 16, 0x000b29c0, 1},
++	{{0x4190, 0x6c90, 0x92c2, 0xc181, 0x64e9, 0x3024, 0x2a54, 0x800b, 0x94c3, 0x0915, 0xa004, 0x3820, 0xa000, 0x5711, 0x27ea, 0x9fd8 }, 16, 0x000b29e0, 1},
++	{{0x3800, 0xa80c, 0x7557, 0x7fe5, 0xc181, 0x3880, 0xa804, 0x351f, 0x801f, 0xcc47, 0x3400, 0xa800, 0xd497, 0xecfe, 0xec1a, 0x3420 }, 16, 0x000b2a00, 1},
++	{{0xa000, 0x5594, 0x3400, 0xa804, 0x74d5, 0x3600, 0xa004, 0xdc81, 0x64e0, 0x3400, 0xa004, 0x64e0, 0x3600, 0xb004, 0x70e1, 0xdc9d }, 16, 0x000b2a20, 1},
++	{{0x94c7, 0x4194, 0x6c90, 0x92c2, 0xc181, 0x64e9, 0x90c0, 0x94c3, 0x0915, 0xa004, 0x3961, 0xe942, 0x656a, 0x2dff, 0x9dbd, 0x98c0 }, 16, 0x000b2a40, 1},
++	{{0x6c90, 0xc290, 0x27e8, 0x9fd8, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf241, 0xf552, 0x94c0, 0xf1d1, 0xf5d2, 0x9ac0, 0x64e9, 0xf4d5 }, 16, 0x000b2a60, 1},
++	{{0x3bc0, 0x2ac8, 0x8009, 0x94c0, 0xf288, 0x80af, 0xd121, 0x90c0, 0x94c6, 0x8022, 0xc182, 0x92c2, 0xf108, 0x98c0, 0xd521, 0x3ac0 }, 16, 0x000b2a80, 1},
++	{{0x2ac4, 0x8009, 0x840f, 0x5312, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa400, 0x5316, 0xd1a1, 0x90c0, 0x94c6, 0x8026, 0xc282, 0x92c2 }, 16, 0x000b2aa0, 1},
++	{{0x4216, 0x98c0, 0xd5a1, 0x34c2, 0x2ac6, 0x8009, 0x8413, 0x3480, 0xa000, 0x5314, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa800, 0x5217 }, 16, 0x000b2ac0, 1},
++	{{0xd121, 0x90c0, 0x94c6, 0x801a, 0xc182, 0x92c2, 0x4117, 0x1213, 0xd521, 0x840d, 0x6569, 0x90c0, 0x94c3, 0x0915, 0xb000, 0x3680 }, 16, 0x000b2ae0, 1},
++	{{0xa000, 0x27ee, 0x9ff6, 0x3480, 0xa000, 0x5116, 0xd0a1, 0x90c0, 0x94c6, 0x8024, 0xc282, 0x3482, 0xa000, 0x4216, 0x98c0, 0xd4a1 }, 16, 0x000b2b00, 1},
++	{{0x3ec0, 0x2aca, 0x8009, 0x840f, 0x5316, 0x65e9, 0x90c0, 0x94c3, 0x0935, 0xa000, 0x9ac0, 0x74d7, 0x3dc0, 0x2ac4, 0x8009, 0xc284 }, 16, 0x000b2b20, 1},
++	{{0x96c0, 0x74c1, 0x27e8, 0x9ff0, 0x3600, 0xa004, 0x7551, 0x90c0, 0x3640, 0xa000, 0x531d, 0xc581, 0x9ac0, 0x27e9, 0x9fd8, 0x90c0 }, 16, 0x000b2b40, 1},
++	{{0x3413, 0x8100, 0x3620, 0xa000, 0xf6ca, 0x8481, 0x3640, 0xa000, 0x5310, 0xf3ca, 0x3c00, 0xa004, 0xd693, 0x3701, 0x8001, 0xcc43 }, 16, 0x000b2b60, 1},
++	{{0xc381, 0x3800, 0xa80c, 0xdf05, 0x66e0, 0xd591, 0x3800, 0xa80c, 0xdd9d, 0x6760, 0xecfe, 0x3820, 0xa804, 0x7365, 0xec19, 0xf34a }, 16, 0x000b2b80, 1},
++	{{0x3647, 0xa004, 0x6c90, 0x5594, 0x3626, 0xb000, 0xc181, 0x74d5, 0x3800, 0xa004, 0x64e9, 0xdc83, 0x65e0, 0x64e0, 0x3e07, 0xa400 }, 16, 0x000b2ba0, 1},
++	{{0x90c0, 0x70e3, 0x90c0, 0xdd9d, 0x0915, 0xa008, 0x94c7, 0x4394, 0x6d90, 0x92c2, 0xc381, 0x65e9, 0x3024, 0x2d64, 0x800b, 0x94c3 }, 16, 0x000b2bc0, 1},
++	{{0x0915, 0xa008, 0x3413, 0x8200, 0x2518, 0x812a, 0x3413, 0x8300, 0x2518, 0x8122, 0x3413, 0x8400, 0x2518, 0x811a, 0x3413, 0x8500 }, 16, 0x000b2be0, 1},
++	{{0x80bf, 0x3413, 0x8700, 0x80b9, 0x3a40, 0xa000, 0x3413, 0x8600, 0x74d7, 0x5110, 0x3800, 0xa840, 0x6c58, 0x2718, 0x8150, 0x33a4 }, 16, 0x000b2c00, 1},
++	{{0x35b0, 0x800b, 0x3e00, 0xa206, 0x27ee, 0x9fd8, 0x75d1, 0x7ce5, 0x77d0, 0xc181, 0x3e80, 0xa406, 0x3718, 0x801f, 0xc941, 0x3f1c }, 16, 0x000b2c20, 1},
++	{{0x801f, 0xc381, 0x3800, 0xb800, 0xd490, 0xd594, 0x7c65, 0x94c0, 0xe9fe, 0xcb40, 0xe91e, 0x3620, 0xa000, 0x5791, 0xebfe, 0x3600 }, 16, 0x000b2c40, 1},
++	{{0xa804, 0x7657, 0xeb1e, 0x3600, 0xa004, 0xde01, 0x64e0, 0x3400, 0xa004, 0x6660, 0x3600, 0xb004, 0x7261, 0xdc9f, 0x94c7, 0x4191 }, 16, 0x000b2c60, 1},
++	{{0x6c90, 0x3646, 0xa000, 0xc181, 0x5093, 0x3600, 0xb000, 0x64e9, 0x74d0, 0x25e0, 0xdc83, 0x96c7, 0x64e0, 0x0915, 0xa008, 0x3600 }, 16, 0x000b2c80, 1},
++	{{0xb000, 0x70e3, 0xdd98, 0x94c7, 0x4393, 0x6d90, 0x92c2, 0xc381, 0x65e9, 0x3024, 0x2d64, 0x800b, 0x94c3, 0x0915, 0xa008, 0x96c0 }, 16, 0x000b2ca0, 1},
++	{{0x5310, 0x27e9, 0x9fd8, 0x3820, 0xa000, 0x74d3, 0x7de5, 0xc481, 0x96c0, 0x3319, 0x801f, 0xcf43, 0x3400, 0xa004, 0xd611, 0xeffe }, 16, 0x000b2cc0, 1},
++	{{0xef19, 0x5397, 0x74d3, 0x3600, 0xa808, 0xdc84, 0x6660, 0x64e0, 0x3600, 0xa808, 0x70e4, 0xde1b, 0x3647, 0xa000, 0x6c90, 0x4497 }, 16, 0x000b2ce0, 1},
++	{{0x92c2, 0xc181, 0x64e9, 0x3024, 0x2d64, 0x800b, 0x94c3, 0x0915, 0xa008, 0x3820, 0xa000, 0x5610, 0x27eb, 0x9fd8, 0x3800, 0xa808 }, 16, 0x000b2d00, 1},
++	{{0x75d6, 0x7f65, 0xc181, 0x3880, 0xa000, 0x371b, 0x801f, 0xcf46, 0xd493, 0xeffe, 0xef1b, 0x3420, 0xa000, 0x5397, 0x3400, 0xa800 }, 16, 0x000b2d20, 1},
++	{{0x75d3, 0x24e0, 0xdd81, 0x65e0, 0x3600, 0xb000, 0x71e1, 0xdc9b, 0x94c7, 0x4197, 0x6d90, 0x92c2, 0xc381, 0x65e9, 0x90c0, 0x94c3 }, 16, 0x000b2d40, 1},
++	{{0x0915, 0xa008, 0x3961, 0xe842, 0x656a, 0x2dff, 0x9de7, 0x94c0, 0xd722, 0xf0d3, 0x840d, 0xd624, 0x90c0, 0x94c2, 0x0995, 0xa000 }, 16, 0x000b2d60, 1},
++	{{0x9cc0, 0x3b1f, 0x8018, 0x6c90, 0x3b1a, 0x80c0, 0x934c, 0x9ac0, 0x3b0c, 0x8010, 0x67e9, 0x3b0e, 0x8020, 0x9cc0, 0x6660, 0x2b03 }, 16, 0x000b2d80, 1},
++	{{0x8036, 0x6760, 0x27ee, 0x9fc0, 0x96c7, 0x6569, 0x20c0, 0x8001, 0x90c0, 0x96c7, 0x6669, 0x09c0, 0xa002, 0x92c3, 0x7470, 0x96c7 }, 16, 0x000b2da0, 1},
++	{{0x6769, 0x09c0, 0xa004, 0x92c3, 0x7470, 0x94c3, 0x09c0, 0xa008, 0x1416, 0x33e0, 0x3f00, 0x8003, 0x9ec0, 0x392e, 0x9fcc, 0x6669 }, 16, 0x000b2dc0, 1},
++	{{0x391f, 0x8004, 0xdd84, 0xee42, 0x96c0, 0x391a, 0x8003, 0x8055, 0x98c0, 0x65e9, 0x391c, 0x8020, 0x7cc9, 0x92c3, 0x7470, 0x96c7 }, 16, 0x000b2de0, 1},
++	{{0x6769, 0x09a0, 0xa010, 0x92c3, 0x7470, 0x96c7, 0x67e9, 0x09a0, 0xa100, 0x92c3, 0x7470, 0x96c7, 0x6669, 0x09a0, 0xa020, 0x92c3 }, 16, 0x000b2e00, 1},
++	{{0x7470, 0x96c7, 0x6569, 0x09a0, 0xa040, 0x92c3, 0x7470, 0x94c3, 0x09a0, 0xa080, 0x96c0, 0xdc19, 0x2003, 0x8010, 0x92d0, 0x78c1 }, 16, 0x000b2e20, 1},
++	{{0x90c0, 0x90c0, 0x98c0, 0x27eb, 0x9fc2, 0x7470, 0xf1a0, 0x3cc8, 0x161b, 0x3900, 0x20c0, 0x8008, 0x3d1f, 0x80ff, 0x98c0, 0xdf99 }, 16, 0x000b2e40, 1},
++	{{0x3a00, 0x20c2, 0x8008, 0x0711, 0x3302, 0x20ca, 0x8008, 0x90c0, 0x141b, 0x3900, 0x20c4, 0x8008, 0x3e48, 0x111b, 0x3d00, 0x20c6 }, 16, 0x000b2e60, 1},
++	{{0x8008, 0x331b, 0x80ff, 0x98c0, 0xdd9c, 0x3102, 0x20c8, 0x8008, 0x0312, 0x3a00, 0x20cc, 0x8008, 0x521b, 0x3d48, 0x571b, 0x3f1e }, 16, 0x000b2e80, 1},
++	{{0x80ff, 0xdf1a, 0x4611, 0x96c0, 0x571b, 0x27e9, 0x9fa8, 0x3fc8, 0x561b, 0x3d19, 0x80ff, 0xdc9f, 0x4115, 0x511b, 0x3cc8, 0x571b }, 16, 0x000b2ea0, 1},
++	{{0x3f1b, 0x80ff, 0xdd99, 0x3480, 0xa000, 0x4311, 0x511b, 0x3cc8, 0x5713, 0x96c0, 0x3f1a, 0x80ff, 0xe7e9, 0x96c0, 0xdd19, 0x9e21 }, 16, 0x000b2ec0, 1},
++	{{0x9f21, 0x3480, 0xa000, 0x4213, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4592, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b2ee0, 1},
++	{{0x96c0, 0x5d98, 0x2a03, 0x806c, 0x1998, 0x1005, 0xa03f, 0x5a98, 0x5c98, 0x3420, 0xa000, 0x5318, 0x3600, 0xa004, 0x7de2, 0xeeec }, 16, 0x000b2f00, 1},
++	{{0x3420, 0xa000, 0x9a43, 0x545a, 0x555a, 0x565a, 0x575a, 0x3420, 0xa000, 0x5052, 0x1059, 0x535c, 0x3600, 0xa004, 0x63a0, 0x5159 }, 16, 0x000b2f20, 1},
++	{{0x3800, 0xa00c, 0x6324, 0x638d, 0x525c, 0x3800, 0xa00c, 0x6301, 0x638a, 0x5259, 0x3420, 0xa000, 0x555c, 0x3a00, 0xa21d, 0x62a8 }, 16, 0x000b2f40, 1},
++	{{0x630e, 0x63c1, 0x5359, 0x3420, 0xa000, 0x545c, 0x3a00, 0xa23f, 0x622c, 0x6285, 0x6340, 0x63d7, 0x3400, 0xa844, 0x63e3, 0x3c20 }, 16, 0x000b2f60, 1},
++	{{0xa20d, 0x6209, 0x6282, 0x6b6b, 0x5059, 0x972d, 0x3400, 0xa844, 0x6f5e, 0x3c20, 0xa21d, 0x63a0, 0x6206, 0x62c3, 0x5159, 0x962d }, 16, 0x000b2f80, 1},
++	{{0x3a00, 0xa23f, 0x6324, 0x638d, 0x6242, 0x62df, 0x3400, 0xa844, 0x62e2, 0x3c30, 0xa01d, 0x6301, 0x638a, 0x625b, 0x5259, 0x952d }, 16, 0x000b2fa0, 1},
++	{{0x3400, 0xa844, 0x6e54, 0x3c20, 0xa21d, 0x62a8, 0x630e, 0x63c1, 0x5359, 0x942d, 0xecee, 0x08f1, 0x9ff6, 0x96c0, 0x902c, 0x09f1 }, 16, 0x000b2fc0, 1},
++	{{0x9ff4, 0x96c0, 0x912c, 0x08f5, 0x9ffc, 0x96c0, 0x902c, 0x09f5, 0x9ffe, 0x993c, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000b2fe0, 1},
++	{{0x94c0, 0x9f70, 0xf3c1, 0xc563, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6c90, 0x9248, 0x2a03, 0x803a, 0x96c0, 0x6f10, 0x9620 }, 16, 0x000b3000, 1},
++	{{0x9720, 0x94c0, 0x4110, 0x9f20, 0x9ac0, 0x280a, 0x801c, 0x90c0, 0x280c, 0x8004, 0x3718, 0x2000, 0x8000, 0x9ac0, 0x2808, 0x8038 }, 16, 0x000b3020, 1},
++	{{0x90c0, 0x2b02, 0x801c, 0x2a02, 0x800e, 0x9742, 0x96c0, 0x4638, 0x2902, 0x8002, 0x96c0, 0xe9ea, 0x2a0b, 0x8004, 0x94c8, 0x46a9 }, 16, 0x000b3040, 1},
++	{{0x46ab, 0x9743, 0x9ac0, 0x2902, 0x8002, 0x90c0, 0x2c0f, 0x8004, 0xedec, 0x94d8, 0x46ad, 0x46af, 0x96c0, 0x47b4, 0x2a0a, 0x8038 }, 16, 0x000b3060, 1},
++	{{0x90c0, 0x2d10, 0x01c6, 0x2eac, 0x8009, 0x24e8, 0x3361, 0x3ed8, 0x8648, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff }, 16, 0x000b3080, 1},
++	{{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9ac0, 0x6c10, 0x9f21, 0x01c2, 0x2ea8, 0x8009, 0x94c0 }, 16, 0x000b30a0, 1},
++	{{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9ac0, 0x280e }, 16, 0x000b30c0, 1},
++	{{0x802c, 0x90c0, 0x270b, 0x8198, 0x3800, 0xa100, 0xe7eb, 0x2e09, 0x8004, 0x36e0, 0xa100, 0xece9, 0x5011, 0x3c00, 0xa900, 0x75d0 }, 16, 0x000b30e0, 1},
++	{{0xec62, 0x06c6, 0x2eb0, 0x8009, 0x3800, 0xa100, 0x74d6, 0x5214, 0xf87f, 0x3c40, 0xa000, 0x01fa, 0x9f00, 0xda12, 0x00f8, 0x9efc }, 16, 0x000b3100, 1},
++	{{0x3dd8, 0x04f8, 0x9ef8, 0x65e1, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3 }, 16, 0x000b3120, 1},
++	{{0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a00, 0xa004, 0x7551, 0x3cc0, 0x2e54 }, 16, 0x000b3140, 1},
++	{{0x8009, 0x3800, 0xa004, 0x6561, 0x27eb, 0x9f30, 0x3600, 0xa004, 0x6569, 0x509c, 0x2418, 0x8874, 0x3822, 0xa000, 0x3700, 0x2000 }, 16, 0x000b3160, 1},
++	{{0x8100, 0x9746, 0x90c0, 0x94c8, 0x409b, 0x509c, 0x2c10, 0x0093, 0x3300, 0x2005, 0x8a00, 0x3100, 0x2000, 0x8200, 0x35c3, 0x7841 }, 16, 0x000b3180, 1},
++	{{0x71f1, 0x81fb, 0x98c0, 0x3cc0, 0x2e8c, 0x8009, 0x9744, 0x27ea, 0x9f4c, 0x519c, 0x94c8, 0x419a, 0x519c, 0x3c58, 0x0192, 0x3200 }, 16, 0x000b31a0, 1},
++	{{0x2000, 0x8100, 0x3c00, 0xa008, 0x6461, 0x6c9d, 0x3361, 0x3218, 0x80b1, 0x3c40, 0xa000, 0x6468, 0x6d10, 0x74d0, 0x02f8, 0x9ef4 }, 16, 0x000b31c0, 1},
++	{{0x3846, 0xa000, 0x6c10, 0x01f8, 0x9ef0, 0x32e4, 0x3d62, 0x8001, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b31e0, 1},
++	{{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a20, 0xa001, 0x11f8, 0x9ef0, 0x7651, 0xc598, 0x3c20, 0xa006, 0x64e8, 0x27eb, 0x9f44, 0x6661 }, 16, 0x000b3200, 1},
++	{{0xf167, 0x3800, 0xa804, 0xd641, 0xe9eb, 0xeceb, 0x98c1, 0x66e8, 0x66e8, 0xc0ff, 0x6c10, 0x94c6, 0xf565, 0x6d10, 0x94c7, 0xec70 }, 16, 0x000b3220, 1},
++	{{0xc2ff, 0x94c0, 0xe968, 0xf3e5, 0x96c0, 0x65e0, 0xf1e7, 0xf266, 0x3820, 0xa000, 0x64e0, 0xf068, 0x5594, 0x3620, 0xa000, 0x5391 }, 16, 0x000b3240, 1},
++	{{0xf0e8, 0x3840, 0xa000, 0xf2e6, 0x04f8, 0x9eec, 0x3c40, 0xa000, 0x0bf8, 0x9ee8, 0x90c0, 0x03f8, 0x9ee4, 0x32e4, 0x3d8c, 0x8001 }, 16, 0x000b3260, 1},
++	{{0x3840, 0xa000, 0x5f93, 0x05f8, 0x9ee0, 0x3300, 0x2000, 0x8200, 0x3620, 0xa000, 0x11f8, 0x9ef0, 0x3400, 0xa800, 0xd5c1, 0x65e8 }, 16, 0x000b3280, 1},
++	{{0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x77d1, 0x67e1, 0x96c0, 0x67e8, 0xf763, 0xf761, 0x94c6, 0xf1e1, 0x6c10 }, 16, 0x000b32a0, 1},
++	{{0x9ac7, 0xf3e3, 0x90c0, 0x67e8, 0xc0ff, 0x64e0, 0x96c6, 0x65e0, 0x6d10, 0xf064, 0x92c3, 0xc2ff, 0x94c0, 0xf262, 0xf2e4, 0x32e4 }, 16, 0x000b32c0, 1},
++	{{0x3d62, 0x8001, 0xf0e2, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x7751, 0x6761, 0x96c0 }, 16, 0x000b32e0, 1},
++	{{0x6768, 0xf65f, 0xf65d, 0x94c6, 0xf1dd, 0x6c10, 0x9ac7, 0xf3df, 0x90c0, 0x6768, 0xc0ff, 0x64e0, 0x96c6, 0x65e0, 0x6d10, 0xf060 }, 16, 0x000b3300, 1},
++	{{0x92c3, 0xc2ff, 0x94c0, 0xf25e, 0xf2e0, 0x32e4, 0x3d62, 0x8001, 0xf0de, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b3320, 1},
++	{{0x6d10, 0x92c3, 0xc2ff, 0x3600, 0xa104, 0x77d1, 0xcf4e, 0x3640, 0xa004, 0x67e1, 0xf659, 0x3840, 0xa004, 0x67e8, 0xf75b, 0xf1d9 }, 16, 0x000b3340, 1},
++	{{0x96c6, 0x64e0, 0x6c10, 0xf3db, 0x3e47, 0xa002, 0x90c0, 0x07f8, 0x9edc, 0x6768, 0xc0ff, 0x65e0, 0x94c6, 0xf05c, 0x6d10, 0x92c3 }, 16, 0x000b3360, 1},
++	{{0xc2ff, 0x94c0, 0xf25a, 0xf2dc, 0x32e4, 0x3d62, 0x8001, 0xf0da, 0x3550, 0xc598, 0x26e8, 0xf557, 0x94c6, 0xf3d7, 0x6c10, 0x94c7 }, 16, 0x000b3380, 1},
++	{{0x65e0, 0xc0ff, 0x9ac0, 0x7452, 0xf058, 0x32e4, 0x3d86, 0x8001, 0xf2d8, 0x3c60, 0xa000, 0x17f8, 0x9edc, 0x64e1, 0x13f8, 0x9ee4 }, 16, 0x000b33a0, 1},
++	{{0x3820, 0xb004, 0x67e8, 0x6cd9, 0xf755, 0x94c6, 0xf3d5, 0x6d10, 0x96c7, 0x64e8, 0xc2ff, 0x65e0, 0x94c6, 0xf256, 0x6c10, 0x32e4 }, 16, 0x000b33c0, 1},
++	{{0x3d62, 0x8001, 0x94c7, 0xf2d6, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60 }, 16, 0x000b33e0, 1},
++	{{0xa000, 0x17f8, 0x9edc, 0x7551, 0x15f8, 0x9ee0, 0x3820, 0xa004, 0x67e8, 0x6561, 0xf753, 0x3600, 0xa800, 0x6cc9, 0xf3d3, 0x98c1 }, 16, 0x000b3400, 1},
++	{{0x64e8, 0x64e8, 0xc0ff, 0x6c10, 0x96c6, 0x65e0, 0x6c10, 0xf054, 0x32e4, 0x3d62, 0x8001, 0x94c7, 0xf2d4, 0xc0ff, 0xc598, 0x26e8 }, 16, 0x000b3420, 1},
++	{{0xf551, 0x94c6, 0xf3d1, 0x6d10, 0x94c7, 0x65e0, 0xc2ff, 0x98c0, 0xf252, 0x32e4, 0x3d86, 0x8001, 0xf2d2, 0x3c40, 0xa001, 0x1bf8 }, 16, 0x000b3440, 1},
++	{{0x9ee8, 0x75d1, 0x17f8, 0x9edc, 0x3a20, 0xb004, 0x67e8, 0x75d7, 0x03f8, 0x9ed8, 0x94c6, 0xeb44, 0x6d10, 0x94c7, 0x5193, 0xc2ff }, 16, 0x000b3460, 1},
++	{{0x24e8, 0x0bf8, 0x9ee8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3550, 0xc598, 0x26e8, 0xf54f, 0x94c6, 0xf3cf }, 16, 0x000b3480, 1},
++	{{0x6c10, 0x94c7, 0x65e0, 0xc0ff, 0x9ac0, 0x7452, 0xf050, 0x32e4, 0x3d86, 0x8001, 0xf2d0, 0x3c40, 0xa000, 0x1bf8, 0x9ee8, 0x64e1 }, 16, 0x000b34a0, 1},
++	{{0x17f8, 0x9edc, 0x3640, 0xa004, 0x67e8, 0xf74d, 0x94c0, 0xefeb, 0xf3cd, 0x96c7, 0x65e0, 0xc2ff, 0xef68, 0x3420, 0xa000, 0x5697 }, 16, 0x000b34c0, 1},
++	{{0x3400, 0xa800, 0x6cc6, 0x96c6, 0x64e8, 0x6d10, 0xf14b, 0x94c6, 0xf24e, 0x6c10, 0x94c7, 0xf1cb, 0xc0ff, 0x96c0, 0x64e0, 0xf04c }, 16, 0x000b34e0, 1},
++	{{0xf2ce, 0x32e4, 0x3d62, 0x8001, 0xf0cc, 0xc598, 0x26e8, 0xf549, 0x94c6, 0xf3c9, 0x6d10, 0x94c7, 0x65e0, 0xc2ff, 0x98c0, 0xf24a }, 16, 0x000b3500, 1},
++	{{0x32e4, 0x3d86, 0x8001, 0xf2ca, 0x3c40, 0xa001, 0x1bf8, 0x9ee8, 0x76d1, 0x17f8, 0x9edc, 0x3820, 0xa00c, 0x67e8, 0x66e1, 0xf747 }, 16, 0x000b3520, 1},
++	{{0xeb70, 0x94c7, 0x5293, 0xc0ff, 0x3400, 0xa800, 0x6dc9, 0x96c6, 0x65e8, 0x6c10, 0xf345, 0x94c6, 0xf048, 0x6d10, 0x94c7, 0xf1c5 }, 16, 0x000b3540, 1},
++	{{0xc2ff, 0x96c0, 0x64e0, 0xf246, 0xf3c7, 0x32e4, 0x3d62, 0x8001, 0x96c0, 0x65e0, 0xf2c8, 0xf0c6, 0xc598, 0x26e8, 0x75d5, 0x98c6 }, 16, 0x000b3560, 1},
++	{{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a40, 0xa000, 0x6768, 0x64e1, 0x75d6, 0xf7f4, 0x3400, 0xa800, 0x6cc7, 0x98c1 }, 16, 0x000b3580, 1},
++	{{0x64e8, 0x64e8, 0xc2ff, 0x6d10, 0x94c6, 0xf143, 0x6c10, 0x94c7, 0xf1c3, 0xc0ff, 0x9ac0, 0x64e0, 0xf044, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b35a0, 1},
++	{{0xf0c4, 0xc598, 0x26e8, 0xf541, 0x94c6, 0xf3c1, 0x6d10, 0x94c7, 0x65e0, 0xc2ff, 0x98c0, 0xf242, 0x32e4, 0x3d86, 0x8001, 0xf2c2 }, 16, 0x000b35c0, 1},
++	{{0x3e60, 0xa000, 0x64e1, 0x13f8, 0x9ed8, 0x67e8, 0x11f8, 0x9ef0, 0x3600, 0xb000, 0x75d7, 0x6fd9, 0x3607, 0xb000, 0xc2ff, 0x6ca7 }, 16, 0x000b35e0, 1},
++	{{0x94c6, 0x64e8, 0x6d10, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b3600, 1},
++	{{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x14f8, 0x9eec, 0x7551, 0x12f8, 0x9ef4, 0x3600, 0xb000, 0x6561, 0x74d2, 0x3400 }, 16, 0x000b3620, 1},
++	{{0xa800, 0x6d88, 0x65e8, 0x92c2, 0x6d10, 0x3607, 0xa008, 0xc2ff, 0x6568, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff }, 16, 0x000b3640, 1},
++	{{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3751, 0x3141, 0x3477, 0x8171, 0x6761, 0x2769, 0x75d6 }, 16, 0x000b3660, 1},
++	{{0x2418, 0x8368, 0x3822, 0xa000, 0x3700, 0x2000, 0x8100, 0x6768, 0x92c3, 0x65e4, 0x65e8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10 }, 16, 0x000b3680, 1},
++	{{0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x37d1, 0x2768, 0x3200 }, 16, 0x000b36a0, 1},
++	{{0x2000, 0x8080, 0x27e1, 0x3161, 0x3218, 0x80b1, 0x6fcb, 0x3600, 0xa004, 0x3fe9, 0x9f00, 0x3403, 0xa004, 0x64e4, 0x3880, 0xb004 }, 16, 0x000b36c0, 1},
++	{{0x64e8, 0x75d1, 0xcf41, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10, 0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b36e0, 1},
++	{{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x37d1, 0x3101, 0x2000, 0x8200, 0x67e1, 0x3400, 0xa004, 0x6e3f, 0x3a20, 0xb004, 0x6668 }, 16, 0x000b3700, 1},
++	{{0x75d4, 0x04f8, 0x9ed4, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10, 0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b3720, 1},
++	{{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x24e1, 0xc598, 0x24e8, 0x75d5, 0x92c2, 0x6c10, 0x94c7, 0x66e8, 0xc0ff, 0x98c6, 0x32e4 }, 16, 0x000b3740, 1},
++	{{0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3e40, 0xa000, 0x77d0, 0x14f8, 0x9ed4, 0x7751, 0x27ea, 0x9f5c, 0x3c00, 0xb204, 0x6668 }, 16, 0x000b3760, 1},
++	{{0x75d4, 0x74d4, 0xe9ea, 0xecea, 0x3646, 0xa000, 0x6d10, 0x5792, 0x3a07, 0xa002, 0x90c0, 0xec68, 0xc2ff, 0x6668, 0x94c0, 0xe964 }, 16, 0x000b3780, 1},
++	{{0xea6c, 0x3660, 0xa000, 0x5394, 0x5592, 0x3860, 0xa000, 0x5291, 0x07f8, 0x9ed0, 0x3847, 0xa000, 0xc0ff, 0x02f8, 0x9ecc, 0x3846 }, 16, 0x000b37a0, 1},
++	{{0xa000, 0x6c10, 0x03f8, 0x9ec8, 0x32e4, 0x3d62, 0x8001, 0x3620, 0xa000, 0x05f8, 0x9ec4, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b37c0, 1},
++	{{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa004, 0x7751, 0x17f8, 0x9ed0, 0x3600, 0xb004, 0x6761, 0x74d7, 0x3a20, 0xb004 }, 16, 0x000b37e0, 1},
++	{{0x6768, 0x75d6, 0x06f8, 0x9ec0, 0x92c2, 0x6d10, 0x3607, 0xa008, 0xc2ff, 0x67e8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3 }, 16, 0x000b3800, 1},
++	{{0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x16f8, 0x9ec0, 0x64e1 }, 16, 0x000b3820, 1},
++	{{0x12f8, 0x9ecc, 0x3800, 0xb204, 0x6768, 0x6cd8, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b3840, 1},
++	{{0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x16f8 }, 16, 0x000b3860, 1},
++	{{0x9ec0, 0x64e1, 0x13f8, 0x9ec8, 0x3800, 0xb204, 0x6768, 0x6cd9, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff, 0x98c6, 0x32e4 }, 16, 0x000b3880, 1},
++	{{0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60 }, 16, 0x000b38a0, 1},
++	{{0xa000, 0x16f8, 0x9ec0, 0x64e1, 0x15f8, 0x9ec4, 0x3800, 0xb204, 0x6768, 0x6cc5, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff }, 16, 0x000b38c0, 1},
++	{{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3550, 0xc598, 0x26e8, 0xf573, 0x94c6, 0xf3f3, 0x6c10, 0x94c7, 0x65e0 }, 16, 0x000b38e0, 1},
++	{{0xc0ff, 0x9ac0, 0x7452, 0xf074, 0x32e4, 0x3d86, 0x8001, 0xf2f4, 0x3a20, 0xa000, 0x16f8, 0x9ec0, 0x64e1, 0xf2ed, 0x3800, 0xa204 }, 16, 0x000b3900, 1},
++	{{0x6768, 0x6cd8, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598 }, 16, 0x000b3920, 1},
++	{{0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40, 0xa000, 0x7457, 0x77d1, 0x6760, 0x14f8, 0x9ed4 }, 16, 0x000b3940, 1},
++	{{0x34d6, 0x27e1, 0x3600, 0x2000, 0x8200, 0x6fdf, 0x3400, 0xa040, 0x6d97, 0x65e8, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b3960, 1},
++	{{0xc2ff, 0x3c00, 0xa100, 0x64e1, 0xcf49, 0x3300, 0x2000, 0x8100, 0x3600, 0xa004, 0x64e8, 0x6ed9, 0x3607, 0xa004, 0x64e4, 0x74d5 }, 16, 0x000b3980, 1},
++	{{0x3400, 0xa004, 0x7cf8, 0x3601, 0xb800, 0xd591, 0xd599, 0x65e1, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x66e8, 0xc2ff, 0x98c6, 0x32e4 }, 16, 0x000b39a0, 1},
++	{{0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3400, 0xa004 }, 16, 0x000b39c0, 1},
++	{{0x77d1, 0x3400, 0xa004, 0x67e1, 0x3a40, 0xa000, 0x07c6, 0x2ea8, 0x8009, 0x5116, 0x3c00, 0xac00, 0x34e2, 0x8001, 0xc581, 0x36e6 }, 16, 0x000b39e0, 1},
++	{{0x8001, 0x3600, 0xa800, 0x30e2, 0x8001, 0x98c0, 0xd812, 0x07c6, 0x2ea0, 0x8009, 0x9ac0, 0xd446, 0xf774, 0x07c6, 0x2ea4, 0x8009 }, 16, 0x000b3a00, 1},
++	{{0x96c0, 0x6461, 0xf072, 0xf773, 0x32e4, 0x3c5a, 0x8001, 0x3160, 0x3ed8, 0x8648, 0x2468, 0x37d0, 0x3600, 0x3fb6, 0x8192, 0x90c0 }, 16, 0x000b3a20, 1},
++	{{0x96c3, 0x3260, 0x3ed8, 0x8648, 0x92c3, 0xd7c2, 0x33f6, 0x3620, 0x3f6c, 0x8324, 0x840b, 0x73f6, 0x94c7, 0x843b, 0x6fbf, 0x3620 }, 16, 0x000b3a40, 1},
++	{{0x3f6c, 0x8324, 0x33f6, 0x3240, 0x3f22, 0x84b6, 0x840f, 0x73f2, 0x94c7, 0x8422, 0x6f9f, 0x92c3, 0xc5ff, 0x3240, 0x3f22, 0x84b6 }, 16, 0x000b3a60, 1},
++	{{0x73f2, 0x90c0, 0x98c2, 0x3260, 0x3ed8, 0x8648, 0xc5ff, 0x92c2, 0x6fab, 0x3e20, 0xa000, 0x07f8, 0x9ebc, 0x67e8, 0x75d7, 0x74d7 }, 16, 0x000b3a80, 1},
++	{{0xcf45, 0x92c2, 0x6d10, 0x94c7, 0x67e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6 }, 16, 0x000b3aa0, 1},
++	{{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3751, 0xf3f4, 0x25e8, 0x6761, 0x94c6, 0x74d6, 0x6d10, 0x94c7, 0x6768, 0xc2ff }, 16, 0x000b3ac0, 1},
++	{{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff }, 16, 0x000b3ae0, 1},
++	{{0x3a00, 0xa004, 0x75d1, 0x74d6, 0x27ec, 0x9f34, 0x3600, 0xa004, 0x65e1, 0x5294, 0x3400, 0xa800, 0x6d9d, 0x65e8, 0x92c2, 0x6d10 }, 16, 0x000b3b00, 1},
++	{{0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b3b20, 1},
++	{{0x6d10, 0x92c3, 0xc2ff, 0x3551, 0x34d7, 0x3600, 0x2000, 0x8100, 0x6561, 0x6dca, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x67e8, 0xc2ff }, 16, 0x000b3b40, 1},
++	{{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc698, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b3b60, 1},
++	{{0xc2ff, 0x3c20, 0xa004, 0x76d1, 0xcf4d, 0x03c6, 0x2ea0, 0x8009, 0x3860, 0xa004, 0x66e1, 0xf371, 0xf2f2, 0x3c00, 0xac06, 0x34a6 }, 16, 0x000b3b80, 1},
++	{{0x8005, 0xc781, 0x36a3, 0x8005, 0x3600, 0xa804, 0x30a6, 0x8005, 0x3a00, 0xa804, 0xdb16, 0x3200, 0x3fb6, 0x8192, 0x3a40, 0xa804 }, 16, 0x000b3ba0, 1},
++	{{0xd743, 0x01c6, 0x2ea4, 0x8009, 0x32e4, 0x3c5a, 0x8001, 0x3c40, 0xa040, 0x6c3c, 0xf170, 0x3160, 0x3ed8, 0x8648, 0x2468, 0x76d0 }, 16, 0x000b3bc0, 1},
++	{{0x90c0, 0x3823, 0xa000, 0x3560, 0x3ed8, 0x8648, 0x3403, 0xa800, 0xd6c5, 0x32f2, 0x3220, 0x3f6c, 0x8324, 0x840b, 0x72f2, 0x94c7 }, 16, 0x000b3be0, 1},
++	{{0x8445, 0x6ea9, 0x3820, 0xa000, 0x3220, 0x3f6c, 0x8324, 0x3a00, 0xa800, 0x72f2, 0x3240, 0x3f22, 0x84b6, 0x8411, 0x72f2, 0x3607 }, 16, 0x000b3c00, 1},
++	{{0xa040, 0x6e89, 0x8424, 0x92c3, 0xc7ff, 0x3240, 0x3f22, 0x84b6, 0x72f2, 0x90c0, 0x98c2, 0x3260, 0x3ed8, 0x8648, 0xc7ff, 0x92c2 }, 16, 0x000b3c20, 1},
++	{{0x6ea9, 0x3c40, 0xa000, 0x66e8, 0x75d5, 0x74d5, 0xf67c, 0xcf45, 0x92c2, 0x6d10, 0x94c7, 0x66e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62 }, 16, 0x000b3c40, 1},
++	{{0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3600, 0xa004, 0x75d1 }, 16, 0x000b3c60, 1},
++	{{0xf3f1, 0x3600, 0xa008, 0x65e8, 0x65e1, 0x3a46, 0xa400, 0x6d10, 0x03f8, 0x9eb8, 0x74d3, 0x3607, 0xa008, 0xc2ff, 0x65e8, 0x98c6 }, 16, 0x000b3c80, 1},
++	{{0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40 }, 16, 0x000b3ca0, 1},
++	{{0xa001, 0x27ea, 0x9f40, 0x74d1, 0x13f8, 0x9eb8, 0x3800, 0xb004, 0x64e1, 0x74d3, 0x5292, 0x3400, 0xa800, 0x6db8, 0x65e8, 0x92c2 }, 16, 0x000b3cc0, 1},
++	{{0x6d10, 0x3607, 0xa008, 0xc2ff, 0x65e8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x2768, 0x75d6, 0x98c6, 0x32e4 }, 16, 0x000b3ce0, 1},
++	{{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9ac0, 0x7751, 0x3200, 0x2000, 0x8100, 0xcf4d, 0x2761, 0x74d5, 0x6dca, 0x65e8, 0x92c2 }, 16, 0x000b3d00, 1},
++	{{0x6d10, 0x94c7, 0x66e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b3d20, 1},
++	{{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa004, 0x7551, 0xf6fc, 0xc598, 0x3a00, 0xa40c, 0x6561, 0x6768, 0x75d5, 0x74d6, 0x3c00 }, 16, 0x000b3d40, 1},
++	{{0xac00, 0x34e2, 0x8002, 0x90c0, 0x36e6, 0x8002, 0x3807, 0xb000, 0xc0ff, 0x30e2, 0x8002, 0x3400, 0xa004, 0xd912, 0x3400, 0xa004 }, 16, 0x000b3d60, 1},
++	{{0xd546, 0x3a46, 0xa000, 0x90c0, 0xf27e, 0x6c10, 0x66e8, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a00, 0xa00c }, 16, 0x000b3d80, 1},
++	{{0x7650, 0x76d1, 0x14f8, 0x9ef8, 0x3e00, 0xa200, 0x6668, 0x75d4, 0x77d5, 0x3101, 0x2000, 0x8200, 0x3e06, 0xb000, 0x90c0, 0x32e4 }, 16, 0x000b3da0, 1},
++	{{0x3d62, 0x8001, 0x6d10, 0x7754, 0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b3dc0, 1},
++	{{0xc2ff, 0x3800, 0xa008, 0x7651, 0x76d7, 0x7456, 0x3600, 0xa008, 0x6661, 0x66e0, 0x3c00, 0xa600, 0x6668, 0x75d4, 0x74d5, 0x77d5 }, 16, 0x000b3de0, 1},
++	{{0xcf44, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3e00, 0xa003, 0x11fa, 0x9f00, 0x7656, 0x76d7, 0x7751, 0xca89 }, 16, 0x000b3e00, 1},
++	{{0x3c60, 0xa004, 0x66e0, 0x10f8, 0x9efc, 0x6761, 0xf2fe, 0x38c0, 0xa000, 0xe942, 0x17f8, 0x9ebc, 0x3680, 0xa000, 0x5d11, 0xcf4c }, 16, 0x000b3e20, 1},
++	{{0x98c0, 0xc598, 0x3bc0, 0x2e2c, 0x8009, 0xed61, 0xed8a, 0x96c0, 0xedfe, 0x2518, 0x8c24, 0x9cc0, 0x6668, 0x75d4, 0xed1b, 0x3900 }, 16, 0x000b3e40, 1},
++	{{0x2000, 0x8100, 0x3600, 0xa100, 0x5d95, 0xcb42, 0x96c0, 0xc0ff, 0x27ef, 0x9f1c, 0x94c0, 0xe93b, 0x9d61, 0x3c00, 0xa004, 0x6561 }, 16, 0x000b3e60, 1},
++	{{0xc94c, 0x3500, 0x2000, 0x8100, 0x3e00, 0xa208, 0x77c4, 0x6568, 0x75d2, 0x3119, 0x2000, 0xbe00, 0x98c0, 0xd6c6, 0xf77a, 0x01fa }, 16, 0x000b3e80, 1},
++	{{0x9f00, 0x94c6, 0x449f, 0x6d10, 0x94c7, 0x4797, 0xc2ff, 0xef4c, 0x0597, 0xedef, 0x98c0, 0xed68, 0x32e4, 0x3d62, 0x8001, 0xcd4f }, 16, 0x000b3ea0, 1},
++	{{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcd47, 0x3700, 0x2000, 0x8100, 0x98c0, 0x6e9f }, 16, 0x000b3ec0, 1},
++	{{0xef64, 0x11fa, 0x9f00, 0x3044, 0x2a72, 0x800b, 0x0597, 0x4195, 0x3c00, 0xa004, 0x6561, 0x3500, 0x2000, 0x8100, 0xc0ff, 0x3c00 }, 16, 0x000b3ee0, 1},
++	{{0xaa08, 0xd6c2, 0x6568, 0x75d2, 0x27ed, 0x9f1c, 0x37c5, 0x26e4, 0x3400, 0x2000, 0x8100, 0x96c7, 0xd646, 0xc2ff, 0xf77a, 0x94c6 }, 16, 0x000b3f00, 1},
++	{{0x459d, 0x6d10, 0x0795, 0x3119, 0x2000, 0xbe00, 0x96c0, 0xed4c, 0x01fa, 0x9f00, 0x0495, 0xeaed, 0x94c0, 0xea68, 0xcd4f, 0x98c0 }, 16, 0x000b3f20, 1},
++	{{0xefea, 0x33e4, 0x3d62, 0x8001, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcd47, 0x3700 }, 16, 0x000b3f40, 1},
++	{{0x2000, 0x8100, 0x98c0, 0x6d1f, 0xeaef, 0x11fa, 0x9f00, 0x0192, 0xed64, 0x0295, 0x3144, 0x2a72, 0x800b, 0x3e06, 0xb400, 0x90c0 }, 16, 0x000b3f60, 1},
++	{{0x01fa, 0x9f00, 0x7454, 0x6d10, 0x74d5, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x9ac0, 0x77d6, 0x27ec, 0x9f1c, 0x6e10, 0xf17a }, 16, 0x000b3f80, 1},
++	{{0x3820, 0xa000, 0x67e4, 0x449c, 0xf2fe, 0x3e00, 0xb004, 0x6568, 0x75d2, 0x4794, 0x3500, 0x2000, 0x8100, 0x96c0, 0xd6c6, 0xec4c }, 16, 0x000b3fa0, 1},
++	{{0xc0ff, 0x98c6, 0x3119, 0x2000, 0xbe00, 0x6d10, 0x94c7, 0xefec, 0xc2ff, 0x98c0, 0xcc4f, 0x32e4, 0x3d62, 0x8001, 0x0594, 0xef68 }, 16, 0x000b3fc0, 1},
++	{{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcc47, 0x3500, 0x2000, 0x8100, 0x2d3a, 0x0197 }, 16, 0x000b3fe0, 1},
++	{{0x11fa, 0x9f00, 0x98c0, 0xec64, 0x3044, 0x2a72, 0x800b, 0x4294, 0x3c00, 0xa004, 0x6561, 0x3500, 0x2000, 0x8100, 0xc0ff, 0x3c00 }, 16, 0x000b4000, 1},
++	{{0xa404, 0x6568, 0x27ed, 0x9f1c, 0x75d2, 0xf57a, 0x98c6, 0x3119, 0x2000, 0xbe00, 0x6d10, 0x98c0, 0xcd4f, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b4020, 1},
++	{{0x98c7, 0x01fa, 0x9f00, 0x90c0, 0xc2ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcd47 }, 16, 0x000b4040, 1},
++	{{0x3400, 0x2000, 0x8100, 0x3700, 0x2000, 0x8100, 0x2f9f, 0x019d, 0x11fa, 0x9f00, 0x0495, 0xd646, 0xed4c, 0x0495, 0xebed, 0x94c0 }, 16, 0x000b4060, 1},
++	{{0xed64, 0xeb68, 0x3044, 0x2a72, 0x800b, 0x0193, 0x4795, 0x3c00, 0xa004, 0x6561, 0x3700, 0x2000, 0x8100, 0xc0ff, 0x3c00, 0xa204 }, 16, 0x000b4080, 1},
++	{{0x6568, 0x6e1f, 0x75d2, 0x27e9, 0x9f1c, 0x98c6, 0x3119, 0x2000, 0xbe00, 0x6d10, 0x94c7, 0xf47a, 0xc2ff, 0x98c0, 0xcf44, 0x32e4 }, 16, 0x000b40a0, 1},
++	{{0x3d62, 0x8001, 0x9ac0, 0x01fa, 0x9f00, 0x90c0, 0x09f8, 0x9eb4, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b40c0, 1},
++	{{0xc2ff, 0x9ac0, 0x19f8, 0x9eb4, 0x6f5f, 0x11fa, 0x9f00, 0xcf4c, 0x4199, 0x4691, 0xe94c, 0x0691, 0xefe9, 0x94c0, 0xef68, 0xe964 }, 16, 0x000b40e0, 1},
++	{{0x3044, 0x2a72, 0x800b, 0x0197, 0x4491, 0x3c00, 0xb004, 0x67e8, 0x75d7, 0x74d6, 0x01fa, 0x9f00, 0x92c2, 0x6d10, 0x94c7, 0x6768 }, 16, 0x000b4100, 1},
++	{{0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10 }, 16, 0x000b4120, 1},
++	{{0x92c3, 0xc2ff, 0x3c40, 0xa004, 0x7451, 0xf2fe, 0x3400, 0x2000, 0x8100, 0x3e00, 0xa803, 0x27ea, 0x9f1c, 0x6568, 0x6461, 0x75d2 }, 16, 0x000b4140, 1},
++	{{0xc0ff, 0x3e00, 0xb800, 0xd640, 0x77d0, 0x3119, 0x2000, 0xbe00, 0xefea, 0x94c6, 0xf47a, 0x6d10, 0x32e4, 0x3d62, 0x8001, 0x92c3 }, 16, 0x000b4160, 1},
++	{{0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3e00, 0xa008, 0x6768, 0x7457, 0x3400 }, 16, 0x000b4180, 1},
++	{{0x2000, 0x8100, 0xeaef, 0x3a00, 0xa010, 0x77d1, 0x74d6, 0x6f00, 0xc598, 0x96c6, 0x75d5, 0x6c10, 0x479a, 0x9ac7, 0x4692, 0x90c0 }, 16, 0x000b41a0, 1},
++	{{0x66e8, 0xc0ff, 0x7754, 0x94c6, 0xea4c, 0x6d10, 0x32e4, 0x3d8c, 0x8001, 0x94c7, 0xefea, 0xc2ff, 0x3620, 0xa000, 0x17f8, 0x9ebc }, 16, 0x000b41c0, 1},
++	{{0x3600, 0xb004, 0x67e8, 0x75d7, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0x7656, 0x64e1, 0xeaef, 0xedef }, 16, 0x000b41e0, 1},
++	{{0x9ac0, 0xd641, 0x3600, 0x2000, 0x8100, 0xed68, 0x2f06, 0x0492, 0x11fa, 0x9f00, 0x0795, 0xea64, 0x0692, 0x3144, 0x2a72, 0x800b }, 16, 0x000b4200, 1},
++	{{0x3a00, 0xb004, 0x67e8, 0x74d7, 0x6f90, 0xc498, 0x90c0, 0x98c7, 0x2618, 0x81a2, 0x90c0, 0xc2ff, 0x92c3, 0xf274, 0x24e9, 0x3200 }, 16, 0x000b4220, 1},
++	{{0x2000, 0x8100, 0x2518, 0x8186, 0x7161, 0x2518, 0x8180, 0x7171, 0x8447, 0x3c00, 0xb000, 0xd4a6, 0x75d7, 0x3000, 0x2000, 0x8001 }, 16, 0x000b4240, 1},
++	{{0x8437, 0x3e00, 0xa002, 0x6c90, 0x04f8, 0x9eb0, 0x67e8, 0x01fa, 0x9f00, 0x94c6, 0xc781, 0x6d10, 0x32e4, 0x3d74, 0x8001, 0x92c3 }, 16, 0x000b4260, 1},
++	{{0xc2ff, 0x3a40, 0xa000, 0x11fa, 0x9f00, 0x64e1, 0xf2fe, 0x96c0, 0xc598, 0x14f8, 0x9eb0, 0x3200, 0x2000, 0x8100, 0x30f2, 0x7551 }, 16, 0x000b4280, 1},
++	{{0x94c6, 0x840f, 0x6e10, 0x3d62, 0x7a41, 0x656a, 0x81fb, 0x3a00, 0xa009, 0x666a, 0x74c1, 0x6e90, 0x75d5, 0x3800, 0xa004, 0x78c1 }, 16, 0x000b42a0, 1},
++	{{0x2718, 0x80c4, 0x9ac0, 0x01fa, 0x9f00, 0x64e8, 0x04f8, 0x9eb0, 0x3846, 0xa000, 0x6c10, 0x01f8, 0x9eac, 0x3a47, 0xa000, 0xc0ff }, 16, 0x000b42c0, 1},
++	{{0x05f8, 0x9ea8, 0x66e8, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3860, 0xa000, 0xf2fe, 0x11f8, 0x9eac, 0x3c20 }, 16, 0x000b42e0, 1},
++	{{0xa000, 0x15f8, 0x9ea8, 0x90c0, 0x01f8, 0x9ea4, 0x3640, 0xa000, 0xcf40, 0xf27e, 0x3800, 0xb004, 0x64e9, 0x75d1, 0xcf48, 0x98c6 }, 16, 0x000b4300, 1},
++	{{0x2418, 0x89ca, 0x90c0, 0x6d10, 0x92c2, 0xf274, 0x3c40, 0xa001, 0x11f8, 0x9ea4, 0x64e8, 0x01f8, 0x9eac, 0x3a46, 0xa000, 0x6d10 }, 16, 0x000b4320, 1},
++	{{0x05f8, 0x9ea8, 0x64e0, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x15f8, 0x9ea8, 0x64e1, 0x11f8, 0x9eac, 0x3a00 }, 16, 0x000b4340, 1},
++	{{0xa084, 0x7ac1, 0x60e0, 0x12f8, 0x9eb0, 0x3600, 0xa808, 0x7175, 0x74c1, 0x81a3, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3e00 }, 16, 0x000b4360, 1},
++	{{0xa200, 0x67e9, 0x6c90, 0x75d1, 0x3000, 0x2000, 0x8001, 0x8031, 0x3a40, 0xa001, 0x01fa, 0x9f00, 0x64e8, 0xf27e, 0x98c6, 0x32e4 }, 16, 0x000b4380, 1},
++	{{0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xf174, 0x3044, 0x23d0, 0x800b, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3a20 }, 16, 0x000b43a0, 1},
++	{{0xa000, 0xf174, 0x3144, 0x23d0, 0x800b, 0x3420, 0xa000, 0xf774, 0x98c0, 0x74d6, 0xf3f4, 0x01fa, 0x9f00, 0x3640, 0xa000, 0x65e8 }, 16, 0x000b43c0, 1},
++	{{0xf27e, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5 }, 16, 0x000b43e0, 1},
++	{{0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a60, 0xa000, 0x7651, 0xf2fe, 0x17f8, 0x9ebc, 0x3e00, 0xa208, 0x6661 }, 16, 0x000b4400, 1},
++	{{0x6568, 0x75d2, 0x3700, 0x2000, 0x8100, 0x3e40, 0xb000, 0x7e41, 0xd7c7, 0x3600, 0x2000, 0x8200, 0xf27e, 0x96c7, 0x6f1f, 0xc2ff }, 16, 0x000b4420, 1},
++	{{0xcf44, 0x96c6, 0x6768, 0x6d10, 0x74d6, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6 }, 16, 0x000b4440, 1},
++	{{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a20, 0xa001, 0x17f8, 0x9ebc, 0x7451, 0xcf4c, 0x3a00, 0xa20c, 0x6461, 0x67e8 }, 16, 0x000b4460, 1},
++	{{0x75d7, 0xcf44, 0x3840, 0xa044, 0x6d83, 0x00f8, 0x9ea0, 0x3a47, 0xa020, 0xc2ff, 0x03f8, 0x9e9c, 0x6ccc, 0x94c6, 0x64e8, 0x6d10 }, 16, 0x000b4480, 1},
++	{{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b44a0, 1},
++	{{0xc2ff, 0x3c20, 0xa000, 0x76d1, 0x74d7, 0xf2fe, 0x27e9, 0x9f1c, 0x3c00, 0xb004, 0x6568, 0x75d2, 0xf57a, 0x09f8, 0x9e98, 0x92c2 }, 16, 0x000b44c0, 1},
++	{{0x6d10, 0x94c7, 0x67e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b44e0, 1},
++	{{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa000, 0x76d1, 0x17f8, 0x9ebc, 0x3800, 0xa204, 0x67e8, 0x66e1, 0x75d7, 0x2c9a, 0x05f8 }, 16, 0x000b4500, 1},
++	{{0x9e94, 0x98c1, 0x64e8, 0x64e8, 0xc2ff, 0x6d10, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3420, 0xa000, 0xc598 }, 16, 0x000b4520, 1},
++	{{0x3600, 0xb004, 0x66e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40, 0xa000, 0x19f8, 0x9e98, 0x64e1 }, 16, 0x000b4540, 1},
++	{{0x17f8, 0x9ebc, 0x3e20, 0xa801, 0x13f8, 0x9e9c, 0x67e8, 0x7cc1, 0x75d7, 0xcf4c, 0x3600, 0xa800, 0x6cac, 0x4199, 0x98c1, 0x64e8 }, 16, 0x000b4560, 1},
++	{{0x64e8, 0xc2ff, 0x6d10, 0x98c6, 0x09f8, 0x9e98, 0x90c0, 0x6c10, 0x32e4, 0x3d62, 0x8001, 0x92c3, 0xc0ff, 0x3420, 0xa000, 0xc598 }, 16, 0x000b4580, 1},
++	{{0x3600, 0xb004, 0x66e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c20, 0xa000, 0x10f8, 0x9ea0, 0x90c0 }, 16, 0x000b45a0, 1},
++	{{0x15f8, 0x9e94, 0x3c00, 0xa020, 0x6d5a, 0x19f8, 0x9e98, 0x6fc3, 0xcf4c, 0x11fa, 0x9f00, 0x34d1, 0x2e57, 0x2564, 0x6f97, 0x3d41 }, 16, 0x000b45c0, 1},
++	{{0x4191, 0xe94c, 0x0491, 0xebe9, 0x94c0, 0xe964, 0xeb68, 0x3044, 0x2a72, 0x800b, 0x0293, 0x4791, 0x3a00, 0xb004, 0x67e8, 0x74d7 }, 16, 0x000b45e0, 1},
++	{{0x6f90, 0xc498, 0x90c0, 0x98c7, 0x2618, 0x81a8, 0x90c0, 0xc2ff, 0x92c3, 0xf274, 0x24e9, 0x3300, 0x2000, 0x8100, 0x2518, 0x818c }, 16, 0x000b4600, 1},
++	{{0x71e1, 0x2518, 0x8186, 0x71f1, 0x8447, 0x3c00, 0xb000, 0xd4a6, 0x75d7, 0x3000, 0x2000, 0x8001, 0x8437, 0x3e00, 0xa002, 0x6c90 }, 16, 0x000b4620, 1},
++	{{0x04f8, 0x9e90, 0x67e8, 0x01fa, 0x9f00, 0x94c6, 0xc781, 0x6d10, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x3a40, 0xa000, 0x11fa }, 16, 0x000b4640, 1},
++	{{0x9f00, 0x64e1, 0xf2fe, 0x96c0, 0xc598, 0x14f8, 0x9e90, 0x3451, 0x3300, 0x2000, 0x8100, 0x70f3, 0x96c6, 0x8411, 0x6e10, 0x90c0 }, 16, 0x000b4660, 1},
++	{{0x3c62, 0x7a41, 0x646a, 0x81fb, 0x3a00, 0xa009, 0x666a, 0x7641, 0x6c10, 0x75d5, 0x3800, 0xa004, 0x7a41, 0x2718, 0x80c8, 0x9ac0 }, 16, 0x000b4680, 1},
++	{{0x01fa, 0x9f00, 0x64e8, 0x04f8, 0x9e90, 0x3846, 0xa000, 0x6c10, 0x04f8, 0x9e8c, 0x3a47, 0xa000, 0xc0ff, 0x00f8, 0x9e88, 0x66e8 }, 16, 0x000b46a0, 1},
++	{{0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3860, 0xa000, 0xf2fe, 0x14f8, 0x9e8c, 0x3c20, 0xa000, 0x10f8, 0x9e88 }, 16, 0x000b46c0, 1},
++	{{0x90c0, 0x01f8, 0x9e84, 0x3840, 0xa000, 0xcf40, 0xf27e, 0x90c0, 0x3600, 0xa004, 0x6669, 0xcf48, 0x98c6, 0x2418, 0x8600, 0x90c0 }, 16, 0x000b46e0, 1},
++	{{0x6d90, 0x3606, 0xb000, 0xf374, 0x75d4, 0x3c40, 0xa001, 0x11f8, 0x9e84, 0x6668, 0x04f8, 0x9e8c, 0x3a46, 0xa000, 0x6d10, 0x00f8 }, 16, 0x000b4700, 1},
++	{{0x9e88, 0x64e0, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x10f8, 0x9e88, 0x64e1, 0x14f8, 0x9e8c, 0x3a00, 0xb004 }, 16, 0x000b4720, 1},
++	{{0x7841, 0x6cc4, 0x13f8, 0x9e90, 0x3600, 0xa808, 0x71f0, 0x7641, 0x81a1, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3e00, 0xa200 }, 16, 0x000b4740, 1},
++	{{0x67e9, 0x6c90, 0x75d4, 0x3000, 0x2000, 0x8001, 0x8031, 0x3a40, 0xa001, 0x01fa, 0x9f00, 0x6668, 0xf27e, 0x98c6, 0x32e4, 0x3d74 }, 16, 0x000b4760, 1},
++	{{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xf174, 0x3044, 0x27ae, 0x800b, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3a20, 0xa000 }, 16, 0x000b4780, 1},
++	{{0xf474, 0x3144, 0x27ae, 0x800b, 0x3420, 0xa000, 0xf774, 0x98c0, 0x74d6, 0xf3f4, 0x01fa, 0x9f00, 0x3640, 0xa000, 0x65e8, 0xf27e }, 16, 0x000b47a0, 1},
++	{{0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6 }, 16, 0x000b47c0, 1},
++	{{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a60, 0xa000, 0x7651, 0xf2fe, 0x17f8, 0x9ebc, 0x3e00, 0xa208, 0x6661, 0x6568 }, 16, 0x000b47e0, 1},
++	{{0x75d2, 0x3700, 0x2000, 0x8100, 0x3e40, 0xb000, 0x7e41, 0xd7c7, 0x3600, 0x2000, 0x8200, 0xf27e, 0x96c7, 0x6f1f, 0xc2ff, 0xcf44 }, 16, 0x000b4800, 1},
++	{{0x96c6, 0x6768, 0x6d10, 0x74d6, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b4820, 1},
++	{{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a20, 0xa001, 0x17f8, 0x9ebc, 0x76d1, 0xcf4c, 0x3a00, 0xa20c, 0x66e1, 0x67e8, 0x75d7 }, 16, 0x000b4840, 1},
++	{{0xcf44, 0x3840, 0xa044, 0x6e5b, 0x05f8, 0x9e80, 0x3a47, 0xa400, 0xc2ff, 0x04f8, 0x9e7c, 0x6cd4, 0x94c6, 0x64e8, 0x6d10, 0x98c6 }, 16, 0x000b4860, 1},
++	{{0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff }, 16, 0x000b4880, 1},
++	{{0x3c20, 0xa000, 0x7451, 0x74d7, 0xf2fe, 0x27ea, 0x9f1c, 0x3c00, 0xb004, 0x6568, 0x75d2, 0xf07a, 0x0af8, 0x9e78, 0x92c2, 0x6d10 }, 16, 0x000b48a0, 1},
++	{{0x94c7, 0x67e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b48c0, 1},
++	{{0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa000, 0x76d1, 0x17f8, 0x9ebc, 0x3800, 0xa204, 0x67e8, 0x66e1, 0x75d7, 0x2cda, 0x05f8, 0x9e74 }, 16, 0x000b48e0, 1},
++	{{0x98c1, 0x64e8, 0x64e8, 0xc2ff, 0x6d10, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3420, 0xa000, 0xc198, 0x3600 }, 16, 0x000b4900, 1},
++	{{0xb004, 0x64e8, 0x75d1, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x17f8, 0x9ebc, 0x64e1, 0x14f8 }, 16, 0x000b4920, 1},
++	{{0x9e7c, 0x3e00, 0xa204, 0x67e8, 0x7cc1, 0x75d7, 0xcf4c, 0x1af8, 0x9e78, 0x3600, 0xa804, 0x6d34, 0x64e1, 0x98c1, 0x64e4, 0x64e4 }, 16, 0x000b4940, 1},
++	{{0xc2ff, 0x6d10, 0x3800, 0xb004, 0x6568, 0x74d2, 0x419a, 0x98c6, 0x0af8, 0x9e78, 0x90c0, 0x6c10, 0x32e4, 0x3d62, 0x8001, 0x92c3 }, 16, 0x000b4960, 1},
++	{{0xc0ff, 0x3420, 0xa000, 0xc198, 0x3600, 0xb004, 0x64e8, 0x75d1, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40 }, 16, 0x000b4980, 1},
++	{{0xa000, 0x1af8, 0x9e78, 0x90c0, 0x15f8, 0x9e80, 0x3a00, 0xa040, 0x6c1b, 0xcf4c, 0x15f8, 0x9e74, 0x2d9a, 0x2f40, 0x2e20, 0x0192 }, 16, 0x000b49a0, 1},
++	{{0x11fa, 0x9f00, 0x3dc1, 0xea4c, 0x0692, 0xebea, 0x94c0, 0xeb68, 0xea64, 0x3044, 0x2a72, 0x800b, 0x0393, 0x4492, 0x98c0, 0x6e90 }, 16, 0x000b49c0, 1},
++	{{0x6f90, 0xc4dc, 0xc098, 0x3a40, 0xa001, 0x27eb, 0x9f1c, 0x7654, 0xf77a, 0x3c00, 0xa804, 0x6c7c, 0x459b, 0x3fc0, 0x2d38, 0x8009 }, 16, 0x000b49e0, 1},
++	{{0x3c00, 0xa800, 0x7654, 0x4593, 0x3300, 0x2000, 0x8100, 0x96c0, 0x6c7d, 0xeb4c, 0xedee, 0x98c0, 0x3902, 0x8024, 0xe9eb, 0x4393 }, 16, 0x000b4a00, 1},
++	{{0x96c0, 0x7d42, 0xeb64, 0xed64, 0x94c0, 0xca42, 0xe968, 0x0791, 0x4793, 0xea1f, 0x1392, 0x3044, 0x2a72, 0x800b, 0x4395, 0x3e40 }, 16, 0x000b4a20, 1},
++	{{0xa004, 0x27ed, 0x9f1c, 0x6c90, 0x6f90, 0x67e4, 0xf77a, 0x3a20, 0xa000, 0x479d, 0x3000, 0x2000, 0x8100, 0x0195, 0x3398, 0x2f5c }, 16, 0x000b4a40, 1},
++	{{0xbf02, 0xed4c, 0x0095, 0xe9ed, 0x94c0, 0xe968, 0xed64, 0x0391, 0x4795, 0x3880, 0xa000, 0x5411, 0x27ec, 0x9f2c, 0x9ac0, 0xd22f }, 16, 0x000b4a60, 1},
++	{{0x5394, 0x3000, 0x2000, 0x8001, 0x96c0, 0x7dc1, 0x2518, 0x8248, 0x25e1, 0x6c90, 0x65e8, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10 }, 16, 0x000b4a80, 1},
++	{{0x92c3, 0xc2ff, 0x3751, 0xf3fa, 0x25e8, 0x6761, 0x94c6, 0x74d6, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b4aa0, 1},
++	{{0x6c10, 0x92c3, 0xc0ff, 0xc798, 0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0x75d1, 0x74d6 }, 16, 0x000b4ac0, 1},
++	{{0x27ec, 0x9f2c, 0x94c0, 0xeaec, 0xf37a, 0xea70, 0x1392, 0x0af8, 0x9e70, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6 }, 16, 0x000b4ae0, 1},
++	{{0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9cc0 }, 16, 0x000b4b00, 1},
++	{{0x76d1, 0x1af8, 0x9e70, 0x74d6, 0x27ec, 0x9f2c, 0xe9ec, 0x0592, 0xe96c, 0x1391, 0x09f8, 0x9e6c, 0x65e8, 0x92c2, 0x6d10, 0x94c7 }, 16, 0x000b4b20, 1},
++	{{0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10 }, 16, 0x000b4b40, 1},
++	{{0x92c3, 0xc2ff, 0x9cc0, 0x7651, 0x19f8, 0x9e6c, 0x74d6, 0x27ec, 0x9f2c, 0xedec, 0x0491, 0xed68, 0x1395, 0x0df8, 0x9e68, 0x65e8 }, 16, 0x000b4b60, 1},
++	{{0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6, 0x32e4 }, 16, 0x000b4b80, 1},
++	{{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9cc0, 0x76d1, 0x1df8, 0x9e68, 0x74d6, 0x27ec, 0x9f2c, 0xefec, 0x0595, 0xef64, 0x5397 }, 16, 0x000b4ba0, 1},
++	{{0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6 }, 16, 0x000b4bc0, 1},
++	{{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0x7651, 0x74d6, 0x27ec, 0x9f2c, 0x4497, 0x5394, 0x65e8, 0x92c2, 0x6d10 }, 16, 0x000b4be0, 1},
++	{{0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b4c00, 1},
++	{{0x6d10, 0x92c3, 0xc2ff, 0x96c0, 0xc786, 0x27ec, 0x9f2c, 0x96c0, 0x4194, 0x27eb, 0x9f18, 0x1393, 0x3101, 0x2000, 0x8020, 0x25e8 }, 16, 0x000b4c20, 1},
++	{{0xcb4e, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10, 0x94c7, 0x6c10, 0xc2ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10 }, 16, 0x000b4c40, 1},
++	{{0x92c3, 0xc2ff, 0x3be1, 0xcb46, 0x67ea, 0x94c0, 0x419b, 0x81cd, 0x9ac0, 0x1af8, 0x9e70, 0x90c0, 0x19f8, 0x9e6c, 0x96c0, 0xcba8 }, 16, 0x000b4c60, 1},
++	{{0x1df8, 0x9e68, 0x3660, 0xa000, 0xcda4, 0xcaa0, 0x94c0, 0xf8ff, 0xecee, 0x3680, 0xa100, 0xeeee, 0xefee, 0x1292, 0xf0fa, 0x3c47 }, 16, 0x000b4c80, 1},
++	{{0x3d47, 0x1791, 0x5395, 0x3a00, 0xa100, 0x7dc7, 0x7fc7, 0x5697, 0xee3b, 0x38e0, 0xa000, 0x7f47, 0xec3d, 0xef3a, 0x0090, 0xee7c }, 16, 0x000b4ca0, 1},
++	{{0x3680, 0xa000, 0x4296, 0x4794, 0x3680, 0xa000, 0x4397, 0x4696, 0x96c0, 0x6c10, 0x27ec, 0x9e68, 0xe7ec, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000b4cc0, 1},
++	{{0x94c0, 0x9621, 0x9721, 0x9f71, 0x3044, 0x23d0, 0x800b, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3044, 0x27ae, 0x800b, 0x3820 }, 16, 0x000b4ce0, 1},
++	{{0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x5510 }, 16, 0x000b4d00, 1},
++	{{0x270a, 0x8030, 0x26e9, 0xe7ea, 0x98c6, 0x2518, 0x829c, 0x90c0, 0x6c10, 0x98c0, 0xf6d3, 0x3ac0, 0x2e80, 0x8009, 0x9ac0, 0x3616 }, 16, 0x000b4d20, 1},
++	{{0x8040, 0xc788, 0x280c, 0x8004, 0x9ac0, 0x280e, 0x802c, 0x90c0, 0x2718, 0x812a, 0x3680, 0xa100, 0xedea, 0xebea, 0x3680, 0xa100 }, 16, 0x000b4d40, 1},
++	{{0xe8ea, 0xed64, 0x3680, 0xa100, 0xeb68, 0xe86c, 0x9ac0, 0x280f, 0x801c, 0x90c0, 0x280b, 0x8036, 0x3820, 0xa000, 0xfd41, 0x280d }, 16, 0x000b4d60, 1},
++	{{0x8038, 0x3660, 0xa000, 0xfb42, 0xf843, 0x1315, 0x5213, 0xd1a1, 0x84a1, 0x9ac0, 0xd129, 0x38c0, 0x2e80, 0x8009, 0x5096, 0x3620 }, 16, 0x000b4d80, 1},
++	{{0xa000, 0xfbc1, 0x8051, 0x3620, 0xa000, 0xffc2, 0x4610, 0x3600, 0xa100, 0xfac3, 0x4f93, 0x3680, 0xa000, 0x4c97, 0xf944, 0x0992 }, 16, 0x000b4da0, 1},
++	{{0x38c0, 0x2e70, 0x8009, 0x94c0, 0xfc45, 0xfb46, 0x3284, 0x38cc, 0x800b, 0x98c0, 0xfd47, 0x09c2, 0x2e70, 0x8009, 0x94c0, 0xf9c4 }, 16, 0x000b4dc0, 1},
++	{{0xfcc5, 0x3044, 0x2e30, 0x800b, 0x94c0, 0xfbc6, 0xfdc7, 0x98c0, 0x676a, 0x76d6, 0xeae9, 0xe8e9, 0x96c0, 0x7ae1, 0x5158, 0x8439 }, 16, 0x000b4de0, 1},
++	{{0x98c0, 0x61f4, 0x9b45, 0x2b03, 0x8014, 0x6df4, 0x96c0, 0x7dc8, 0x2103, 0x801c, 0x25e5, 0x5158, 0x22f4, 0x7dc8, 0x94d0, 0x6ef4 }, 16, 0x000b4e00, 1},
++	{{0x75db, 0x35d5, 0x435a, 0x7dc8, 0x65e5, 0x7dc8, 0x75db, 0x4352, 0x90c0, 0x9ac0, 0x2f0f, 0x8038, 0x7be1, 0x2d0d, 0x8038, 0x9ac0 }, 16, 0x000b4e20, 1},
++	{{0x2b0b, 0x8038, 0x67ea, 0x2e0e, 0x8038, 0x96c0, 0x8141, 0x2c0c, 0x8038, 0x3a20, 0xa000, 0xf8c3, 0x31c1, 0x2c38, 0x8009, 0x90c0 }, 16, 0x000b4e40, 1},
++	{{0x3a80, 0xa000, 0x4190, 0x3044, 0x2fc2, 0x800b, 0x01c2, 0x2e70, 0x8009, 0x9ac0, 0x676a, 0xede9, 0x3bc0, 0x2c38, 0x8009, 0x840f }, 16, 0x000b4e60, 1},
++	{{0x9f46, 0x90c0, 0x90c0, 0x92d0, 0x505d, 0x409b, 0x98c0, 0x3bc0, 0x2e80, 0x8009, 0xf944, 0x96c0, 0xc788, 0x280f, 0x8004, 0x3600 }, 16, 0x000b4e80, 1},
++	{{0xa100, 0xeceb, 0xedeb, 0x3880, 0xa000, 0xed68, 0x2f0e, 0x8018, 0x96c0, 0xec64, 0x2e0a, 0x801a, 0x96c0, 0xf848, 0x2a0d, 0x8002 }, 16, 0x000b4ea0, 1},
++	{{0x3640, 0xa000, 0xfc49, 0xfd4a, 0x1315, 0x3bc0, 0x2e80, 0x8009, 0x1312, 0xd1a1, 0x94c0, 0xfcca, 0x8435, 0x96c0, 0xd1a9, 0xfa4b }, 16, 0x000b4ec0, 1},
++	{{0xfd4c, 0x90c0, 0x94c7, 0xfbc9, 0x4613, 0x96c3, 0x38c0, 0x2e70, 0x8009, 0x98c3, 0x4e93, 0x3284, 0x3a18, 0x800b, 0x92c3, 0x4f94 }, 16, 0x000b4ee0, 1},
++	{{0x94c0, 0xfacb, 0xfdcc, 0x90c0, 0x9ac0, 0x2e0e, 0x8038, 0x7be1, 0x2d0d, 0x8038, 0x9ac0, 0x2a0a, 0x8038, 0x67ea, 0x2f0f, 0x8038 }, 16, 0x000b4f00, 1},
++	{{0x81a9, 0x96c0, 0x676a, 0xf9c4, 0xf8c8, 0x8417, 0x9f46, 0x98c0, 0x3bc0, 0x2c38, 0x8009, 0xede9, 0x90c0, 0x92d0, 0x559b, 0x455d }, 16, 0x000b4f20, 1},
++	{{0x98c0, 0x2808, 0x802c, 0x7556, 0x9248, 0x9ac0, 0x2a03, 0x801c, 0x90c0, 0x2b03, 0x804c, 0x9ac0, 0x280a, 0x800a, 0x90c0, 0x2b02 }, 16, 0x000b4f40, 1},
++	{{0x801c, 0x2a0d, 0x8002, 0x143d, 0x5112, 0xd221, 0x8447, 0x1090, 0xd0a9, 0x8441, 0x96c0, 0x676a, 0xeee9, 0xece9, 0x94c6, 0x8437 }, 16, 0x000b4f60, 1},
++	{{0x7961, 0x96c0, 0x7941, 0x515c, 0x9b42, 0x6274, 0x6e74, 0x96c0, 0x7e48, 0x2103, 0x801c, 0x2665, 0x515c, 0x22f4, 0x7e48, 0x94d0 }, 16, 0x000b4f80, 1},
++	{{0x6ef4, 0x765c, 0x3655, 0x445e, 0x7e48, 0x6665, 0x7e48, 0x765c, 0x4456, 0x9ad0, 0x2a0a, 0x8038, 0x90c0, 0x2808, 0x8038, 0x90c0 }, 16, 0x000b4fa0, 1},
++	{{0x90c0, 0x6c10, 0x27ec, 0x9fd0, 0xe7ec, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b4fc0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xcba6, 0x270d, 0x8040, 0x3640, 0xa000, 0xe7ed, 0xc9ae, 0x96c0, 0xcaa2 }, 16, 0x000b4fe0, 1},
++	{{0x280d, 0x8004, 0x3800, 0xa100, 0xccaa, 0x2d0e, 0x8018, 0x3840, 0xa100, 0x5311, 0x2e0f, 0x801a, 0x36e0, 0xa000, 0xecef, 0xefef }, 16, 0x000b5000, 1},
++	{{0x36c0, 0xa100, 0xec3b, 0xedef, 0x3660, 0xa100, 0xebef, 0xebef, 0x3660, 0xa100, 0xeb39, 0xeaef, 0x3620, 0xa000, 0xeeef, 0xef3a }, 16, 0x000b5020, 1},
++	{{0x36a0, 0xa100, 0xe8ef, 0xed3c, 0x94c0, 0xe944, 0xf341, 0x94c0, 0xc781, 0xc688, 0x94c0, 0xeaed, 0xeced, 0x3680, 0xa100, 0xe862 }, 16, 0x000b5040, 1},
++	{{0xea64, 0x36a0, 0xa100, 0xe939, 0xeb66, 0x98c0, 0xee7e, 0x3110, 0x2000, 0x8000, 0x94c0, 0xf842, 0xfd43, 0xfb44, 0x5319, 0x1519 }, 16, 0x000b5060, 1},
++	{{0xd1af, 0x3620, 0xa000, 0x5319, 0x8470, 0x5219, 0x94c0, 0xf8d7, 0xfdc4, 0x90c0, 0x3420, 0xa000, 0x5598, 0x3400, 0xa004, 0x7ee3 }, 16, 0x000b5080, 1},
++	{{0x3420, 0xa000, 0x4594, 0x3420, 0xa000, 0x5198, 0x3400, 0xa004, 0x7ce3, 0x3420, 0xa000, 0x4195, 0x3420, 0xa000, 0x5498, 0x3400 }, 16, 0x000b50a0, 1},
++	{{0xa004, 0x7e63, 0x34a0, 0xa000, 0x4495, 0x3420, 0xa000, 0x5698, 0x3400, 0xa004, 0x7f63, 0x34a0, 0xa000, 0x4694, 0x3420, 0xa000 }, 16, 0x000b50c0, 1},
++	{{0x5098, 0x3600, 0xa004, 0x7c63, 0xf857, 0x3420, 0xa000, 0x4097, 0x4196, 0x3600, 0xa100, 0x6e10, 0x4513, 0x36a0, 0xa000, 0x4312 }, 16, 0x000b50e0, 1},
++	{{0x9742, 0x3880, 0xa000, 0x4210, 0x2b02, 0x8002, 0x38c0, 0xa000, 0x4317, 0x2e0b, 0x8004, 0x3420, 0xa000, 0xedee, 0x94c8, 0x44bd }, 16, 0x000b5100, 1},
++	{{0x44bb, 0x94c0, 0xe8ea, 0xf945, 0x94c0, 0xfa46, 0xfc47, 0x3660, 0xa000, 0xfe48, 0xff49, 0x3660, 0xa000, 0xf84a, 0xfa4b, 0x3660 }, 16, 0x000b5120, 1},
++	{{0xa000, 0xfb4c, 0xf94d, 0x3224, 0x30d0, 0x800b, 0x3660, 0xa000, 0xfc4e, 0xfd4f, 0x3a40, 0xa000, 0x7577, 0x6e90, 0xf3c1, 0xfdcf }, 16, 0x000b5140, 1},
++	{{0x3860, 0xa000, 0xdd03, 0xf8ca, 0xf9cd, 0x3860, 0xa000, 0x6569, 0xfec8, 0xffc9, 0x94c0, 0xfac6, 0xfcc7, 0x3640, 0xa000, 0xf9c5 }, 16, 0x000b5160, 1},
++	{{0xfacb, 0x3660, 0xa000, 0xfbcc, 0xfcce, 0x8048, 0x98c0, 0x3110, 0x2000, 0x8000, 0xc081, 0x3640, 0xa000, 0xf8c3, 0xede9, 0x96c0 }, 16, 0x000b5180, 1},
++	{{0x9348, 0x2b03, 0x801c, 0x96c0, 0xed18, 0x280b, 0x8034, 0x96c0, 0xf8c2, 0x2d0d, 0x8034, 0x4015, 0x4510, 0x5513, 0x7065, 0x90c0 }, 16, 0x000b51a0, 1},
++	{{0x96c2, 0x4010, 0x2003, 0x808c, 0x94d0, 0x2b0b, 0x8038, 0x90c0, 0x90c0, 0x3c40, 0xa100, 0x7b61, 0x7fc1, 0xfdc4, 0x2d0d, 0x8038 }, 16, 0x000b51c0, 1},
++	{{0x3ca0, 0xa000, 0x2c0c, 0x8038, 0x676a, 0x2f0f, 0x8038, 0x9ac0, 0x2d0d, 0x8038, 0x90c0, 0x2e0e, 0x8038, 0x96c0, 0xfd44, 0x2c0c }, 16, 0x000b51e0, 1},
++	{{0x8038, 0x3ce0, 0xa100, 0x2909, 0x8038, 0x90c0, 0x2b0b, 0x8038, 0x3ce0, 0xa100, 0x2a0a, 0x8038, 0x90c0, 0x2808, 0x8038, 0x9ac0 }, 16, 0x000b5200, 1},
++	{{0x2a0a, 0x8038, 0x90c0, 0x2cff, 0x9e5f, 0x3ce0, 0xa100, 0x2f0f, 0x8038, 0x90c0, 0x2e0e, 0x8038, 0x27ec, 0x9fc0, 0xe7ec, 0x94c0 }, 16, 0x000b5220, 1},
++	{{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x3144, 0x31d2, 0x800b, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b5240, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b5260, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b5280, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b52a0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0xc941, 0xc840, 0x94c0, 0xc848 }, 16, 0x000b52c0, 1},
++	{{0xc949, 0x9ac0, 0x3604, 0x8001, 0x90c0, 0x3405, 0x8001, 0x96c0, 0x7e78, 0x3005, 0x8001, 0x3ee8, 0x6331, 0x2fd5, 0x7f47, 0x6c5f }, 16, 0x000b52e0, 1},
++	{{0xc840, 0x90c0, 0x94c0, 0x9621, 0x9721, 0x94c0, 0xc848, 0x9f71, 0x9ac0, 0x3318, 0x807f, 0xc598, 0x32cc, 0x80c7, 0x9cc0, 0x3e70 }, 16, 0x000b5300, 1},
++	{{0x8000, 0x74f4, 0x75d5, 0x9620, 0x9720, 0x9cc0, 0x7c48, 0x64e8, 0x3200, 0x200c, 0x9800, 0xc84e, 0x6461, 0x94c7, 0x6fb2, 0xc0ff }, 16, 0x000b5320, 1},
++	{{0x94c6, 0x66e8, 0x6c10, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3451, 0x3100, 0x2003, 0x8600, 0x3244, 0x32d0 }, 16, 0x000b5340, 1},
++	{{0x800b, 0x6461, 0x9ac0, 0x6464, 0x3418, 0x200f, 0xa200, 0xc846, 0x7270, 0x98c7, 0x280a, 0x8048, 0x90c0, 0x6e10, 0x92c3, 0x6c7d }, 16, 0x000b5360, 1},
++	{{0x96c0, 0x6dd7, 0x9621, 0x9721, 0x9f70, 0x4392, 0x90c0, 0x90c0, 0x9ac0, 0x2809, 0x8048, 0x90c0, 0x331d, 0x8f00, 0x3ee8, 0x3200 }, 16, 0x000b5380, 1},
++	{{0x2001, 0x8300, 0x9ac0, 0x3644, 0x8005, 0x90c0, 0x3442, 0x8005, 0x98c0, 0xd812, 0x3300, 0x200c, 0x9800, 0xd444, 0x6461, 0x94c0 }, 16, 0x000b53a0, 1},
++	{{0x6c33, 0x9f70, 0x4091, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0xf4c3, 0xd623, 0x92c3, 0x7cd8, 0x96c3, 0xcc44, 0x280b, 0x8048 }, 16, 0x000b53c0, 1},
++	{{0x90c0, 0x92c3, 0xecfe, 0x94c7, 0x9f70, 0xec1b, 0x92c3, 0x4194, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b53e0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6469, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b5400, 1},
++	{{0x2418, 0x817a, 0x98c6, 0xe758, 0x3000, 0x2000, 0x8100, 0x98c0, 0x38c0, 0x3608, 0x8009, 0x9744, 0x27ef, 0x9fe8, 0x5798, 0x94c8 }, 16, 0x000b5420, 1},
++	{{0x479f, 0x5798, 0x32e4, 0x3c48, 0x8001, 0x0797, 0x30d8, 0x2cce, 0xbdcc, 0x2468, 0x34d0, 0xc498, 0x94c6, 0x75d4, 0x6c10, 0x94c7 }, 16, 0x000b5440, 1},
++	{{0x6668, 0xc0ff, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10 }, 16, 0x000b5460, 1},
++	{{0x92c3, 0xc2ff, 0x3551, 0x3140, 0x3477, 0x8171, 0x6561, 0x6569, 0x2418, 0x8102, 0x96c2, 0x3000, 0x2000, 0x8100, 0x2568, 0x3452 }, 16, 0x000b5480, 1},
++	{{0x3244, 0x32d0, 0x800b, 0x92c3, 0x6464, 0x2568, 0x3100, 0x2000, 0x8080, 0x98c0, 0xd441, 0x3160, 0x3218, 0x80b1, 0x31ee, 0x9f00 }, 16, 0x000b54a0, 1},
++	{{0x98c7, 0x3244, 0x32d0, 0x800b, 0x6764, 0x7456, 0x2f92, 0x3244, 0x32d0, 0x800b, 0x34d7, 0x7457, 0x96c0, 0x7550, 0x27ef, 0x9ff8 }, 16, 0x000b54c0, 1},
++	{{0x3244, 0x32d0, 0x800b, 0x5197, 0x3650, 0x3452, 0xe8ef, 0xe864, 0x1590, 0x3244, 0x32d0, 0x800b, 0x6cd5, 0x34d0, 0x3452, 0xeeef }, 16, 0x000b54e0, 1},
++	{{0xee68, 0x1396, 0x3244, 0x32d0, 0x800b, 0x6cd9, 0x36d0, 0x3452, 0xef6c, 0x1397, 0x3244, 0x32d0, 0x800b, 0x6ccd, 0x9cc0, 0x7650 }, 16, 0x000b5500, 1},
++	{{0x7452, 0xf1c6, 0x3244, 0x32d0, 0x800b, 0x6cc4, 0x35d0, 0x3457, 0x3100, 0x2000, 0x8200, 0x3244, 0x32d0, 0x800b, 0x6d59, 0x2468 }, 16, 0x000b5520, 1},
++	{{0x2fab, 0x34d0, 0xc498, 0x94c6, 0x75d4, 0x6c10, 0x94c7, 0x6668, 0xc0ff, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff }, 16, 0x000b5540, 1},
++	{{0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x2768, 0x24e1, 0x3000, 0x2000, 0x8100, 0x94c7, 0x6cd1 }, 16, 0x000b5560, 1},
++	{{0x6764, 0x7f78, 0x94c1, 0xd41e, 0xd416, 0x3244, 0x32d0, 0x800b, 0x6461, 0x3500, 0x2000, 0x8100, 0x6c01, 0xe778, 0x94c0, 0x9e21 }, 16, 0x000b5580, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x57d1 }, 16, 0x000b55a0, 1},
++	{{0x270d, 0x8020, 0xe7ed, 0x94c0, 0xf841, 0xf0cf, 0x96c0, 0xfbc1, 0x2908, 0x8002, 0x94c0, 0xc250, 0xf042, 0x3800, 0xa100, 0x4793 }, 16, 0x000b55c0, 1},
++	{{0x2b0c, 0x8004, 0x3840, 0xa000, 0x5110, 0x2c0e, 0x8002, 0x38c0, 0xa000, 0x4114, 0x2a0d, 0x8002, 0x5710, 0x0716, 0xc84f, 0xee46 }, 16, 0x000b55e0, 1},
++	{{0x499e, 0x96c0, 0x4096, 0x2e0c, 0x804c, 0x1415, 0xed42, 0x9ac0, 0x2e0a, 0x8050, 0x7e51, 0x2e0b, 0x8008, 0x4494, 0x3480, 0xa000 }, 16, 0x000b5600, 1},
++	{{0x5114, 0x3319, 0x8010, 0x24e9, 0x5115, 0x94c0, 0x7cc9, 0x80b1, 0x4192, 0x00c6, 0x3638, 0x8009, 0x06c6, 0x3628, 0x8009, 0x3244 }, 16, 0x000b5620, 1},
++	{{0x32d0, 0x800b, 0x6c22, 0x96c0, 0x6dc2, 0x2e0f, 0x8034, 0x0397, 0x3400, 0x2000, 0x8100, 0x1592, 0x01c6, 0x3634, 0x8009, 0x02c6 }, 16, 0x000b5640, 1},
++	{{0x3630, 0x8009, 0x2c38, 0x3244, 0x32d0, 0x800b, 0x6cb5, 0x1294, 0xc9b0, 0x96c0, 0x6c3d, 0xebef, 0xc847, 0x94c0, 0xeb39, 0xc298 }, 16, 0x000b5660, 1},
++	{{0x35d2, 0x0093, 0xc481, 0x1197, 0x06c6, 0x363c, 0x8009, 0x70f6, 0x8435, 0x64e8, 0x92c2, 0x6c10, 0x94c7, 0x6568, 0xc0ff, 0x98c6 }, 16, 0x000b5680, 1},
++	{{0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3651 }, 16, 0x000b56a0, 1},
++	{{0xc847, 0x6661, 0x3000, 0x2010, 0xa000, 0x96c0, 0x6c7d, 0x2e0c, 0x8008, 0x0494, 0x3144, 0x3706, 0x800b, 0x9ac0, 0x280d, 0x8006 }, 16, 0x000b56c0, 1},
++	{{0x90c0, 0x2e0a, 0x8004, 0x96c0, 0x5115, 0x2d0f, 0x8002, 0x98c0, 0x7cd1, 0xed64, 0x2e0c, 0x8034, 0x4192, 0x5017, 0x7c51, 0x4093 }, 16, 0x000b56e0, 1},
++	{{0x5515, 0x7ed1, 0x4594, 0x98c0, 0x6e10, 0xe84a, 0x2e0d, 0x800c, 0x96c0, 0x5510, 0x2809, 0x8002, 0x3c00, 0xa100, 0x2e0a, 0x8010 }, 16, 0x000b5700, 1},
++	{{0x7ece, 0x280b, 0x8004, 0x96c0, 0x4595, 0x2e0b, 0x8014, 0x3800, 0xa100, 0x5711, 0x280a, 0x8006, 0x9ac0, 0x2e0c, 0x8018, 0x7fce }, 16, 0x000b5720, 1},
++	{{0x2809, 0x8008, 0x3800, 0xa100, 0x4792, 0x2e08, 0x801c, 0x3880, 0xa000, 0x5013, 0x280f, 0x800a, 0x3c80, 0xa100, 0x2e09, 0x8020 }, 16, 0x000b5740, 1},
++	{{0x7c51, 0x280c, 0x800c, 0x3800, 0xa100, 0x4093, 0x2e0e, 0x8024, 0x3880, 0xa100, 0x5012, 0x280f, 0x8010, 0x3c80, 0xa100, 0x2e0d }, 16, 0x000b5760, 1},
++	{{0x8028, 0x7c51, 0x280b, 0x8012, 0x3800, 0xa100, 0x4094, 0x2e0a, 0x802c, 0x1511, 0xe84e, 0x3860, 0xa000, 0x7ece, 0xfa45, 0xf943 }, 16, 0x000b5780, 1},
++	{{0x3680, 0xa000, 0x4590, 0xf9c1, 0x96c0, 0x5717, 0x2e0f, 0x8030, 0x3640, 0xa000, 0x7fce, 0xfd44, 0x3680, 0xa000, 0x4791, 0x9742 }, 16, 0x000b57a0, 1},
++	{{0x36c0, 0xa100, 0x5714, 0xecea, 0x3ac0, 0xa000, 0x7fd1, 0xfac2, 0x2e09, 0x8048, 0x3680, 0xa000, 0x4796, 0xc081, 0x3880, 0xa000 }, 16, 0x000b57c0, 1},
++	{{0x5117, 0x2b02, 0x8002, 0x7cce, 0x3480, 0xa000, 0x4195, 0x38c0, 0xa100, 0x5213, 0x290d, 0x8040, 0x7d4e, 0x3480, 0xa000, 0x4294 }, 16, 0x000b57e0, 1},
++	{{0x96c0, 0x5210, 0x2908, 0x8048, 0x96c0, 0x7d51, 0x2909, 0x804c, 0x4297, 0x3480, 0xa000, 0x5312, 0x7dd1, 0x3480, 0xa000, 0x4391 }, 16, 0x000b5800, 1},
++	{{0x3480, 0xa000, 0x4095, 0x94c8, 0x44b8, 0x44b9, 0x3680, 0xa000, 0x2e0d, 0x8004, 0x3a80, 0xa000, 0x5195, 0x3510, 0x2029, 0xae00 }, 16, 0x000b5820, 1},
++	{{0x72f1, 0x800b, 0x64ea, 0x94c6, 0xd2d9, 0x6e90, 0x3880, 0xa100, 0x4595, 0x2e0f, 0x8008, 0x3a80, 0xa000, 0x5597, 0x3100, 0x2000 }, 16, 0x000b5840, 1},
++	{{0x8100, 0x70f5, 0x800d, 0x3100, 0x2014, 0xa800, 0x72f1, 0xd0dd, 0x3a80, 0xa000, 0x4197, 0x3700, 0x2005, 0x8a00, 0x5495, 0x2668 }, 16, 0x000b5860, 1},
++	{{0x7454, 0x94c7, 0x840b, 0x6e10, 0x7077, 0xd257, 0x0495, 0x3000, 0x2005, 0x8a00, 0x5492, 0x2668, 0x76d4, 0x94c7, 0x840b, 0x6e10 }, 16, 0x000b5880, 1},
++	{{0x72f0, 0xd250, 0x0492, 0x3310, 0x2029, 0xae00, 0x3480, 0xa000, 0x5496, 0x71f4, 0x800b, 0x666a, 0x94c6, 0xd1dc, 0x6d90, 0x3a80 }, 16, 0x000b58a0, 1},
++	{{0xa000, 0x4396, 0x3500, 0x2000, 0x8100, 0x5097, 0x72f0, 0x800d, 0x3500, 0x2014, 0xa800, 0x7075, 0xd2d8, 0x3620, 0xa000, 0xfdc4 }, 16, 0x000b58c0, 1},
++	{{0x4597, 0x3000, 0x2005, 0x8a00, 0x3480, 0xa000, 0x5595, 0x26e8, 0x7755, 0x94c7, 0x840b, 0x6e90, 0x7370, 0xd2d0, 0x36c0, 0xa100 }, 16, 0x000b58e0, 1},
++	{{0x4595, 0xeaec, 0x3a80, 0xa000, 0x5392, 0x3400, 0x2005, 0x8a00, 0x25e8, 0x76d3, 0x94c7, 0x840b, 0x6d90, 0x72f4, 0xd1d4, 0x3a80 }, 16, 0x000b5900, 1},
++	{{0xa000, 0x4392, 0x3210, 0x2029, 0xae00, 0x5593, 0x7175, 0x800b, 0x66ea, 0x94c6, 0xd15d, 0x6d10, 0x0293, 0x3400, 0x2000, 0x8100 }, 16, 0x000b5920, 1},
++	{{0x5794, 0x7277, 0x800d, 0x3400, 0x2004, 0x8800, 0x73f4, 0xd25f, 0x0494, 0x3700, 0x2005, 0x8a00, 0x3480, 0xa000, 0x5390, 0x25e8 }, 16, 0x000b5940, 1},
++	{{0x7653, 0x94c7, 0x840b, 0x6d90, 0x7277, 0xd1d7, 0x3600, 0xa100, 0xfbc3, 0x4390, 0x3700, 0x2005, 0x8a00, 0x5693, 0x2768, 0x7456 }, 16, 0x000b5960, 1},
++	{{0x94c7, 0x840b, 0x6f10, 0x7077, 0xd357, 0x96c0, 0x4693, 0x2e08, 0x8034, 0x1490, 0xf846, 0x2668, 0x3754, 0x3500, 0x201e, 0xbc00 }, 16, 0x000b5980, 1},
++	{{0x94c7, 0x840b, 0x6e10, 0x7375, 0xd255, 0x0490, 0x3210, 0x2029, 0xae00, 0x3480, 0xa000, 0x5591, 0x7175, 0x800b, 0x66ea, 0x94c6 }, 16, 0x000b59a0, 1},
++	{{0xd15d, 0x6d10, 0x3600, 0xa100, 0xf9c1, 0x4291, 0x3640, 0xa000, 0x5095, 0xff47, 0x98c0, 0xca4e, 0x3244, 0x3410, 0x800b, 0x1191 }, 16, 0x000b59c0, 1},
++	{{0xc05f, 0x94c0, 0xf9c1, 0xca46, 0x2e0c, 0x8054, 0x0094, 0xfc48, 0x3244, 0x3410, 0x800b, 0x1191, 0x5092, 0x94c0, 0xfcc8, 0xf9c1 }, 16, 0x000b59e0, 1},
++	{{0xc057, 0xec44, 0x0094, 0xfc48, 0x3244, 0x3410, 0x800b, 0x3680, 0xa000, 0x5090, 0x5191, 0x94c0, 0xfcc8, 0xf9c1, 0xfbc3, 0xec48 }, 16, 0x000b5a00, 1},
++	{{0x0094, 0xfc48, 0x3244, 0x3410, 0x800b, 0x1093, 0x5191, 0x94c0, 0xfcc8, 0xf9c1, 0x3420, 0xa000, 0xfdc4, 0xec44, 0x0094, 0xfc48 }, 16, 0x000b5a20, 1},
++	{{0x3244, 0x3410, 0x800b, 0x3680, 0xa000, 0x5095, 0x5191, 0x94c0, 0xfcc8, 0xf9c1, 0x3420, 0xa000, 0xfac5, 0xec44, 0x0094, 0xfc48 }, 16, 0x000b5a40, 1},
++	{{0x3244, 0x3410, 0x800b, 0x3680, 0xa000, 0x5092, 0x5191, 0x3820, 0xa000, 0x6c90, 0xfcc8, 0xffc7, 0x3700, 0x2000, 0x8100, 0xec44 }, 16, 0x000b5a60, 1},
++	{{0x0094, 0x3000, 0x2000, 0x8001, 0xec48, 0x0794, 0xedec, 0x3680, 0xa000, 0x5397, 0xfc48, 0x25e8, 0xed78, 0x94c6, 0xcd4e, 0x6d10 }, 16, 0x000b5a80, 1},
++	{{0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x9ac0, 0x64e1, 0xcd46, 0x3600, 0x2000, 0x8100, 0x9ac0, 0x6c86, 0xfcc8, 0x3000, 0x2000 }, 16, 0x000b5aa0, 1},
++	{{0x8001, 0x2c90, 0x4195, 0x1397, 0xebec, 0x25e8, 0xeb64, 0x94c6, 0xcb4f, 0x6d10, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x9cc0 }, 16, 0x000b5ac0, 1},
++	{{0x64e1, 0x6d90, 0x6c10, 0xcb47, 0x2102, 0x8408, 0x9ac0, 0x6f86, 0x2e0d, 0x84a8, 0x6d10, 0xfcc8, 0x0793, 0xeaed, 0x3680, 0xa000 }, 16, 0x000b5ae0, 1},
++	{{0xe8ed, 0x4395, 0x3680, 0xa000, 0xeeed, 0xea68, 0x36a0, 0xa100, 0xe839, 0xee64, 0x3620, 0xa000, 0x4892, 0xed50, 0x3680, 0xa000 }, 16, 0x000b5b00, 1},
++	{{0x4a96, 0xebed, 0x96c0, 0x4395, 0x2c0c, 0x8024, 0x96c0, 0x4394, 0x2702, 0x841c, 0x94c0, 0xefed, 0xeb6c, 0x0393, 0xef68, 0x98c0 }, 16, 0x000b5b20, 1},
++	{{0x10c0, 0x362c, 0x8009, 0xf9c1, 0x009f, 0x03c6, 0x362c, 0x8009, 0x2704, 0x8080, 0x0397, 0x3710, 0x2000, 0x8000, 0x3820, 0xa000 }, 16, 0x000b5b40, 1},
++	{{0xed3f, 0x2b02, 0x8002, 0x96c0, 0x4795, 0x290a, 0x80b4, 0x3688, 0xa000, 0x42b8, 0x42ba, 0x98c0, 0x2e0a, 0x84bc, 0x6c10, 0xf8c6 }, 16, 0x000b5b60, 1},
++	{{0x029a, 0x31e0, 0x2148, 0x80fa, 0x96c0, 0x429a, 0x2c00, 0x8080, 0x96c0, 0x419a, 0x2e0b, 0x8078, 0x0092, 0x5590, 0x0593, 0xea4c }, 16, 0x000b5b80, 1},
++	{{0x96c0, 0xf2d0, 0x2400, 0x8040, 0x2568, 0x049a, 0xeb3c, 0x0092, 0xf19f, 0x94c0, 0x4113, 0x8427, 0xd523, 0x90c0, 0x98c3, 0xf6d0 }, 16, 0x000b5ba0, 1},
++	{{0x3ac0, 0x361c, 0x8009, 0x92c3, 0x7f42, 0x92c3, 0xcd46, 0x90c0, 0x92c3, 0xed1a, 0x92c3, 0x4995, 0x96c0, 0x6c10, 0x27eb, 0x9fe0 }, 16, 0x000b5bc0, 1},
++	{{0xe7eb, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0xe748, 0xfbc9 }, 16, 0x000b5be0, 1},
++	{{0x90c0, 0x2b0c, 0x8408, 0x5e94, 0xc56f, 0x1005, 0xa004, 0x90c0, 0x98c0, 0x2c0f, 0x800c, 0x64ea, 0x5596, 0x98c0, 0x2f0b, 0x8004 }, 16, 0x000b5c00, 1},
++	{{0x7455, 0x5297, 0x3ee7, 0x149b, 0x06c6, 0x3648, 0x8009, 0x38e1, 0x138b, 0xd741, 0x1358, 0x03c2, 0x362c, 0x8009, 0x9ac0, 0x69f1 }, 16, 0x000b5c20, 1},
++	{{0x06c2, 0x3648, 0x8009, 0xe9eb, 0x846e, 0x98c0, 0x1cc0, 0x362c, 0x8009, 0xe96c, 0x9ac0, 0x74d3, 0x36cb, 0x9647, 0x439e, 0x9b41 }, 16, 0x000b5c40, 1},
++	{{0x9ac0, 0x6f44, 0xd543, 0x5d91, 0x2b03, 0x8022, 0x2e02, 0x6d29, 0xed8e, 0x9e5c, 0x9ac7, 0x2103, 0x803c, 0x90c0, 0x2d00, 0x8400 }, 16, 0x000b5c60, 1},
++	{{0x90c0, 0x94c7, 0x5558, 0xee3d, 0x2af2, 0x5196, 0x9cc0, 0x6f55, 0x7451, 0x7ce7, 0x3acb, 0x9647, 0x459e, 0x2e02, 0x1a91, 0xd543 }, 16, 0x000b5c80, 1},
++	{{0x6d18, 0xea8e, 0x92d0, 0x9e5c, 0x94c3, 0x2d00, 0x8400, 0x90c0, 0x90c0, 0x92c3, 0xee3d, 0x2d90, 0x0e94, 0x14c0, 0x362c, 0x8009 }, 16, 0x000b5ca0, 1},
++	{{0x3e67, 0x049b, 0x00c6, 0x362c, 0x8009, 0x98c0, 0x6665, 0x4093, 0x2000, 0x8051, 0x36d4, 0x0297, 0xc1a8, 0x3ac0, 0x3144, 0x8009 }, 16, 0x000b5cc0, 1},
++	{{0x7751, 0x7f43, 0xcb46, 0x90c0, 0xeb1a, 0x5693, 0x727e, 0x9ac6, 0x805d, 0x90c0, 0x78e1, 0x3303, 0x8001, 0x7551, 0x7d43, 0x94c0 }, 16, 0x000b5ce0, 1},
++	{{0xd91e, 0xcd42, 0x3dee, 0x9fff, 0xed1a, 0x1095, 0xed44, 0x707c, 0x94c6, 0x803b, 0x7451, 0x96c0, 0xda18, 0x31e8, 0x9fff, 0x3066 }, 16, 0x000b5d00, 1},
++	{{0x2ca8, 0x1695, 0xd91d, 0x94c0, 0x6c28, 0x8015, 0x33a4, 0x3590, 0x800b, 0x3c49, 0x3144, 0x3d3c, 0x800b, 0x6c10, 0x646a, 0x98c6 }, 16, 0x000b5d20, 1},
++	{{0x3044, 0x3d58, 0x800b, 0xd740, 0xf642, 0x31f0, 0x6cd3, 0x94c0, 0x74c1, 0x8593, 0x6e90, 0xf542, 0xc567, 0x90c0, 0x90c0, 0xf0c2 }, 16, 0x000b5d40, 1},
++	{{0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x36d0, 0x01c6, 0x3640, 0x8009, 0x2d7c, 0x3cf8, 0x00c6, 0x3644 }, 16, 0x000b5d60, 1},
++	{{0x8009, 0x3655, 0x3dc0, 0x33d4, 0x8009, 0x6c7d, 0x38ca, 0x9218, 0x2e98, 0x31e0, 0x3fff, 0x80ff, 0x96c0, 0x7ac1, 0xdc84, 0xcc45 }, 16, 0x000b5d80, 1},
++	{{0xcb45, 0xecfe, 0x94c0, 0xebfe, 0xec1d, 0x1394, 0xeb1d, 0x1593, 0x3244, 0x32d0, 0x800b, 0x6c0d, 0x94c0, 0xd5c0, 0x9f70, 0x7453 }, 16, 0x000b5da0, 1},
++	{{0x9cc0, 0x7751, 0x6f90, 0x6d10, 0x6c90, 0x9620, 0x9720, 0x96c0, 0x6e90, 0x9e20, 0x9f20, 0xffc7, 0x90c0, 0x2f0b, 0x8014, 0x1493 }, 16, 0x000b5dc0, 1},
++	{{0xeaeb, 0x3270, 0xea70, 0x94c0, 0x5312, 0x8043, 0x9ac0, 0x2b0a, 0x8058, 0x90c0, 0x371b, 0x8001, 0x65e9, 0x94c7, 0x802f, 0x6c20 }, 16, 0x000b5de0, 1},
++	{{0x3244, 0x32d0, 0x800b, 0x2464, 0x5192, 0x96c0, 0x7650, 0xe9ea, 0xc281, 0x94c0, 0xea58, 0xe968, 0x1191, 0xe8ea, 0xe87c, 0x1590 }, 16, 0x000b5e00, 1},
++	{{0x3044, 0x3e8e, 0x800b, 0x4592, 0x96c0, 0xe9eb, 0x2b0d, 0x8010, 0x1395, 0xe970, 0x31f0, 0x5411, 0x96c0, 0x391c, 0x8004, 0x8453 }, 16, 0x000b5e20, 1},
++	{{0x9ac0, 0x6669, 0x3410, 0x203c, 0x8800, 0xed44, 0x94c0, 0x6c7c, 0x803f, 0x2c0c, 0x1595, 0x3100, 0x2000, 0x8100, 0x3244, 0x32d0 }, 16, 0x000b5e40, 1},
++	{{0x800b, 0x6c85, 0x98c0, 0x2d08, 0x8048, 0x7650, 0xc284, 0x1190, 0xe854, 0x98c0, 0xe9e8, 0x3018, 0x2012, 0x9c00, 0x2c7c, 0xe970 }, 16, 0x000b5e60, 1},
++	{{0x1591, 0x3044, 0x3e8e, 0x800b, 0x4590, 0x2e10, 0xc781, 0x96c0, 0x6d90, 0xe8eb, 0xeeeb, 0x94c0, 0xe86c, 0xee70, 0x5010, 0x2469 }, 16, 0x000b5e80, 1},
++	{{0x5016, 0x96c0, 0x3118, 0x8008, 0x844d, 0x2469, 0x3ac0, 0x3624, 0x8009, 0x96c0, 0x8035, 0x2b0c, 0x8044, 0x1992, 0x5094, 0xec74 }, 16, 0x000b5ea0, 1},
++	{{0x290a, 0x80a0, 0x3420, 0xa000, 0x5092, 0x3400, 0xa004, 0x7070, 0x8421, 0x3600, 0xa040, 0x6db0, 0x5094, 0x6464, 0x3073, 0x3044 }, 16, 0x000b5ec0, 1},
++	{{0x3ef0, 0x800b, 0xd1d0, 0x2d90, 0x3144, 0x3ef0, 0x800b, 0x6d90, 0x3e00, 0xa002, 0x6c10, 0x2b02, 0x8002, 0x6c10, 0x2f09, 0x804c }, 16, 0x000b5ee0, 1},
++	{{0x9ac0, 0x2f0e, 0x8048, 0x90c0, 0x2b0c, 0x8030, 0x3660, 0xa000, 0x55be, 0x53b9, 0x3a60, 0xb808, 0xd445, 0xd443, 0x5596, 0x5391 }, 16, 0x000b5f00, 1},
++	{{0x3a20, 0xb808, 0xd445, 0xd443, 0x5494, 0xeaec, 0x3a00, 0xb800, 0x6e54, 0xd440, 0xea70, 0xeb70, 0x2e40, 0x5092, 0x2dcc, 0x5413 }, 16, 0x000b5f20, 1},
++	{{0x96c0, 0xd743, 0x391c, 0x8002, 0x7370, 0x843d, 0x98c0, 0x6669, 0x6c02, 0x2c0a, 0x803c, 0x96c0, 0x6464, 0xc84e, 0x8031, 0x3244 }, 16, 0x000b5f40, 1},
++	{{0x32d0, 0x800b, 0x5192, 0x98c0, 0xd5c0, 0xe9ea, 0x0902, 0xa002, 0x94c0, 0xea44, 0xe968, 0x1191, 0xebea, 0x94c0, 0xeb68, 0xc846 }, 16, 0x000b5f60, 1},
++	{{0x1593, 0xc783, 0x4592, 0x96c0, 0xd3a1, 0x2c0a, 0x8044, 0x90c0, 0x94c2, 0x2c09, 0x804c, 0x9e51, 0x90c0, 0x92c2, 0xee6c, 0x94c6 }, 16, 0x000b5f80, 1},
++	{{0x8018, 0x5796, 0x92c2, 0x4791, 0x1092, 0xea48, 0x7073, 0x90c0, 0x94c1, 0x4592, 0x4192, 0x2c0b, 0x8050, 0x98c0, 0xeeeb, 0x3600 }, 16, 0x000b5fa0, 1},
++	{{0x2000, 0x8100, 0xee64, 0x5096, 0x6c02, 0x4093, 0xeb68, 0x4393, 0x5510, 0x66e9, 0x90c0, 0x96c2, 0x3d00, 0x20a6, 0x8008, 0x8018 }, 16, 0x000b5fc0, 1},
++	{{0x92c2, 0x4215, 0xd2a2, 0x90c0, 0x96c2, 0x3c00, 0x20aa, 0x8008, 0x90c0, 0x92c2, 0x4214, 0x96c0, 0x7453, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000b5fe0, 1},
++	{{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9ac0, 0x280e }, 16, 0x000b6000, 1},
++	{{0x800c, 0x90c0, 0x270b, 0x8030, 0x3620, 0xa000, 0x5d96, 0xecee, 0x94c0, 0xec68, 0xe7eb, 0x3680, 0xa000, 0xed42, 0x5014, 0x3a80 }, 16, 0x000b6020, 1},
++	{{0xa000, 0x311a, 0x8100, 0x55d5, 0xf947, 0x98c0, 0x3b18, 0x8100, 0xffd3, 0xfc48, 0x96c0, 0x7160, 0xf846, 0xf945, 0x96c0, 0x8027 }, 16, 0x000b6040, 1},
++	{{0x2e0b, 0x8004, 0x98c0, 0x6d90, 0x4514, 0x2080, 0x8000, 0x5a93, 0x90c0, 0xea48, 0x4012, 0x1c93, 0xeb66, 0x90c0, 0xec4a, 0x4014 }, 16, 0x000b6060, 1},
++	{{0x4313, 0x94c0, 0xfcc8, 0xebee, 0xeb64, 0x1114, 0x5713, 0x64e9, 0x840d, 0x67e9, 0x8009, 0xd3a2, 0x2718, 0x8256, 0x3800, 0xa100 }, 16, 0x000b6080, 1},
++	{{0xf1d4, 0x2e0e, 0x809c, 0x3640, 0xa000, 0xe8e9, 0xfe41, 0x3244, 0x3bf0, 0x800b, 0x3420, 0xa000, 0xfe49, 0x3820, 0xa000, 0x77d0 }, 16, 0x000b60a0, 1},
++	{{0xf6d4, 0xfec9, 0x96c0, 0x676a, 0xfdc5, 0xf043, 0x3840, 0xa000, 0x847d, 0x2e09, 0x843c, 0x94c0, 0xece9, 0xeae9, 0x94c0, 0xebe9 }, 16, 0x000b60c0, 1},
++	{{0xec74, 0x94c0, 0xea78, 0xeb70, 0x1491, 0x535d, 0x266a, 0x25e6, 0x1194, 0x5092, 0x94c0, 0xd91b, 0x841d, 0x96c0, 0x7171, 0x2400 }, 16, 0x000b60e0, 1},
++	{{0x8040, 0x8439, 0x4294, 0x0292, 0x3064, 0x213a, 0x800b, 0x4491, 0x3244, 0x32d0, 0x800b, 0x1193, 0xc94a, 0x96c0, 0xda9b, 0x4092 }, 16, 0x000b6100, 1},
++	{{0xc942, 0x72f0, 0x90c0, 0x96c2, 0x4594, 0x2000, 0x8040, 0x94c1, 0xc581, 0x4592, 0x94c1, 0x4591, 0x4091, 0x3b61, 0x5591, 0x276a }, 16, 0x000b6120, 1},
++	{{0x7ae1, 0x94c0, 0x4591, 0x81a7, 0x3a20, 0xa000, 0x2e0c, 0x8428, 0x6c10, 0xc2a8, 0x96c0, 0x5694, 0x2100, 0x8051, 0x35f6, 0x3ac0 }, 16, 0x000b6140, 1},
++	{{0x2eb4, 0x8009, 0x7752, 0x7f43, 0xcb46, 0x90c0, 0xeb1a, 0x5413, 0x71f4, 0x9ac6, 0x8051, 0x90c0, 0x7961, 0x3500, 0x8001, 0x7752 }, 16, 0x000b6160, 1},
++	{{0x7f43, 0xcb46, 0x90c0, 0xeb1a, 0x1513, 0xeb44, 0x32f3, 0x2cb5, 0x5693, 0x802f, 0x32e4, 0x6c2d, 0x8015, 0x33a4, 0x3590, 0x800b }, 16, 0x000b6180, 1},
++	{{0x3a20, 0xa000, 0xfec9, 0x3164, 0x21ae, 0x800b, 0x6c10, 0x646a, 0x92c2, 0x7c49, 0x98c6, 0x3064, 0x21d0, 0x800b, 0xd740, 0xf642 }, 16, 0x000b61a0, 1},
++	{{0x74d2, 0x3071, 0x6d51, 0x94c0, 0x7542, 0x859f, 0x6e90, 0xf542, 0x3c20, 0xa000, 0x3ec9, 0x93d1, 0xebee, 0x2002, 0x8098, 0x96c0 }, 16, 0x000b61c0, 1},
++	{{0x7571, 0xf5c2, 0xf6c2, 0x3a20, 0xa000, 0x3cc8, 0x93d1, 0xeb38, 0xf544, 0x3840, 0xa000, 0x7670, 0x5993, 0xfcc8, 0xedee, 0x3680 }, 16, 0x000b61e0, 1},
++	{{0xa000, 0xe948, 0xed62, 0x3480, 0xa000, 0x5511, 0x7175, 0x90c0, 0x3482, 0xa000, 0x4111, 0x3420, 0xa000, 0x5b93, 0x90c0, 0x3480 }, 16, 0x000b6200, 1},
++	{{0xa000, 0xeb4a, 0x3480, 0xa000, 0x5513, 0x7275, 0x90c0, 0x3482, 0xa000, 0x4013, 0x5514, 0x3b1b, 0x8040, 0x25e9, 0x5315, 0x806b }, 16, 0x000b6220, 1},
++	{{0x98c0, 0x65e9, 0x3b18, 0x8080, 0x5a93, 0x845f, 0x2469, 0xea46, 0x94c0, 0x5112, 0x8033, 0x96c0, 0x7171, 0xc181, 0xc088, 0x844b }, 16, 0x000b6240, 1},
++	{{0x32e4, 0x3a8c, 0x8001, 0x94c0, 0xf24a, 0xfd4b, 0x94c0, 0xfdcb, 0xc381, 0x3620, 0xa000, 0xfec9, 0xf2ca, 0x0315, 0x3164, 0x22a8 }, 16, 0x000b6260, 1},
++	{{0x800b, 0x96c0, 0x7271, 0xc181, 0xc088, 0x841f, 0x32e4, 0x3a8c, 0x8001, 0x94c0, 0xf24a, 0xfd4b, 0x94c0, 0xfdcb, 0xc181, 0x3620 }, 16, 0x000b6280, 1},
++	{{0xa000, 0xfec9, 0xf2ca, 0x4115, 0x3880, 0xa000, 0xee68, 0x2d00, 0x809c, 0x3480, 0xa000, 0x479e, 0x3480, 0xa000, 0x4696, 0x3480 }, 16, 0x000b62a0, 1},
++	{{0xa000, 0xee3d, 0x3480, 0xa000, 0x5116, 0x64e9, 0x90c0, 0x96c2, 0x3b00, 0x20a4, 0x8008, 0x8018, 0x92c2, 0x4213, 0xd0a2, 0x90c0 }, 16, 0x000b62c0, 1},
++	{{0x96c2, 0x3d00, 0x20a8, 0x8008, 0x90c0, 0x92c2, 0x4215, 0x96c0, 0xfcc8, 0x2b02, 0x8002, 0x3c00, 0xa100, 0x2e0d, 0x803c, 0x90c0 }, 16, 0x000b62e0, 1},
++	{{0x2e0f, 0x807c, 0x1114, 0xebed, 0x3a40, 0xa100, 0x331f, 0x8007, 0x55bb, 0x5697, 0x67e9, 0x94c0, 0xfcc6, 0x849f, 0x2f10, 0x2f90 }, 16, 0x000b6300, 1},
++	{{0x6d90, 0x98c0, 0x2c0c, 0x804c, 0xd745, 0x5593, 0x98c0, 0xd745, 0x50bc, 0x2b02, 0x8002, 0x1094, 0xd7c0, 0x2c10, 0xd7c0, 0x17bd }, 16, 0x000b6320, 1},
++	{{0xd747, 0x2769, 0xd447, 0x94c0, 0xf8d3, 0x8425, 0x94c0, 0xfdc5, 0xf2d4, 0x7d41, 0x94c0, 0xe8ad, 0xe9ed, 0x8053, 0x32e4, 0x3c84 }, 16, 0x000b6340, 1},
++	{{0x8001, 0xf241, 0x3164, 0x23ac, 0x800b, 0x1795, 0xfcc6, 0xd447, 0x2c0a, 0x804c, 0x56ba, 0x1692, 0xd5c6, 0x98c0, 0xd5c6, 0x3244 }, 16, 0x000b6360, 1},
++	{{0x3d70, 0x800b, 0xd443, 0x94c0, 0xf3d4, 0xfec7, 0x65ea, 0x841f, 0x96c0, 0x9b43, 0x2b03, 0x8008, 0x515e, 0x62f4, 0x6ef4, 0x7645 }, 16, 0x000b6380, 1},
++	{{0x7e48, 0x6665, 0x92d0, 0x7e48, 0x765c, 0x445f, 0x2c10, 0x3164, 0x2464, 0x800b, 0x94c0, 0xfcc6, 0xf1c4, 0x3244, 0x3dc0, 0x800b }, 16, 0x000b63a0, 1},
++	{{0x94c0, 0xfc41, 0xf0c3, 0x3620, 0xa000, 0x2f0c, 0x8004, 0x3420, 0xa000, 0x5394, 0xc56e, 0x1105, 0xa004, 0x90c0, 0x90c0, 0x3840 }, 16, 0x000b63c0, 1},
++	{{0xa004, 0x7456, 0xf2d4, 0xec44, 0x3800, 0xa004, 0x656a, 0x2c0e, 0x8004, 0x3620, 0xa000, 0xfec7, 0x8467, 0x3244, 0x32d0, 0x800b }, 16, 0x000b63e0, 1},
++	{{0x3880, 0xa800, 0x7453, 0x5194, 0x575e, 0x3244, 0x32d0, 0x800b, 0x3800, 0xb000, 0x75d0, 0x7456, 0x5196, 0x3c00, 0xa004, 0x6f53 }, 16, 0x000b6400, 1},
++	{{0xcc4e, 0x3244, 0x3d70, 0x800b, 0x3400, 0xa800, 0x7456, 0x3800, 0xa008, 0x7750, 0x7961, 0xcc46, 0x3600, 0xa008, 0x62f7, 0x656a }, 16, 0x000b6420, 1},
++	{{0x6ef7, 0x75c5, 0x7dc8, 0x65e5, 0x7dc8, 0x94c0, 0x75db, 0x81b0, 0x435f, 0x3400, 0xa800, 0x7750, 0xc566, 0x90c0, 0x3640, 0xa100 }, 16, 0x000b6440, 1},
++	{{0x6c10, 0x4697, 0x27ed, 0x9fd0, 0xe7ed, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b6460, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x3303, 0x8001, 0x7551, 0x9620, 0x9720, 0x98c0, 0x77d2 }, 16, 0x000b6480, 1},
++	{{0x74d2, 0x9e20, 0x9f20, 0x94c0, 0xe758, 0xeee8, 0x94c0, 0xf6cd, 0xf5ce, 0x98c0, 0x71e6, 0x6e0a, 0xe8ee, 0xcf42, 0x96c0, 0x7454 }, 16, 0x000b64a0, 1},
++	{{0x2518, 0x8100, 0x96c0, 0x666a, 0xf443, 0xf545, 0x94c7, 0xf542, 0x7841, 0x7440, 0x98c0, 0xd442, 0x3264, 0x2490, 0x800b, 0x94c0 }, 16, 0x000b64c0, 1},
++	{{0xf044, 0xf041, 0x94c0, 0xf0c4, 0xf5c5, 0x96c0, 0x74d0, 0xf542, 0xf641, 0x3264, 0x2490, 0x800b, 0xe8ee, 0x94c0, 0xcf4a, 0xf0c4 }, 16, 0x000b64e0, 1},
++	{{0x3e00, 0xa001, 0x7372, 0x74d2, 0x7450, 0x75d0, 0xf5c5, 0xf4c3, 0x3a00, 0xa008, 0x7cc3, 0x7c43, 0xc845, 0x847b, 0x3880, 0xa000 }, 16, 0x000b6500, 1},
++	{{0x74d0, 0xca41, 0xc940, 0x96c0, 0x9b44, 0x2b03, 0x8026, 0x94c0, 0xea1e, 0xe91e, 0x9ac0, 0x2b02, 0x8002, 0x90c0, 0x2a0f, 0x8004 }, 16, 0x000b6520, 1},
++	{{0x96c0, 0xcd45, 0x2808, 0x8004, 0x290c, 0x8004, 0x71f7, 0x8425, 0x3361, 0x1092, 0x5491, 0x94c0, 0x6c7c, 0x800b, 0x7260, 0x8415 }, 16, 0x000b6540, 1},
++	{{0x3bc1, 0x1092, 0xea48, 0x0095, 0x3064, 0x257e, 0x800b, 0x1097, 0xef48, 0x38c1, 0x1091, 0xe948, 0x4095, 0x1094, 0xec48, 0x94d0 }, 16, 0x000b6560, 1},
++	{{0x40b8, 0xed48, 0x90c0, 0x90c0, 0xf4c3, 0x98c0, 0x7372, 0x7d43, 0xcf45, 0xcc45, 0x94c0, 0xc942, 0x8429, 0x96c0, 0x9b44, 0x2b03 }, 16, 0x000b6580, 1},
++	{{0x8018, 0x96c0, 0xee19, 0x2b02, 0x8002, 0x96c0, 0xef44, 0x2e0d, 0x8004, 0x57bc, 0x92d0, 0x47be, 0x52bf, 0x42bd, 0xe778, 0x94c0 }, 16, 0x000b65a0, 1},
++	{{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b65c0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c10, 0x9620, 0x9720, 0x96c0, 0x76d0, 0x9e20, 0x9f20 }, 16, 0x000b65e0, 1},
++	{{0x96c0, 0xc481, 0x270e, 0x80a0, 0x96c0, 0xe7ee, 0x2304, 0x8080, 0x94c0, 0xeee9, 0xfbef, 0x96c0, 0x5196, 0x2b03, 0x801a, 0x2f44 }, 16, 0x000b6600, 1},
++	{{0xefe8, 0x4696, 0x519b, 0x24e6, 0x529b, 0x94c0, 0x7451, 0x74d2, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x509b, 0x36d4, 0x6466, 0x2d7c }, 16, 0x000b6620, 1},
++	{{0x519b, 0x3551, 0x34d0, 0x3455, 0x6e10, 0x36d0, 0x6566, 0x6d7c, 0x3455, 0x0526, 0x20f8, 0x800c, 0x7750, 0x6e7c, 0x34d6, 0x7456 }, 16, 0x000b6640, 1},
++	{{0x2d7c, 0x6c7c, 0x0522, 0x20f8, 0x800c, 0x5317, 0x35d4, 0xd5a1, 0x94c0, 0xfaef, 0x845d, 0x90c0, 0x9ac0, 0x2a08, 0x8408, 0x6c10 }, 16, 0x000b6660, 1},
++	{{0x2304, 0x8080, 0x98c0, 0x76d0, 0x5298, 0x2b03, 0x8010, 0x2566, 0x5198, 0x7452, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x5098, 0x36d4 }, 16, 0x000b6680, 1},
++	{{0x6466, 0x2d7c, 0x5198, 0x3550, 0x3455, 0x24e6, 0x7653, 0x7750, 0x6e7c, 0x3456, 0x0626, 0x20fc, 0x800c, 0x76d0, 0x6d7c, 0x3555 }, 16, 0x000b66a0, 1},
++	{{0x7455, 0x2e7c, 0x6c7c, 0x0622, 0x20fc, 0x800c, 0x35d4, 0x5717, 0xd7a2, 0x94c0, 0xf8ef, 0x845b, 0x9ac0, 0x2304, 0x8080, 0x6c10 }, 16, 0x000b66c0, 1},
++	{{0x2b03, 0x801c, 0x96c0, 0x76d0, 0x280d, 0x8810, 0x529d, 0x2566, 0x519d, 0x7452, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x509d, 0x36d4 }, 16, 0x000b66e0, 1},
++	{{0x6466, 0x2d7c, 0x519d, 0x3550, 0x3455, 0x24e6, 0x7653, 0x7750, 0x6e7c, 0x3456, 0x0626, 0x2100, 0x800c, 0x76d0, 0x6d7c, 0x3555 }, 16, 0x000b6700, 1},
++	{{0x7455, 0x2e7c, 0x6c7c, 0x0622, 0x2100, 0x800c, 0x35d4, 0x5117, 0xd4a3, 0x94c0, 0xfcef, 0x845b, 0x9ac0, 0x2304, 0x8080, 0x6c10 }, 16, 0x000b6720, 1},
++	{{0x2b03, 0x801c, 0x96c0, 0x76d0, 0x2c0c, 0x8c18, 0x529c, 0x2566, 0x519c, 0x7452, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x509c, 0x36d4 }, 16, 0x000b6740, 1},
++	{{0x6466, 0x2d7c, 0x519c, 0x3550, 0x3455, 0x24e6, 0x7653, 0x7750, 0x6e7c, 0x3456, 0x0626, 0x20f4, 0x800c, 0x76d0, 0x6d7c, 0x3555 }, 16, 0x000b6760, 1},
++	{{0x7455, 0x2e7c, 0x6c7c, 0x0622, 0x20f4, 0x800c, 0x96c0, 0xd114, 0x5317, 0xf8ef, 0x96c0, 0x6564, 0xe9ee, 0xf341, 0x3284, 0x29f0 }, 16, 0x000b6780, 1},
++	{{0x800b, 0xf203, 0x9ac0, 0x2f0c, 0x8028, 0x77d0, 0x2e0d, 0x8e0a, 0x1114, 0xc681, 0x3319, 0x8800, 0x64e9, 0x96c0, 0xfbf1, 0x2518 }, 16, 0x000b67a0, 1},
++	{{0x8112, 0x98c0, 0xfc67, 0x3284, 0x2570, 0x800a, 0x2b08, 0x8058, 0x3c66, 0xfce7, 0xf043, 0xc56d, 0x1005, 0xa004, 0x90c0, 0x3c80 }, 16, 0x000b67c0, 1},
++	{{0xa000, 0x2e09, 0x8b64, 0x6e10, 0x2704, 0x807f, 0x3420, 0xa000, 0xeae9, 0x96c0, 0x539a, 0x2200, 0x8081, 0x34d3, 0x539a, 0x96c8 }, 16, 0x000b67e0, 1},
++	{{0x6e44, 0x74d3, 0x539a, 0x6e44, 0x6e4c, 0x6665, 0xc565, 0x90c0, 0x96c0, 0x6d90, 0xedec, 0x9f42, 0xed6c, 0x1555, 0x3b00, 0x3cb4 }, 16, 0x000b6800, 1},
++	{{0x800c, 0x3c20, 0xa004, 0x63f6, 0x3900, 0x3cb8, 0x800c, 0xeae9, 0x3800, 0xa004, 0x6ff6, 0x2b02, 0x8002, 0x90c0, 0x96d0, 0x79c1 }, 16, 0x000b6820, 1},
++	{{0x569a, 0x43b9, 0x46bb, 0x9cc0, 0x6c90, 0x7750, 0x3301, 0x38ac, 0x800c, 0xf241, 0x98c0, 0xf342, 0x3800, 0x3cb4, 0x800c, 0x3264 }, 16, 0x000b6840, 1},
++	{{0x2490, 0x800b, 0xf466, 0x98c0, 0x7456, 0x6d90, 0x2704, 0x8081, 0x3840, 0xa000, 0xfce7, 0x290b, 0x82a6, 0x94c0, 0xf4e6, 0xeaeb }, 16, 0x000b6860, 1},
++	{{0x92c8, 0x9382, 0x3074, 0x3d00, 0x3cb8, 0x800c, 0x804b, 0x2e90, 0x2d10, 0x3800, 0x3cb4, 0x800c, 0x90c0, 0x1190, 0x5a95, 0x96c0 }, 16, 0x000b6880, 1},
++	{{0xd541, 0xc081, 0xe848, 0x96c0, 0x7ac1, 0xea1b, 0xed48, 0x96c0, 0x3415, 0x8081, 0x909a, 0x800b, 0x3400, 0xa004, 0x73f2, 0x8005 }, 16, 0x000b68a0, 1},
++	{{0xc381, 0x65e9, 0x81d7, 0x3164, 0x28d6, 0x800b, 0x2704, 0x8081, 0x90c0, 0x92c8, 0x9685, 0x96c0, 0xebec, 0x2c08, 0x800c, 0x1010 }, 16, 0x000b68c0, 1},
++	{{0xeb62, 0x96c0, 0x7077, 0xe8ef, 0xe9ee, 0x94c7, 0xfc67, 0x6c90, 0x98c6, 0x3264, 0x3370, 0x800b, 0xc181, 0x919b, 0x3264, 0x2f10 }, 16, 0x000b68e0, 1},
++	{{0x800b, 0x94c0, 0xe9ee, 0xe8ef, 0x2704, 0x8081, 0x9ac0, 0x2e0a, 0x8524, 0x90c0, 0x27eb, 0x9f70, 0x94c0, 0xe8ea, 0xfce7, 0x92d0 }, 16, 0x000b6900, 1},
++	{{0x90a0, 0x9083, 0x96c0, 0x5314, 0x2e0b, 0x8e0a, 0x9ac0, 0x3719, 0x8800, 0xedea, 0x27e9, 0x9f70, 0x94c0, 0x64e9, 0x91e3, 0x94c0 }, 16, 0x000b6920, 1},
++	{{0xf3c3, 0x8069, 0x9ac0, 0x2304, 0x8080, 0x64e9, 0x2b03, 0x8032, 0x90c0, 0x9ac2, 0x2000, 0x80ff, 0x90c0, 0x2200, 0x80ff, 0x92c2 }, 16, 0x000b6940, 1},
++	{{0x909d, 0x96c6, 0x73f3, 0x9299, 0xed41, 0x90c0, 0x94c3, 0x2300, 0x80ff, 0x92c3, 0x9399, 0x94c0, 0x91e3, 0xf6c3, 0x24e9, 0xe941 }, 16, 0x000b6960, 1},
++	{{0x90c0, 0x9ac2, 0x2500, 0x80ff, 0x90c0, 0x2400, 0x80ff, 0x92c2, 0x959d, 0x96c6, 0x73f6, 0x9499, 0xed41, 0x90d0, 0x94c3, 0x2500 }, 16, 0x000b6980, 1},
++	{{0x80ff, 0x92c3, 0x9599, 0x1014, 0xe9ee, 0x98c0, 0x3118, 0x8100, 0xe8ef, 0xca4e, 0x6469, 0x80a1, 0x3384, 0x30a0, 0x800b, 0x94c0 }, 16, 0x000b69a0, 1},
++	{{0xfce7, 0xca46, 0xc569, 0x1005, 0xa004, 0x90c0, 0x98c0, 0x6e10, 0x6f10, 0xc9a4, 0xebec, 0x96c0, 0xc8a2, 0x2e0d, 0x8523, 0x94c0 }, 16, 0x000b69c0, 1},
++	{{0xeb39, 0x92a5, 0x1513, 0xe9ec, 0x98c0, 0x6d29, 0xe938, 0x2304, 0x8080, 0x9ac0, 0x2b03, 0x801e, 0xd992, 0x2a0b, 0x8640, 0x25e1 }, 16, 0x000b69e0, 1},
++	{{0x1211, 0x509b, 0x65e6, 0xdb9b, 0x96c0, 0x7177, 0x90c0, 0x90c0, 0x3a20, 0xa000, 0xd3d0, 0xd1d8, 0x94a5, 0x509b, 0x3a01, 0xac06 }, 16, 0x000b6a00, 1},
++	{{0x6fb5, 0x6f4e, 0x6e57, 0x6fb5, 0x3400, 0xa800, 0xdb97, 0x67e1, 0x92d0, 0x67e6, 0xdb9f, 0x7177, 0x90c0, 0x9cc1, 0x6f42, 0x2a09 }, 16, 0x000b6a20, 1},
++	{{0x8420, 0x6e40, 0x2a09, 0x8420, 0x96c6, 0x6665, 0x77d0, 0x6765, 0x4499, 0x4691, 0xc561, 0x3640, 0xa000, 0xc9a4, 0xcea2, 0x98c0 }, 16, 0x000b6a40, 1},
++	{{0x3b20, 0x2252, 0x800c, 0xe8ec, 0x3640, 0xa000, 0xedec, 0xe83e, 0x1310, 0xed39, 0x10d3, 0x5715, 0x94c0, 0xf003, 0xf301, 0x96c0 }, 16, 0x000b6a60, 1},
++	{{0xf702, 0x27e9, 0x9f70, 0x3264, 0x3df0, 0x800b, 0x94c0, 0xe8ee, 0xca4e, 0x3384, 0x23b0, 0x800b, 0x3284, 0x25d0, 0x800b, 0x94c0 }, 16, 0x000b6a80, 1},
++	{{0xe9ee, 0xe8ef, 0x94c0, 0xfce7, 0xca46, 0x5396, 0x25e0, 0xefec, 0xef68, 0x91bf, 0x64e9, 0x803b, 0x96c0, 0xd5a1, 0xcda0, 0xebec }, 16, 0x000b6aa0, 1},
++	{{0x94c0, 0xec64, 0x8431, 0x9ac0, 0x2304, 0x8081, 0x90c0, 0x2b03, 0x801a, 0x96c0, 0xeb3d, 0x2e09, 0x819c, 0x94c0, 0x2e0d, 0x8004 }, 16, 0x000b6ac0, 1},
++	{{0x1354, 0x5459, 0x96d0, 0x632c, 0x5253, 0x5155, 0x6718, 0x465d, 0x96c0, 0xfff0, 0x2304, 0x8081, 0x96c0, 0xfdf0, 0x2b03, 0x801a }, 16, 0x000b6ae0, 1},
++	{{0x94c0, 0xee44, 0xef44, 0x9ac0, 0x2001, 0x8147, 0x90c0, 0x2b02, 0x8002, 0x155e, 0x5295, 0x7655, 0x6c7c, 0x36d4, 0x5497, 0x35d5 }, 16, 0x000b6b00, 1},
++	{{0x37d5, 0x7754, 0x96d0, 0x60f5, 0x63f7, 0x75d5, 0x2cf5, 0x6ff6, 0x01bd, 0x47bf, 0x2200, 0x8081, 0x96c0, 0x9f42, 0x27eb, 0x9f70 }, 16, 0x000b6b20, 1},
++	{{0x90c0, 0x90c0, 0x92d0, 0x93a3, 0x9382, 0x27ec, 0x9f60, 0xe7ec, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000b6b40, 1},
++	{{0x98c0, 0xe750, 0x0ac6, 0x38d0, 0x8008, 0xf0c7, 0x96c0, 0x6469, 0x2a0a, 0x81c0, 0x94c0, 0x5412, 0x840f, 0x395b, 0x8000, 0x65e9 }, 16, 0x000b6b60, 1},
++	{{0x844d, 0x0324, 0x20bc, 0x800c, 0xd1a1, 0x94c0, 0xf2c8, 0x8427, 0x9ac0, 0x2304, 0x8081, 0x90c0, 0x2b03, 0x8010, 0x92c0, 0x90c0 }, 16, 0x000b6b80, 1},
++	{{0x92d0, 0x5198, 0x1498, 0x4199, 0x4499, 0x3164, 0x2bcc, 0x800b, 0x94c0, 0xf942, 0xf841, 0x98c0, 0xf243, 0x3900, 0x2a20, 0x800c }, 16, 0x000b6ba0, 1},
++	{{0x3264, 0x25f0, 0x800b, 0x3820, 0x20bc, 0x800c, 0xe770, 0x9f71, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe750, 0xeee9, 0x94c0, 0xefe8 }, 16, 0x000b6bc0, 1},
++	{{0xf942, 0x98c0, 0xf841, 0x3900, 0x2a20, 0x800c, 0x3264, 0x3930, 0x800b, 0x3820, 0x20bc, 0x800c, 0x0ac6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000b6be0, 1},
++	{{0x2a09, 0x81c0, 0x5311, 0x375c, 0x8000, 0x2669, 0x0424, 0x20bc, 0x800c, 0x8047, 0x98c0, 0xd221, 0x3900, 0x2a20, 0x800c, 0x94c0 }, 16, 0x000b6c00, 1},
++	{{0xf3c9, 0x8425, 0x9ac0, 0x2304, 0x8081, 0x90c0, 0x2b03, 0x800e, 0x90c0, 0x92d0, 0x549f, 0x129f, 0x449e, 0x429e, 0x3164, 0x2c58 }, 16, 0x000b6c20, 1},
++	{{0x800b, 0x94c0, 0xfe42, 0xf343, 0x3264, 0x25f0, 0x800b, 0x98c0, 0xff41, 0x3820, 0x20bc, 0x800c, 0xe770, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000b6c40, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3a00, 0xa004, 0x6e90, 0x6d90, 0xce57, 0xf7c3, 0x9ac0, 0x7be1 }, 16, 0x000b6c60, 1},
++	{{0xcd56, 0x3010, 0x2001, 0x8000, 0x3880, 0xa100, 0xd7a1, 0xe9ef, 0xe8ee, 0x94c0, 0xc681, 0x8455, 0x96c0, 0xf2c3, 0x290d, 0x8008 }, 16, 0x000b6c80, 1},
++	{{0x3962, 0x149d, 0xebe9, 0x9ac0, 0x76d4, 0x7961, 0x519b, 0x2b03, 0x8022, 0x98c0, 0x6d7c, 0x9b42, 0x290f, 0x8004, 0x3655, 0x529f }, 16, 0x000b6ca0, 1},
++	{{0x96c0, 0x6c7c, 0x2103, 0x8022, 0x3174, 0x149d, 0x519b, 0x9ac0, 0x76d4, 0xd052, 0xd1d6, 0x7b41, 0x529f, 0x92d0, 0x6d7c, 0x7655 }, 16, 0x000b6cc0, 1},
++	{{0x6c7c, 0x7174, 0xd1d6, 0x2e90, 0x0310, 0xf1c4, 0x96c0, 0x64ea, 0xc481, 0xece8, 0x96c0, 0xf0c6, 0x2718, 0x8150, 0x6c7c, 0xcb44 }, 16, 0x000b6ce0, 1},
++	{{0x90c0, 0x9cc0, 0xebfe, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9cc0, 0x73f4, 0x75d4, 0xc2ff, 0x3010, 0x2001, 0x8000, 0x3c00 }, 16, 0x000b6d00, 1},
++	{{0xa001, 0x2b0d, 0x8004, 0x6c17, 0x2718, 0x810c, 0x3c00, 0xa004, 0x3906, 0x8001, 0xeae9, 0x2a03, 0x8024, 0x3640, 0xa000, 0xea1d }, 16, 0x000b6d20, 1},
++	{{0x9a40, 0x94c0, 0xeee9, 0xed68, 0x94c0, 0xed19, 0xee1b, 0xcc54, 0x3800, 0xa008, 0x66ea, 0x6d90, 0xefe8, 0x94c0, 0xf6c5, 0x842b }, 16, 0x000b6d40, 1},
++	{{0x96c0, 0x9b45, 0x2b03, 0x8008, 0x5417, 0x6e0c, 0x6666, 0x7276, 0x90c0, 0x94c3, 0x2003, 0x8012, 0x3610, 0xa004, 0x79c1, 0xef42 }, 16, 0x000b6d60, 1},
++	{{0x90c0, 0x90c0, 0x3800, 0xa800, 0x72e3, 0x5495, 0x5696, 0x94c0, 0x6c7c, 0x848b, 0x3640, 0xa000, 0x7374, 0x5792, 0x847d, 0x3400 }, 16, 0x000b6d80, 1},
++	{{0xa800, 0x7377, 0x96c0, 0xd056, 0xd153, 0x8075, 0x3400, 0xa004, 0x73e6, 0x8467, 0x3a00, 0xb919, 0x73f6, 0x74d6, 0x6d9f, 0xcf46 }, 16, 0x000b6da0, 1},
++	{{0x3600, 0xa004, 0x7cc2, 0x8459, 0x3c20, 0xa804, 0x3300, 0x8004, 0x9b43, 0x2b03, 0x801e, 0x3680, 0xa000, 0xc450, 0xeffe, 0xef19 }, 16, 0x000b6dc0, 1},
++	{{0x3480, 0xa000, 0xec19, 0x3660, 0xa100, 0x5497, 0x5294, 0x3880, 0xa804, 0x7164, 0xef44, 0xec44, 0x801b, 0x3400, 0xa804, 0x7272 }, 16, 0x000b6de0, 1},
++	{{0x90c0, 0x94c3, 0x2003, 0x8016, 0x98c0, 0x7456, 0x7553, 0x2003, 0x8010, 0x90d0, 0x90c0, 0x90c0, 0x3a10, 0xa008, 0x79c1, 0x7b41 }, 16, 0x000b6e00, 1},
++	{{0xee44, 0xed44, 0xea44, 0x90c0, 0xcc5c, 0x2568, 0x7ac1, 0x3800, 0xa808, 0xd05d, 0x7ac1, 0x84cb, 0x3600, 0xa800, 0x70f5, 0x421c }, 16, 0x000b6e20, 1},
++	{{0x2dff, 0x9ed1, 0x3a00, 0xb000, 0x6f10, 0x7575, 0x2a03, 0x801c, 0x2e7c, 0x7961, 0x9ac0, 0x9a46, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b6e40, 1},
++	{{0x9cc0, 0x280f, 0x8002, 0x656a, 0x6f90, 0x76d2, 0xebe8, 0x96c0, 0x7ae1, 0x5a13, 0x8473, 0x94c0, 0x5d17, 0x9b45, 0x96c0, 0xecea }, 16, 0x000b6e60, 1},
++	{{0x2b03, 0x8030, 0x94c0, 0xeeed, 0xecfe, 0x94c0, 0xeefe, 0xec19, 0x1394, 0xee19, 0x1696, 0xc848, 0x7373, 0x90c0, 0x94c2, 0x4d13 }, 16, 0x000b6e80, 1},
++	{{0x4a17, 0x94c0, 0xef42, 0xeb42, 0x2103, 0x8034, 0x1d13, 0x5817, 0x92c2, 0xc781, 0x94c0, 0xeced, 0xeee8, 0x94c0, 0xecfe, 0xeefe }, 16, 0x000b6ea0, 1},
++	{{0x94c0, 0xec19, 0xee19, 0x1694, 0x5196, 0x70f6, 0x90d0, 0x94c2, 0x4d17, 0x4813, 0x94c0, 0xef42, 0xeb42, 0xc840, 0x92c2, 0xc781 }, 16, 0x000b6ec0, 1},
++	{{0x3961, 0xd3a1, 0x90c0, 0x94c3, 0x2003, 0x800c, 0x90d0, 0x90c0, 0x90c0, 0x3400, 0xa800, 0x7455, 0x94c0, 0xce5f, 0xcd5e, 0x9f70 }, 16, 0x000b6ee0, 1},
++	{{0x3660, 0xa000, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9ac0 }, 16, 0x000b6f00, 1},
++	{{0x270d, 0x80f8, 0x90c0, 0x2400, 0x8081, 0x94c0, 0xe7ed, 0xefe8, 0x98c0, 0x3d00, 0x2f44, 0x800c, 0xf441, 0x96c0, 0xf97d, 0x290a }, 16, 0x000b6f20, 1},
++	{{0x8108, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xe8ed, 0xca4e, 0x98c0, 0x6f10, 0x6d10, 0xf9fd, 0xca46, 0x96c0, 0x9362, 0x2b03, 0x802c }, 16, 0x000b6f40, 1},
++	{{0x96c0, 0xeeea, 0x290c, 0x8110, 0x109e, 0x549c, 0x9ac0, 0x6c7c, 0x3010, 0x2001, 0x8000, 0xc181, 0x98c0, 0x6c7c, 0x75d1, 0x290b }, 16, 0x000b6f60, 1},
++	{{0x810c, 0x579b, 0x33f4, 0x149c, 0x519e, 0x9ac0, 0x76d4, 0xd057, 0xd153, 0x79c1, 0x579b, 0x92d0, 0x6d7c, 0x7655, 0x6c7c, 0x9ec0 }, 16, 0x000b6f80, 1},
++	{{0x2a03, 0x8048, 0x6d90, 0x73f4, 0x74d3, 0x27ec, 0x9fa4, 0x94c0, 0xd151, 0xc4a4, 0xcb42, 0x98c0, 0xfb2e, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b6fa0, 1},
++	{{0x3a00, 0xa00c, 0x7453, 0x74d4, 0x9263, 0xc2ff, 0x98c0, 0x3010, 0x2001, 0x8000, 0xc181, 0x96c0, 0xc582, 0x290b, 0x8110, 0x96c0 }, 16, 0x000b6fc0, 1},
++	{{0xeeea, 0x290d, 0x810c, 0x98c0, 0x65ea, 0x6e10, 0x27e8, 0x9fa4, 0x8427, 0x3820, 0xa000, 0x9b40, 0x2b03, 0x800a, 0x5710, 0x6f87 }, 16, 0x000b6fe0, 1},
++	{{0x67e6, 0xd7a2, 0x90c0, 0x94c3, 0x2003, 0x8010, 0x94d0, 0x7a41, 0xe842, 0x90c0, 0x90c0, 0x3820, 0xa000, 0x71e4, 0x5496, 0x5495 }, 16, 0x000b7000, 1},
++	{{0x94c0, 0x6c7c, 0x8481, 0x3600, 0xa004, 0x7274, 0x5793, 0x8473, 0x3400, 0xa004, 0x7277, 0x3800, 0xa800, 0xd054, 0xd151, 0x806b }, 16, 0x000b7020, 1},
++	{{0x3600, 0xb800, 0x73e4, 0x6e25, 0x8459, 0x266a, 0x37d5, 0xc845, 0x94c0, 0x7fc2, 0x8451, 0x98c0, 0x7bc4, 0x9b44, 0x2b03, 0x801a }, 16, 0x000b7040, 1},
++	{{0x94c0, 0xc157, 0xe8fe, 0xe81a, 0x3680, 0xa000, 0xe91a, 0x90c0, 0x3600, 0xa100, 0x5490, 0x5791, 0x3880, 0xa000, 0x73e4, 0xe844 }, 16, 0x000b7060, 1},
++	{{0xe944, 0x8019, 0x7277, 0x90c0, 0x94c3, 0x2003, 0x8018, 0x3a00, 0xa800, 0x7454, 0x7551, 0x2003, 0x8012, 0x90d0, 0x90c0, 0x90c0 }, 16, 0x000b7080, 1},
++	{{0x98d0, 0x78c1, 0x7ac1, 0xed44, 0xee44, 0xeb44, 0x90c0, 0x3800, 0xb000, 0x6568, 0x7651, 0x79c1, 0x84cf, 0x3b41, 0x421c, 0x3616 }, 16, 0x000b70a0, 1},
++	{{0x8024, 0x2fff, 0x9eff, 0x9ac0, 0x75f6, 0x2a03, 0x801a, 0x6f90, 0xcf49, 0x2f7c, 0x79e1, 0x98c0, 0x9a47, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b70c0, 1},
++	{{0x9ec0, 0x27eb, 0x9fa6, 0x65ea, 0x6c10, 0x77d3, 0x27ec, 0x9fa4, 0x3840, 0xa000, 0x7be1, 0x5b14, 0x847d, 0x94c0, 0x5e13, 0x9b47 }, 16, 0x000b70e0, 1},
++	{{0x38a0, 0xa000, 0xeaeb, 0x2b03, 0x803a, 0x3600, 0xa100, 0xedee, 0xeafe, 0x3600, 0xa100, 0xedfe, 0xea1a, 0x3600, 0xa100, 0xed1a }, 16, 0x000b7100, 1},
++	{{0x5292, 0x5795, 0x73f2, 0x90c0, 0x3642, 0xa000, 0x4e14, 0x4b13, 0x94c0, 0xeb42, 0xec42, 0x2103, 0x8032, 0x1914, 0x5f13, 0x92c2 }, 16, 0x000b7120, 1},
++	{{0xc081, 0x94c0, 0xeee9, 0xedef, 0x94c0, 0xeefe, 0xedfe, 0x94c0, 0xee1a, 0xed1a, 0x1596, 0x5495, 0x7275, 0x90d0, 0x94c2, 0x4913 }, 16, 0x000b7140, 1},
++	{{0x4f14, 0x94c0, 0xeb42, 0xec42, 0x92c2, 0xc081, 0x39e1, 0xd021, 0x90c0, 0x94c3, 0x2003, 0x81da, 0x90d0, 0x90c0, 0x90c0, 0x94c0 }, 16, 0x000b7160, 1},
++	{{0xf9fd, 0xcf41, 0x90c0, 0x90c0, 0x36f6, 0x2e10, 0xef58, 0x26e9, 0x5017, 0x96c0, 0xfbae, 0x2518, 0x81a6, 0x9ac0, 0x27e8, 0x9f10 }, 16, 0x000b7180, 1},
++	{{0x66ea, 0x27ed, 0x9fa4, 0xebfe, 0xeb1a, 0x96c0, 0x5793, 0x290b, 0x8dbe, 0x9ac0, 0x34e2, 0x8000, 0x90c0, 0x36e6, 0x8000, 0x30e2 }, 16, 0x000b71a0, 1},
++	{{0x8000, 0xd992, 0x94c0, 0xd5c6, 0x8448, 0x36c8, 0x944f, 0x96c0, 0x9b45, 0x2b03, 0x8008, 0x3420, 0xa000, 0x581d, 0x90c0, 0x3420 }, 16, 0x000b71c0, 1},
++	{{0xa000, 0xece8, 0xecfe, 0xec1a, 0x5794, 0x7077, 0x92c3, 0x7a41, 0x98c3, 0x3e80, 0x32e0, 0x8008, 0x4798, 0x90c0, 0x3493, 0xa000 }, 16, 0x000b71e0, 1},
++	{{0xe81e, 0x3483, 0xa000, 0x92b8, 0x92c3, 0x421b, 0x98c0, 0x6f90, 0xc081, 0x2c00, 0x8863, 0x9ac0, 0x2a0d, 0x8d00, 0x6c7d, 0x2800 }, 16, 0x000b7200, 1},
++	{{0x8081, 0x96c0, 0x4415, 0x2a03, 0x801e, 0x94c0, 0xed3c, 0x9a48, 0x94c0, 0xeeed, 0xef64, 0x3800, 0xa100, 0xee38, 0x2908, 0x8626 }, 16, 0x000b7220, 1},
++	{{0x98c0, 0x6f10, 0x93a5, 0x27eb, 0x9ff4, 0x9ac0, 0x27ea, 0x9fee, 0x65e9, 0x2200, 0x80b4, 0x2518, 0x80d6, 0x9743, 0x90c0, 0x94c8 }, 16, 0x000b7240, 1},
++	{{0x421a, 0x461b, 0x98c0, 0x65e9, 0xc947, 0x27ec, 0x9ff4, 0x96c0, 0x8057, 0x27ea, 0x9fee, 0x96c0, 0x9b43, 0x2b03, 0x800e, 0x3420 }, 16, 0x000b7260, 1},
++	{{0xa000, 0xe918, 0x9ac0, 0x6c90, 0x2500, 0x80ff, 0x666a, 0x92b9, 0x3620, 0xa000, 0xfdae, 0x8429, 0x3b80, 0x32e0, 0x8008, 0x90c0 }, 16, 0x000b7280, 1},
++	{{0x3420, 0xa000, 0xeb1d, 0x96bb, 0x6daa, 0x65e6, 0x756b, 0x3612, 0x80fe, 0x94c7, 0xd2db, 0x6c90, 0x96d0, 0x74ed, 0x411c, 0xe918 }, 16, 0x000b72a0, 1},
++	{{0x411a, 0x90c0, 0x9ac0, 0x6c90, 0x6e90, 0x6d10, 0x5617, 0x90c0, 0x96c0, 0xcc41, 0x27ea, 0x9fee, 0x27e9, 0x9fa4, 0x98c0, 0xecfc }, 16, 0x000b72c0, 1},
++	{{0x3b80, 0x32e0, 0x8008, 0xea1c, 0x3820, 0xa000, 0x5712, 0x27ea, 0x9ff4, 0x3600, 0xa004, 0x73f6, 0xec1a, 0x94c7, 0x801f, 0x76d0 }, 16, 0x000b72e0, 1},
++	{{0x5c14, 0x90c0, 0xecfc, 0xec19, 0x5a14, 0x90c0, 0x98c0, 0xea1b, 0x3064, 0x331a, 0x800b, 0x92ba, 0x78c1, 0x74e9, 0xd4a1, 0xd2d0 }, 16, 0x000b7300, 1},
++	{{0x76ed, 0x66e9, 0x81ad, 0x3164, 0x332e, 0x800b, 0x92be, 0x94d0, 0x7bc1, 0x9286, 0x90c0, 0x90c0, 0x27ed, 0x9f08, 0xe7ed, 0x94c0 }, 16, 0x000b7320, 1},
++	{{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x3064, 0x3186, 0x800b, 0x94c0, 0xf9fd, 0xcf41, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b7340, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6d10, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x2704 }, 16, 0x000b7360, 1},
++	{{0x8387, 0x3c00, 0xa100, 0x270e, 0x8b00, 0x90c0, 0x290f, 0x85a5, 0x3640, 0xa000, 0xe7ee, 0xeaef, 0x92c8, 0x9282, 0x3820, 0xa000 }, 16, 0x000b7380, 1},
++	{{0xeeef, 0x2b00, 0x849d, 0x9765, 0xee3b, 0xedee, 0x92c8, 0x429d, 0x9765, 0x27ec, 0x9e90, 0x92c8, 0x429c, 0x96c0, 0x5110, 0x280a }, 16, 0x000b73a0, 1},
++	{{0x8028, 0x3840, 0xa000, 0x5512, 0x2000, 0x8081, 0x3b1a, 0x8002, 0x6569, 0x841d, 0xd0a2, 0x90c0, 0x96c2, 0x3d20, 0x2252, 0x800c }, 16, 0x000b73c0, 1},
++	{{0x3623, 0xa000, 0x2000, 0x8081, 0x3422, 0xa000, 0x50d5, 0x3c40, 0xa104, 0x6461, 0x6e90, 0xeb3b, 0x2f0b, 0x87c3, 0x3ac0, 0xa004 }, 16, 0x000b73e0, 1},
++	{{0x646a, 0xefef, 0x290a, 0x8b64, 0x9ac0, 0x27ec, 0x955c, 0x90c0, 0x2718, 0x8504, 0x3c80, 0xa100, 0x290d, 0x8626, 0x90c0, 0x27ee }, 16, 0x000b7400, 1},
++	{{0x9558, 0x3482, 0x3118, 0x8008, 0x3c80, 0xa000, 0x27e9, 0x9964, 0x90c0, 0x27e9, 0x9960, 0x33e1, 0x3e08, 0x800b, 0x9ac0, 0x07fa }, 16, 0x000b7420, 1},
++	{{0x954c, 0x90c0, 0x0ef8, 0x9548, 0x9ac0, 0x0af8, 0x9544, 0x90c0, 0x03fa, 0x9540, 0x94c0, 0x6f90, 0x9742, 0x9ac0, 0x7457, 0x27ed }, 16, 0x000b7440, 1},
++	{{0x9fd4, 0x74d7, 0xc4ff, 0x3ac0, 0x3650, 0x8009, 0x27ee, 0x9fc0, 0x3610, 0x2000, 0x8000, 0x94d0, 0x469e, 0x441d, 0xc01a, 0x37d0 }, 16, 0x000b7460, 1},
++	{{0x1610, 0xca45, 0x96c0, 0x7b61, 0xce43, 0xc355, 0x276a, 0x3de0, 0x3a00, 0x800b, 0x96c0, 0xea1e, 0x2718, 0x81be, 0x3a40, 0xa000 }, 16, 0x000b7480, 1},
++	{{0x3ec0, 0x3650, 0x8009, 0xed1b, 0x96c0, 0xfe46, 0x01fa, 0x9520, 0x3c20, 0xa000, 0x00f8, 0x9550, 0x90c0, 0x0bf8, 0x9538, 0x9ac0 }, 16, 0x000b74a0, 1},
++	{{0x08f8, 0x953c, 0x90c0, 0x02fa, 0x9534, 0x9ac0, 0x04fa, 0x9530, 0x90c0, 0x05f8, 0x952c, 0x9ac0, 0x0cf8, 0x9528, 0x90c0, 0x06fa }, 16, 0x000b74c0, 1},
++	{{0x9524, 0x3c80, 0xa000, 0xe9ea, 0x05fa, 0x951c, 0x90c0, 0x90c0, 0x3600, 0xa100, 0x549d, 0x5299, 0x98c0, 0xf44a, 0x34e0, 0x3fff }, 16, 0x000b74e0, 1},
++	{{0x800f, 0x168d, 0xf1ca, 0x3800, 0xa100, 0x64e6, 0x5089, 0xf248, 0x96c0, 0x7271, 0xf649, 0xf047, 0x96c0, 0x8445, 0x27e8, 0x9fdc }, 16, 0x000b7500, 1},
++	{{0x5290, 0x6566, 0x7272, 0x94c0, 0xf6c8, 0x8437, 0x96c0, 0x6766, 0x27ec, 0x9fe4, 0x3276, 0x5194, 0x94c0, 0x64e6, 0x8425, 0x7271 }, 16, 0x000b7520, 1},
++	{{0x94c0, 0xf6ca, 0x841d, 0x3f48, 0xf0c8, 0x3c48, 0xf64a, 0x1090, 0xf048, 0x3c48, 0x5494, 0x3e48, 0x4090, 0x4494, 0x94c0, 0xf4c8 }, 16, 0x000b7540, 1},
++	{{0xf6c7, 0x94c0, 0xf2ca, 0xf1c9, 0x94c0, 0xf444, 0xf643, 0x94c0, 0xf242, 0xf141, 0x9ac0, 0x27ea, 0x9fb8, 0x90c0, 0x09f8, 0x9518 }, 16, 0x000b7560, 1},
++	{{0x3284, 0x2720, 0x800b, 0x9ac0, 0x01fa, 0x9514, 0x90c0, 0x0df8, 0x9510, 0x94c0, 0xf2d2, 0xf0d1, 0x029e, 0x19f8, 0x9518, 0x008e }, 16, 0x000b7580, 1},
++	{{0x18f8, 0x9520, 0x94c0, 0xc116, 0xf4d2, 0x0091, 0xf6d1, 0x0190, 0xf442, 0x3284, 0x28a0, 0x800b, 0x96c0, 0xf641, 0x27ea, 0x9fc8 }, 16, 0x000b75a0, 1},
++	{{0x9747, 0x9ac0, 0x27e8, 0x9fc8, 0x90c0, 0x1df8, 0x9510, 0x9ac0, 0x11fa, 0x9514, 0x90c0, 0x19f8, 0x9518, 0x90e0, 0x94c8, 0x9086 }, 16, 0x000b75c0, 1},
++	{{0x90e0, 0x98c0, 0x1cf8, 0x953c, 0x7bc1, 0x909e, 0x96c0, 0xfec6, 0x1af8, 0x9528, 0x1214, 0x1cf8, 0x9524, 0x98c0, 0x7961, 0xc11e }, 16, 0x000b75e0, 1},
++	{{0x2d0d, 0x8408, 0x3aa0, 0xa000, 0x7177, 0x4094, 0x2909, 0x8408, 0x2cff, 0x9ee1, 0x0192, 0xfe46, 0x3c40, 0xa000, 0x18f8, 0x953c }, 16, 0x000b7600, 1},
++	{{0x90c0, 0x10f8, 0x9550, 0x9ac0, 0x1bf8, 0x9538, 0x90c0, 0x12fa, 0x9534, 0x9ac0, 0x14fa, 0x9530, 0x90c0, 0x15f8, 0x952c, 0x96c0 }, 16, 0x000b7620, 1},
++	{{0xecea, 0x16fa, 0x9524, 0x9ac0, 0x11fa, 0x9520, 0x90c0, 0x15fa, 0x951c, 0x98c0, 0x27ea, 0x9e90, 0x6f10, 0xc7a5, 0x3c00, 0xa100 }, 16, 0x000b7640, 1},
++	{{0x27ee, 0x9f24, 0x90c0, 0x27eb, 0x9d68, 0x3a00, 0xa100, 0x3722, 0x2206, 0x800c, 0xe8ea, 0x3c20, 0xa000, 0x00f8, 0x9550, 0x90c0 }, 16, 0x000b7660, 1},
++	{{0x0bf8, 0x9538, 0x9ac0, 0x0ff8, 0x950c, 0x90c0, 0x02fa, 0x9534, 0x9ac0, 0x05f8, 0x952c, 0x90c0, 0x0cf8, 0x9528, 0x9ac0, 0x06fa }, 16, 0x000b7680, 1},
++	{{0x9524, 0x90c0, 0x01fa, 0x9520, 0x9ac0, 0x09f8, 0x9518, 0x90c0, 0x05fa, 0x951c, 0x3680, 0xa100, 0x505f, 0x5254, 0x9ac0, 0x27ea }, 16, 0x000b76a0, 1},
++	{{0x9fd0, 0x60b2, 0x08f8, 0x953c, 0x9ac0, 0x04fa, 0x9530, 0x7cc4, 0x03fa, 0x9508, 0x96c0, 0xf146, 0x07fa, 0x9504, 0x32e4, 0x20ca }, 16, 0x000b76c0, 1},
++	{{0x800a, 0x3640, 0xa000, 0xf0c6, 0xefe8, 0x9ac0, 0x18f8, 0x953c, 0x90c0, 0x27ed, 0x9fd2, 0x9ac0, 0x02fc, 0x9fd0, 0x90c0, 0x13fa }, 16, 0x000b76e0, 1},
++	{{0x9508, 0x3840, 0xa000, 0xd91a, 0x5410, 0x5155, 0x3c80, 0xa004, 0x7a61, 0xd999, 0xe8ef, 0x14fa, 0x9530, 0x3c80, 0xb00c, 0x666a }, 16, 0x000b7700, 1},
++	{{0x74d4, 0xc21b, 0x17fa, 0x9504, 0x3840, 0xa104, 0x78e1, 0x5790, 0x849f, 0x3a40, 0xa000, 0x3bc0, 0x3650, 0x8009, 0x9b41, 0x9ac0 }, 16, 0x000b7720, 1},
++	{{0x03fc, 0x9fd0, 0x90c0, 0x2b03, 0x8036, 0x96c0, 0xc51b, 0x27ea, 0x9fc0, 0x3c20, 0xa000, 0x7554, 0x27ef, 0x9fd4, 0x7455, 0x5192 }, 16, 0x000b7740, 1},
++	{{0x22f5, 0x6274, 0x2ef5, 0x6e74, 0x98c0, 0x6d15, 0x7657, 0x2103, 0x8048, 0x76d2, 0x3a00, 0xa808, 0x72f1, 0xd7c5, 0xc31b, 0x4596 }, 16, 0x000b7760, 1},
++	{{0x3453, 0x03fc, 0x9fd0, 0x3a16, 0xa002, 0x90c0, 0x63f4, 0x4592, 0x60f5, 0x3e06, 0xa002, 0x90c0, 0xea44, 0x90c0, 0x6cf5, 0x4617 }, 16, 0x000b7780, 1},
++	{{0x6ff4, 0x3820, 0xa800, 0x6ea7, 0xef42, 0x5192, 0x37d4, 0x7555, 0x3800, 0xa808, 0x7171, 0xd7c2, 0x4296, 0x34a0, 0xa000, 0x4790 }, 16, 0x000b77a0, 1},
++	{{0x94c2, 0x4292, 0x4617, 0x3a80, 0xa000, 0x7be1, 0x7b41, 0xe844, 0xee44, 0x67ea, 0x2dff, 0x9ee1, 0x3e00, 0xa002, 0x6c90, 0x1bf8 }, 16, 0x000b77c0, 1},
++	{{0x9538, 0x666a, 0x15fa, 0x951c, 0x3c20, 0xa000, 0x10f8, 0x9550, 0x6d10, 0x1ff8, 0x950c, 0x9ac0, 0x12fa, 0x9534, 0x90c0, 0x15f8 }, 16, 0x000b77e0, 1},
++	{{0x952c, 0x9ac0, 0x1cf8, 0x9528, 0x90c0, 0x16fa, 0x9524, 0x9ac0, 0x11fa, 0x9520, 0x90c0, 0x19f8, 0x9518, 0x84c4, 0x3a00, 0xa100 }, 16, 0x000b7800, 1},
++	{{0x33e0, 0x3e08, 0x800b, 0xe8eb, 0x38a0, 0xa100, 0xe81d, 0x27ef, 0x9fd4, 0x9cc0, 0x13fa, 0x954c, 0x90c0, 0x1af8, 0x9548, 0x90c0 }, 16, 0x000b7820, 1},
++	{{0x9ec0, 0x1df8, 0x9544, 0x90c0, 0x1ef8, 0x9540, 0x90c0, 0x90c0, 0x3aa0, 0xa000, 0x5e1f, 0x3c80, 0x32e0, 0x8008, 0xe9eb, 0x36c0 }, 16, 0x000b7840, 1},
++	{{0xa000, 0xeef3, 0xec1e, 0x94c0, 0x97bc, 0x844b, 0x3880, 0xa100, 0x78c1, 0x9798, 0xeefe, 0x3600, 0xa100, 0x5615, 0xee1a, 0x3cc0 }, 16, 0x000b7860, 1},
++	{{0xa100, 0x3d1c, 0x8040, 0x5096, 0x2808, 0x8081, 0x6669, 0x92c2, 0x7841, 0x3683, 0xa000, 0x5792, 0x5616, 0x92c3, 0xd79e, 0x92c3 }, 16, 0x000b7880, 1},
++	{{0x6c43, 0x3a80, 0xa000, 0x4096, 0x3064, 0x38c4, 0x800b, 0x919f, 0x94c0, 0x6f90, 0x9747, 0x3420, 0xa000, 0xe91b, 0x92d0, 0x9799 }, 16, 0x000b78a0, 1},
++	{{0x2909, 0x8081, 0x3941, 0x5010, 0x7861, 0x7072, 0x8185, 0x9ac0, 0x1cf8, 0x9528, 0x90c0, 0x16fa, 0x9524, 0x19f8, 0x9518, 0x3a80 }, 16, 0x000b78c0, 1},
++	{{0xa004, 0x7861, 0x7ac8, 0xe948, 0xeb41, 0x3880, 0xa004, 0x646a, 0xe948, 0xee48, 0x3680, 0xa000, 0xec42, 0xec48, 0x2cff, 0x9b59 }, 16, 0x000b78e0, 1},
++	{{0x3680, 0xa000, 0xea44, 0xef41, 0x1ef8, 0x9548, 0x9764, 0x27e9, 0x9e90, 0x5099, 0x94c8, 0x409e, 0x5099, 0x4096, 0x27ee, 0x9500 }, 16, 0x000b7900, 1},
++	{{0xe7ee, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x96c0, 0x6f10, 0x9620, 0x9720, 0x9ac0, 0x290c, 0x892c, 0x90c0 }, 16, 0x000b7920, 1},
++	{{0x2809, 0x8004, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0x5011, 0x92bc, 0x96c0, 0x7160, 0x270a, 0x8020, 0x96c0, 0xe7ea, 0x2518, 0x810e }, 16, 0x000b7940, 1},
++	{{0x3f80, 0x3304, 0x8008, 0x90c0, 0x94bf, 0x6c7d, 0x4411, 0x0185, 0x32e0, 0x8008, 0x7271, 0x8417, 0x3e80, 0x32e0, 0x8008, 0x90c0 }, 16, 0x000b7960, 1},
++	{{0xee41, 0x94c0, 0x7b41, 0x95a6, 0x7275, 0x81f9, 0x6769, 0x802d, 0x9ac0, 0x76d6, 0xce46, 0x3a80, 0x32e0, 0x8008, 0x3ae1, 0x3b80 }, 16, 0x000b7980, 1},
++	{{0x32e0, 0x8008, 0x94c0, 0xcd45, 0xea1e, 0x97ba, 0x2d17, 0xed1b, 0x90bd, 0x6d80, 0x7173, 0x92c2, 0x7b61, 0x9cc0, 0x7f41, 0x6e90 }, 16, 0x000b79a0, 1},
++	{{0x3b20, 0x2206, 0x800c, 0xfc44, 0x96c0, 0xcd46, 0x2200, 0x8081, 0x98c0, 0x3e80, 0x3118, 0x8008, 0xf943, 0xed1b, 0x5355, 0xf345 }, 16, 0x000b79c0, 1},
++	{{0x1610, 0xc481, 0x9ac0, 0xd721, 0xcd45, 0x3f20, 0x2258, 0x800c, 0x8461, 0x94c0, 0xef1d, 0xf246, 0xf547, 0x1756, 0xf6c5, 0x96c0 }, 16, 0x000b79e0, 1},
++	{{0x603f, 0xf448, 0xc84f, 0x9ac0, 0x3a01, 0x8004, 0x90c0, 0x3606, 0x8004, 0x3801, 0x8004, 0xd991, 0xd5c6, 0x7dc4, 0x98c0, 0xf342 }, 16, 0x000b7a00, 1},
++	{{0x3284, 0x2b30, 0x800b, 0xf0c2, 0x3284, 0x2b50, 0x800b, 0x3750, 0xf0c2, 0x96c0, 0x77d0, 0xc847, 0xf4c8, 0x98c0, 0x7a41, 0x4e57 }, 16, 0x000b7a20, 1},
++	{{0x2f0f, 0x8204, 0x5310, 0x71f4, 0x81b3, 0x94c0, 0xf2c6, 0xf5c7, 0x3ac4, 0xee42, 0x7961, 0x656a, 0x8189, 0x94c0, 0xf9c3, 0xfcc4 }, 16, 0x000b7a40, 1},
++	{{0x90c0, 0x5411, 0x949c, 0xc56d, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x3a00, 0xa008, 0x6e10, 0x6e90, 0xffcf, 0xfdd0, 0x96c0, 0xcc54 }, 16, 0x000b7a60, 1},
++	{{0x2204, 0x8081, 0x9ac0, 0x2b03, 0x80dc, 0x90c0, 0x2a03, 0x8044, 0x96c0, 0xcd55, 0x2b02, 0x8002, 0x90c0, 0x3800, 0xa100, 0xfecf }, 16, 0x000b7a80, 1},
++	{{0x2f0d, 0x8004, 0x94c0, 0xfbd0, 0xed44, 0x3cc0, 0xa000, 0x2f0b, 0x8408, 0x90c0, 0x2321, 0x8aab, 0x3a40, 0xa000, 0x3122, 0x2660 }, 16, 0x000b7aa0, 1},
++	{{0x800c, 0xca83, 0x2a02, 0x8102, 0x3640, 0xa100, 0x5710, 0x56bd, 0x3e20, 0xa000, 0xd7a1, 0x7be1, 0x54be, 0x3920, 0x2258, 0x800c }, 16, 0x000b7ac0, 1},
++	{{0x3a00, 0xa100, 0x7be1, 0xcf45, 0x2718, 0x80f2, 0x94c0, 0xcc5c, 0x9b47, 0x3640, 0xa000, 0xcc44, 0xef1b, 0x96c0, 0x50b7, 0x2f0a }, 16, 0x000b7ae0, 1},
++	{{0x8004, 0x3a00, 0xa004, 0x7450, 0x7750, 0xe91c, 0x52b2, 0x98c0, 0x290c, 0x8002, 0x7652, 0x5371, 0x3600, 0xa004, 0x74d3, 0x5574 }, 16, 0x000b7b00, 1},
++	{{0x3e00, 0xa847, 0x63f4, 0x77d5, 0x74d3, 0x7452, 0x90c0, 0x90c0, 0x3e00, 0xb08d, 0x6177, 0x6074, 0x60f6, 0x77d3, 0x90c0, 0x90c0 }, 16, 0x000b7b20, 1},
++	{{0x3e00, 0xa002, 0x74d5, 0x7652, 0x7750, 0x6c75, 0x90c0, 0x90c0, 0x3e00, 0xa00d, 0x6ff7, 0x6d74, 0x6cf6, 0x2103, 0x8072, 0x90c0 }, 16, 0x000b7b40, 1},
++	{{0x3e00, 0xbe53, 0x6c8a, 0x7651, 0x6d57, 0x75d0, 0x50b7, 0x5371, 0x3e00, 0xa413, 0x7750, 0x77d3, 0x6e48, 0x6f59, 0x5574, 0x52b2 }, 16, 0x000b7b60, 1},
++	{{0x3a00, 0xa006, 0x63f7, 0x77d5, 0x7750, 0x7452, 0x3a00, 0xa006, 0x6177, 0x7752, 0x77d3, 0x74d5, 0x3a10, 0xa84c, 0x60f4, 0x6077 }, 16, 0x000b7b80, 1},
++	{{0x77d5, 0x74d3, 0x3a00, 0xa003, 0x7750, 0x7652, 0x6ff4, 0x6c75, 0x3600, 0xa00c, 0x6cf6, 0x6d77, 0x3820, 0xa000, 0x3300, 0x2000 }, 16, 0x000b7ba0, 1},
++	{{0xaaab, 0x3600, 0xb8c0, 0x6d0a, 0x6f57, 0x3600, 0xa0cc, 0x6e46, 0x6f52, 0x5f10, 0x90c0, 0xef61, 0x3420, 0xa000, 0xef8a, 0x94c0 }, 16, 0x000b7bc0, 1},
++	{{0xeffe, 0x8089, 0x3820, 0xb800, 0x74d3, 0x75d3, 0xef19, 0x5997, 0x90c0, 0x9961, 0x3c00, 0xa00c, 0x7e61, 0x7f61, 0x3064, 0x3c6e }, 16, 0x000b7be0, 1},
++	{{0x800b, 0x3600, 0xa00c, 0x6665, 0x6765, 0x3600, 0xa00c, 0x7f62, 0x7e62, 0x3600, 0xb804, 0x7556, 0x7454, 0x3600, 0xa004, 0x6565 }, 16, 0x000b7c00, 1},
++	{{0x6465, 0x3800, 0xaa08, 0x7552, 0x63f4, 0x74d3, 0x3600, 0xa008, 0x62f5, 0x6ff4, 0x3600, 0xb8c8, 0x6ef5, 0x6e57, 0x3c00, 0xa80c }, 16, 0x000b7c20, 1},
++	{{0x6f5a, 0x6665, 0x3064, 0x3c6e, 0x800b, 0x3400, 0xa004, 0x6765, 0x3c00, 0xa00c, 0x7e62, 0x7f62, 0x3064, 0x3c6e, 0x800b, 0x3600 }, 16, 0x000b7c40, 1},
++	{{0xa00c, 0x6665, 0x6765, 0x3600, 0xa00c, 0x6665, 0x6765, 0x3820, 0xa004, 0x7ac8, 0xcc5c, 0x44bb, 0x7a44, 0x92d0, 0xcc54, 0x90c0 }, 16, 0x000b7c60, 1},
++	{{0x3420, 0xa000, 0x46bd, 0xcd5d, 0xc565, 0x90c0, 0x90c0, 0x27ee, 0x9fe0, 0xe7ee, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000b7c80, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6d10, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3382 }, 16, 0x000b7ca0, 1},
++	{{0x3304, 0x8008, 0x9ac0, 0x280f, 0x8004, 0x90c0, 0x270c, 0x8020, 0x3600, 0xa100, 0x5017, 0x94bb, 0x2c7d, 0xe7ec, 0x4417, 0x0085 }, 16, 0x000b7cc0, 1},
++	{{0x32e0, 0x8008, 0x7270, 0x8417, 0x3e80, 0x32e0, 0x8008, 0x90c0, 0xee41, 0x94c0, 0x7941, 0x97a6, 0x7277, 0x81f9, 0x6569, 0x802d }, 16, 0x000b7ce0, 1},
++	{{0x9ac0, 0x75d2, 0xce42, 0x3b80, 0x32e0, 0x8008, 0x39e1, 0x3a80, 0x32e0, 0x8008, 0x94c0, 0xcc43, 0xeb1e, 0x97bb, 0x2c17, 0xec1a }, 16, 0x000b7d00, 1},
++	{{0x91bc, 0x6c84, 0x7071, 0x92c2, 0x7961, 0x9cc0, 0x7d41, 0x6f10, 0x3c20, 0x2206, 0x800c, 0xf943, 0x96c0, 0xcd42, 0x2700, 0x8081 }, 16, 0x000b7d20, 1},
++	{{0x3e80, 0x3118, 0x8008, 0xed1c, 0x5455, 0xf444, 0x1110, 0xc581, 0x9ac0, 0xd4a1, 0xca46, 0x3d20, 0x2258, 0x800c, 0x8463, 0x94c0 }, 16, 0x000b7d40, 1},
++	{{0xed1a, 0xf745, 0xf646, 0x1256, 0xf3c4, 0x96c0, 0x61bd, 0xf547, 0xfd48, 0x9ac0, 0x3a61, 0x8005, 0xc84f, 0x3664, 0x8005, 0x3861 }, 16, 0x000b7d60, 1},
++	{{0x8005, 0xd811, 0xd444, 0x7c44, 0x98c0, 0xf042, 0x3284, 0x2b30, 0x800b, 0xf0c2, 0x3284, 0x2b50, 0x800b, 0x3750, 0xf0c2, 0x96c0 }, 16, 0x000b7d80, 1},
++	{{0x77d0, 0xfdc8, 0xc847, 0xf5c7, 0x98c0, 0x7ac1, 0x4e55, 0x2d0d, 0x8204, 0x5010, 0x7075, 0x81b1, 0x94c0, 0xf7c5, 0xf6c6, 0x3be1 }, 16, 0x000b7da0, 1},
++	{{0x3b44, 0xee42, 0x67ea, 0x8187, 0x96c0, 0xf9c3, 0x27eb, 0x9fe0, 0x1417, 0xe7eb, 0x94c0, 0x9e21, 0x9f21, 0x290a, 0x892c, 0x94c0 }, 16, 0x000b7dc0, 1},
++	{{0x9621, 0x9721, 0x9f70, 0x949a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6e10, 0x2704, 0x8081, 0x280a, 0x829e, 0xebea, 0x92c8 }, 16, 0x000b7de0, 1},
++	{{0x9483, 0x94c0, 0xf087, 0x95a1, 0x246a, 0x7861, 0x94c0, 0xf486, 0x844d, 0x96c0, 0x6c95, 0xf385, 0x9b40, 0x96c0, 0xda91, 0x2b03 }, 16, 0x000b7e00, 1},
++	{{0x8020, 0x66e1, 0x66e6, 0xda9d, 0x72f3, 0x90c0, 0x92c3, 0xc381, 0x98c7, 0x2103, 0x8028, 0x90c0, 0x939a, 0x94c0, 0x92a1, 0xf185 }, 16, 0x000b7e20, 1},
++	{{0x2ea8, 0xea41, 0xd915, 0x6561, 0x6566, 0xd91a, 0x7171, 0x90d0, 0x92c3, 0xc281, 0x92c3, 0x929a, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b7e40, 1},
++	{{0x98c0, 0x09c6, 0x38d0, 0x8008, 0xc381, 0x94c0, 0x9620, 0x9720, 0x96c0, 0xc683, 0x290c, 0x82c0, 0x98c0, 0x7456, 0x5714, 0x2100 }, 16, 0x000b7e60, 1},
++	{{0x8064, 0x96c0, 0x7657, 0x9e20, 0x9f20, 0x98c0, 0x6c7d, 0xeee8, 0x280f, 0x8002, 0x3840, 0xa000, 0x77d4, 0xc08a, 0xe748, 0x2f7c }, 16, 0x000b7e80, 1},
++	{{0x3020, 0x3333, 0x9573, 0x4716, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c08, 0x82c2, 0x3420, 0xa000, 0x5410, 0x3400, 0xa800, 0x76d4 }, 16, 0x000b7ea0, 1},
++	{{0x6d7d, 0x3400, 0xa004, 0x7655, 0x3a00, 0xa804, 0x6c7c, 0x32e4, 0x3c48, 0x8001, 0x3640, 0xa800, 0x74d4, 0x4417, 0x3e40, 0xa008 }, 16, 0x000b7ec0, 1},
++	{{0x77d0, 0x6c90, 0x0cc6, 0x38d0, 0x8008, 0xcaa2, 0x3c20, 0xa000, 0x6e90, 0x3b80, 0x3304, 0x8008, 0xc685, 0x9ac0, 0x2c0d, 0x82c4 }, 16, 0x000b7ee0, 1},
++	{{0x6c90, 0x2f0c, 0x8002, 0x94c0, 0x5415, 0x90bb, 0x3c20, 0xa000, 0x6c7d, 0x0085, 0x32e0, 0x8008, 0xc0a8, 0x3a40, 0xa000, 0x6c7c }, 16, 0x000b7f00, 1},
++	{{0xc8a4, 0x2482, 0x8000, 0x90c0, 0x041c, 0xc0fa, 0x3a40, 0xa000, 0x0ac6, 0x38d0, 0x8008, 0xcba5, 0x3a40, 0xa000, 0x3502, 0x378c }, 16, 0x000b7f20, 1},
++	{{0x800c, 0xc382, 0x9ac0, 0x2a0a, 0x82c6, 0x90c0, 0x2b00, 0x87c7, 0x3820, 0xa000, 0x5412, 0x2200, 0x8387, 0x3a40, 0xb80c, 0x6c7d }, 16, 0x000b7f40, 1},
++	{{0x7456, 0xf241, 0xcea0, 0x3600, 0xa904, 0x6c7c, 0xecf8, 0x3860, 0xa000, 0x4414, 0x2460, 0x9fff, 0x98c0, 0x08c6, 0x38d0, 0x8008 }, 16, 0x000b7f60, 1},
++	{{0xec45, 0x94c0, 0xeaec, 0xe9ec, 0x3820, 0xa000, 0xe8ed, 0x280d, 0x82c8, 0x1415, 0xe83b, 0x3800, 0xa004, 0x76d4, 0xea61, 0xe963 }, 16, 0x000b7f80, 1},
++	{{0x3400, 0xa804, 0x6d7d, 0x3400, 0xa800, 0x7655, 0x96c0, 0x6c7c, 0x2020, 0x8000, 0x949c, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xec5d }, 16, 0x000b7fa0, 1},
++	{{0x90c0, 0x2d0b, 0x82ca, 0x3420, 0xa000, 0x5713, 0x3420, 0xa000, 0x979a, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x82ce, 0x5415 }, 16, 0x000b7fc0, 1},
++	{{0x2c7c, 0xc090, 0x4411, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0d, 0x82d0, 0x3420, 0xa000, 0x5215, 0x3420, 0xa000, 0x4214, 0x98c0 }, 16, 0x000b7fe0, 1},
++	{{0x0dc6, 0x38d0, 0x8008, 0xec44, 0x90c0, 0x2d0b, 0x82d2, 0x3420, 0xa000, 0x5513, 0x3400, 0xa804, 0x6d7c, 0x3420, 0xa000, 0x459c }, 16, 0x000b8000, 1},
++	{{0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0d, 0x82d4, 0x3420, 0xa000, 0x5715, 0x3400, 0xa800, 0x7657, 0x2c7d, 0xc094, 0x3400, 0xa004 }, 16, 0x000b8020, 1},
++	{{0x77d4, 0x3400, 0xa804, 0x6f7c, 0x3420, 0xa000, 0x471c, 0x98c0, 0x0bc6, 0x38d0, 0x8008, 0xedec, 0x94c0, 0xed7c, 0xeaec, 0x3800 }, 16, 0x000b8040, 1},
++	{{0xa100, 0xea7b, 0x2b09, 0x82d6, 0x36a0, 0xa000, 0x5711, 0xebec, 0x3880, 0xa800, 0x7657, 0xeb7a, 0xefec, 0x38a0, 0xa000, 0x6c7d }, 16, 0x000b8060, 1},
++	{{0x7456, 0xef38, 0x3600, 0xa104, 0x77d4, 0xe8ec, 0x3640, 0xa904, 0x6f7c, 0xe83a, 0x3620, 0xa100, 0x4714, 0xeaec, 0x3a60, 0xa100 }, 16, 0x000b8080, 1},
++	{{0x09c6, 0x38d0, 0x8008, 0xea3e, 0x3480, 0xa000, 0xeeec, 0x38c0, 0xa100, 0xee78, 0x2909, 0x82d8, 0x36c0, 0xa000, 0x5211, 0xec3b }, 16, 0x000b80a0, 1},
++	{{0x351c, 0x800f, 0x6c7d, 0x949d, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x82d8, 0x3420, 0xa000, 0x5215, 0x3600, 0xa804, 0x34c9 }, 16, 0x000b80c0, 1},
++	{{0x8104, 0x3400, 0xa800, 0x7571, 0x6e7d, 0x969a, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x82da, 0x3420, 0xa000, 0x5215, 0x3420 }, 16, 0x000b80e0, 1},
++	{{0xa000, 0x4213, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0a, 0x82dc, 0x5612, 0x3600, 0xa004, 0x3d19, 0x80ff, 0x34a0, 0xa000, 0x4117 }, 16, 0x000b8100, 1},
++	{{0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x82dc, 0x3420, 0xa000, 0x5515, 0x3600, 0xa804, 0x3ac8, 0x8208, 0x34a0, 0xa000, 0x4010 }, 16, 0x000b8120, 1},
++	{{0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b, 0x82de, 0x5613, 0x3cce, 0x8104, 0x3600, 0xa004, 0x7576, 0xc55e, 0x3400, 0xa804, 0x6e7d }, 16, 0x000b8140, 1},
++	{{0x3640, 0xa104, 0xd724, 0x4612, 0x90c0, 0x3422, 0xa000, 0xc584, 0x34a2, 0xa000, 0x4512, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0a }, 16, 0x000b8160, 1},
++	{{0x82e6, 0x3420, 0xa000, 0x5012, 0x34a0, 0xa000, 0x401e, 0x3a40, 0xa000, 0x0dc6, 0x38d0, 0x8008, 0xeaee, 0xea68, 0x2d0d, 0x82e8 }, 16, 0x000b8180, 1},
++	{{0x5215, 0x3480, 0xa000, 0x4216, 0x3a00, 0xa100, 0x0bc6, 0x38d0, 0x8008, 0xee48, 0x90c0, 0x2b0d, 0x82e0, 0x3420, 0xa000, 0x5615 }, 16, 0x000b81a0, 1},
++	{{0x3660, 0xa000, 0x4612, 0xc683, 0x5911, 0x90c0, 0x3480, 0xa000, 0xec39, 0x34a0, 0xa000, 0x4c16, 0x3480, 0xa000, 0xee78, 0x34a0 }, 16, 0x000b81c0, 1},
++	{{0xa000, 0x969e, 0x3420, 0xa000, 0x939c, 0xec51, 0x939c, 0xec43, 0x94c0, 0xedec, 0x939c, 0x94c0, 0xeaec, 0xed62, 0x94c0, 0x939d }, 16, 0x000b81e0, 1},
++	{{0xea61, 0x94c0, 0x939a, 0xec53, 0x3a20, 0xa000, 0x4414, 0x32e4, 0x3c8a, 0x8001, 0x3480, 0xa000, 0x4515, 0x98c0, 0x6c90, 0xc556 }, 16, 0x000b8200, 1},
++	{{0x2c00, 0x8848, 0x2300, 0x8081, 0x3620, 0xa000, 0xe8ed, 0xf341, 0x32e4, 0x3c8a, 0x8001, 0xe83c, 0x98c0, 0x6c90, 0xc556, 0x2900 }, 16, 0x000b8220, 1},
++	{{0x8d68, 0x2300, 0x8102, 0x3620, 0xa000, 0xe8ed, 0xf341, 0x32e4, 0x3c8a, 0x8001, 0xe839, 0x98c0, 0x6c90, 0xc556, 0x2900, 0x8a4d }, 16, 0x000b8240, 1},
++	{{0x2500, 0x8204, 0x3620, 0xa000, 0xe8ed, 0xf541, 0x32e4, 0x3c8a, 0x8001, 0xe839, 0x98c0, 0x6c90, 0xc556, 0x2d00, 0x8849, 0x3a20 }, 16, 0x000b8260, 1},
++	{{0xa000, 0x3360, 0x3a54, 0x805f, 0x9763, 0x3a80, 0xa000, 0xed3d, 0x3880, 0x3296, 0x8008, 0x3480, 0xa000, 0x919d, 0x1158, 0x0102 }, 16, 0x000b8280, 1},
++	{{0x2a20, 0x800c, 0x1517, 0x3f20, 0x2206, 0x800c, 0x3c00, 0xa060, 0x3464, 0x8005, 0x90c0, 0x3663, 0x8005, 0x3600, 0xa040, 0x3064 }, 16, 0x000b82a0, 1},
++	{{0x8005, 0xd814, 0xd443, 0x6274, 0x2e74, 0x5158, 0x3554, 0x6274, 0x96d0, 0x6e74, 0x774a, 0x5158, 0x3554, 0x2274, 0x465f, 0x9ac0 }, 16, 0x000b82c0, 1},
++	{{0x6e74, 0x2600, 0x8081, 0x74ca, 0xc381, 0x34cc, 0x015f, 0x3820, 0x2104, 0x800c, 0x4157, 0x32e4, 0x3c48, 0x8001, 0x3457, 0x74d3 }, 16, 0x000b82e0, 1},
++	{{0x98c0, 0x3102, 0x8080, 0x7b61, 0x79c1, 0x3d68, 0x676a, 0x7d48, 0x6565, 0x7d48, 0x94c0, 0x755a, 0x81e2, 0x4258, 0x32e4, 0x3c48 }, 16, 0x000b8300, 1},
++	{{0x8001, 0x34d5, 0x3020, 0x3333, 0x9573, 0x98c0, 0x3300, 0x2000, 0x8001, 0xe8ee, 0x9ac0, 0xd5c0, 0x7c41, 0x3100, 0x2000, 0x8001 }, 16, 0x000b8320, 1},
++	{{0x9cc0, 0x6cd1, 0x2401, 0x8081, 0x65ea, 0x2501, 0x8081, 0x9ac7, 0x64ea, 0x79c1, 0x3f20, 0x2252, 0x800c, 0x9ac7, 0x75c3, 0x78c1 }, 16, 0x000b8340, 1},
++	{{0x3900, 0x2a20, 0x800c, 0x344b, 0x74c1, 0x2c7d, 0x34c9, 0x0023, 0x2250, 0x800c, 0x2d7d, 0x0423, 0x2250, 0x800c, 0x0157, 0x3264 }, 16, 0x000b8360, 1},
++	{{0x3cb0, 0x800b, 0x4557, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8380, 1},
++	{{0x3064, 0x3e60, 0x800b, 0x3820, 0x20bc, 0x800c, 0x90c0, 0x90c0, 0x3e00, 0xa10c, 0x7456, 0x74d7, 0x3d20, 0x20ca, 0x800c, 0xe8ee }, 16, 0x000b83a0, 1},
++	{{0x9ac0, 0x2709, 0x8088, 0x90c0, 0x2400, 0x8081, 0x1015, 0xed53, 0x96c0, 0x6c7d, 0x96bd, 0xe7e9, 0x3c00, 0xa100, 0x6769, 0xe9ef }, 16, 0x000b83c0, 1},
++	{{0x3e00, 0x2cbe, 0x800c, 0x9ac0, 0x27e9, 0x9f78, 0x90c0, 0x2518, 0x80c6, 0x2704, 0x8080, 0x96c0, 0xebee, 0x2700, 0x8081, 0x95a3 }, 16, 0x000b83e0, 1},
++	{{0x94c8, 0x9581, 0x95a3, 0x96c0, 0x6f10, 0xeaed, 0x9a47, 0x96c0, 0xea6f, 0x2a03, 0x8018, 0x94c0, 0x9599, 0x5512, 0x98c0, 0xeaee }, 16, 0x000b8400, 1},
++	{{0x3001, 0x2d3f, 0x800c, 0x94c0, 0x6d10, 0x91ba, 0x64e9, 0x8031, 0x98c0, 0x66ea, 0x74d5, 0xc946, 0xc840, 0x94c0, 0x78e1, 0x8423 }, 16, 0x000b8420, 1},
++	{{0x9f41, 0xe918, 0x96c0, 0x93b9, 0x2909, 0x8081, 0x2103, 0x800e, 0x98c8, 0xdd1b, 0x93b9, 0x2909, 0x8081, 0xdd1b, 0x929a, 0x94d0 }, 16, 0x000b8440, 1},
++	{{0x7b41, 0xea41, 0x90c0, 0x90c0, 0x9cc0, 0x7ae1, 0x2e09, 0x8285, 0x6f10, 0x2b03, 0x8028, 0x94c0, 0x93b9, 0x9b47, 0x96c0, 0x72e3 }, 16, 0x000b8460, 1},
++	{{0x27e8, 0x9f78, 0x94c1, 0x79c1, 0x6d10, 0x94c1, 0x9399, 0x9299, 0x98c0, 0x6461, 0x7b41, 0x97b9, 0xcc46, 0x96c0, 0x3e17, 0x8081 }, 16, 0x000b8480, 1},
++	{{0x92a0, 0xd7c0, 0xce47, 0x90d0, 0xee1c, 0x929e, 0x2f10, 0xebed, 0xeb62, 0x95bb, 0x26e9, 0x6e90, 0x2518, 0x80fe, 0x266a, 0x34d4 }, 16, 0x000b84a0, 1},
++	{{0x3800, 0x2cbe, 0x800c, 0x8447, 0xd622, 0x801f, 0x96c0, 0x9b41, 0x2b03, 0x800c, 0x90c0, 0x90c0, 0x92d0, 0x97a0, 0x67e9, 0x92c3 }, 16, 0x000b84c0, 1},
++	{{0x7b41, 0x3184, 0x250c, 0x800b, 0x94c0, 0x78e2, 0x90a0, 0x96c0, 0x6469, 0x9f41, 0x90a0, 0x90c0, 0x90c0, 0x96cf, 0x6469, 0x7b41 }, 16, 0x000b84e0, 1},
++	{{0x90a0, 0x94c7, 0x6469, 0x7b41, 0x92c3, 0x7b41, 0x9ac0, 0x3614, 0x8080, 0xc844, 0x2700, 0x8081, 0x94c0, 0x6c97, 0x8057, 0x98c0 }, 16, 0x000b8500, 1},
++	{{0xd4a2, 0x3001, 0x2cbe, 0x800c, 0xcc40, 0x8020, 0xec18, 0x96c0, 0x9b41, 0x2b03, 0x800c, 0x90c0, 0x90c0, 0x92d0, 0x92a4, 0x6569 }, 16, 0x000b8520, 1},
++	{{0x92c3, 0x7ac1, 0x3184, 0x256e, 0x800b, 0x94c0, 0x78e2, 0x92a4, 0x96c0, 0x6569, 0x9f41, 0x92a4, 0x90c0, 0x90c0, 0x96cf, 0x6569 }, 16, 0x000b8540, 1},
++	{{0x7ac1, 0x92a4, 0x94c7, 0x6569, 0x7ac1, 0x92c3, 0x7ac1, 0x72f6, 0x8429, 0x9cc0, 0x6d90, 0x3614, 0x8080, 0xc844, 0x2700, 0x8081 }, 16, 0x000b8560, 1},
++	{{0x8017, 0x3201, 0x2cbe, 0x800c, 0x2d17, 0xc942, 0x9f42, 0xe918, 0x90c0, 0x92c8, 0x9381, 0x6e90, 0x9ac0, 0x6f5a, 0xed71, 0x3900 }, 16, 0x000b8580, 1},
++	{{0x2cbe, 0x800c, 0x5015, 0x3076, 0x6c10, 0x840d, 0x2704, 0x8081, 0x90c0, 0x92c8, 0x9081, 0x3c20, 0xac00, 0x77d1, 0x27ee, 0x9f78 }, 16, 0x000b85a0, 1},
++	{{0x7750, 0xefe9, 0xe7ee, 0x3620, 0xa000, 0xeee8, 0x9f71, 0x90c0, 0x3a00, 0xa00c, 0x7456, 0x74d7, 0x2704, 0x8081, 0x3880, 0xa100 }, 16, 0x000b85c0, 1},
++	{{0xe8ee, 0x290b, 0x819c, 0x36c0, 0xa000, 0xe9ef, 0xeeeb, 0x96c0, 0xe84b, 0x2600, 0x8081, 0x92d0, 0x92f8, 0x421e, 0x3840, 0xa000 }, 16, 0x000b85e0, 1},
++	{{0xeae8, 0x2b0e, 0x8102, 0x94c0, 0xefee, 0xea61, 0x94c0, 0x92a7, 0x93fa, 0x3a40, 0xa000, 0x280d, 0x8001, 0xd121, 0xeceb, 0x98c7 }, 16, 0x000b8600, 1},
++	{{0x2b03, 0x8026, 0x90c0, 0x7573, 0x94c1, 0x91fd, 0x94f8, 0x98c7, 0x2304, 0x8080, 0x90c0, 0x6e98, 0x96c1, 0x75d5, 0x4414, 0x4514 }, 16, 0x000b8620, 1},
++	{{0x92c2, 0x93f8, 0x94c0, 0x95a7, 0xec42, 0xd2a1, 0x92c3, 0x7673, 0x94d1, 0x97fd, 0x95f8, 0x94c1, 0x6fb7, 0x4514, 0x96c1, 0x75d7 }, 16, 0x000b8640, 1},
++	{{0x93f8, 0x4714, 0x9ac0, 0x2304, 0x8082, 0x90c0, 0x2b03, 0x8010, 0x2909, 0x831f, 0x91a9, 0xd0a1, 0x90c0, 0x92c2, 0x94f8, 0x94c6 }, 16, 0x000b8660, 1},
++	{{0x801e, 0x4416, 0x92c2, 0x93f8, 0x96c0, 0x76f3, 0x94fd, 0x5216, 0x6c95, 0x75f1, 0x71f2, 0x90c0, 0x92c2, 0x4116, 0x92d0, 0xee62 }, 16, 0x000b8680, 1},
++	{{0x90c0, 0x90c0, 0x96c0, 0x9b46, 0x2b03, 0x800e, 0x3420, 0xa000, 0xeceb, 0x94c0, 0x5014, 0x92fa, 0x7170, 0x90d0, 0x92c2, 0x4214 }, 16, 0x000b86a0, 1},
++	{{0xec42, 0x3820, 0xa000, 0xebeb, 0x2b03, 0x8020, 0x96c0, 0x551b, 0x2304, 0x8080, 0x26e4, 0x3980, 0x321a, 0x8008, 0x7ec1, 0xcf45 }, 16, 0x000b86c0, 1},
++	{{0x90c0, 0x131b, 0xef19, 0x25e4, 0x5017, 0x3610, 0xa100, 0x7dc1, 0x401b, 0xcf43, 0x90c0, 0x3640, 0xa800, 0x77d1, 0xeee8, 0xef19 }, 16, 0x000b86e0, 1},
++	{{0x3640, 0xa000, 0x5617, 0xefe9, 0x9f70, 0x3600, 0xa900, 0x7750, 0x4613, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8700, 1},
++	{{0x3a00, 0xa00c, 0x75d7, 0x74d6, 0xe748, 0xe8ef, 0x10e0, 0xbffb, 0x9ac0, 0x27ef, 0x9fec, 0x90c0, 0x27ec, 0x9fe4, 0x1097, 0xf6c6 }, 16, 0x000b8720, 1},
++	{{0x3f6f, 0x3c6f, 0x1594, 0xf3c8, 0x9ac0, 0x7def, 0x27ed, 0x9ffc, 0x7eef, 0xefe8, 0x9ac0, 0x34c7, 0x8003, 0x90c0, 0x3402, 0x8005 }, 16, 0x000b8740, 1},
++	{{0x9ac0, 0x34c1, 0x8005, 0x90c0, 0x30c7, 0x8003, 0x3c00, 0xa002, 0x3002, 0x8005, 0xdb97, 0x3460, 0x8000, 0x3c00, 0xa002, 0x30c1 }, 16, 0x000b8760, 1},
++	{{0x8005, 0xd912, 0x3060, 0x8000, 0x3e00, 0xb00a, 0x36c4, 0x8003, 0xd891, 0x3602, 0x8005, 0xd810, 0x3e00, 0xa200, 0x3663, 0x8000 }, 16, 0x000b8780, 1},
++	{{0xd542, 0x36c6, 0x8005, 0xd7c4, 0x3a00, 0xa001, 0xd4c6, 0x6561, 0xd443, 0x67e1, 0x3a00, 0xa001, 0x6565, 0x64e1, 0x6461, 0x67e5 }, 16, 0x000b87a0, 1},
++	{{0x3a00, 0xa401, 0x6d4b, 0x64e5, 0x6465, 0x77d3, 0x3800, 0xb800, 0x6d31, 0x7751, 0xf242, 0x4295, 0x94c0, 0xf0c2, 0xf1c1, 0x009a }, 16, 0x000b87c0, 1},
++	{{0xe768, 0x9f70, 0x4192, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x64e9, 0x77d1, 0x6d10, 0x9620, 0x9720, 0x94c0, 0x9e20 }, 16, 0x000b87e0, 1},
++	{{0x9f20, 0x94c6, 0xe748, 0xc781, 0x98c0, 0x67e8, 0xf0ca, 0x27ef, 0x9fdc, 0x96c7, 0x6466, 0x67e6, 0x5197, 0x98c0, 0x7077, 0x75d1 }, 16, 0x000b8800, 1},
++	{{0xc590, 0xf4ca, 0x25e6, 0x2666, 0xeeea, 0x92c2, 0xf7ca, 0x92c2, 0x67e6, 0x71f7, 0xd3d1, 0x92c2, 0x67e6, 0xd097, 0x64e4, 0x6f05 }, 16, 0x000b8820, 1},
++	{{0x6e7c, 0xd79e, 0x9ac0, 0xd61e, 0x74f7, 0x32a4, 0x3590, 0x800b, 0x7474, 0x34f7, 0x1797, 0xf4ca, 0x35d7, 0x2668, 0xf042, 0x94c7 }, 16, 0x000b8840, 1},
++	{{0x65e6, 0x6464, 0x9ac7, 0xd59e, 0xf042, 0x32a4, 0x3590, 0x800b, 0x7473, 0x98c0, 0x27ef, 0x9ffc, 0x67e8, 0xeaee, 0x94c7, 0x4097 }, 16, 0x000b8860, 1},
++	{{0x6464, 0x92c3, 0x4097, 0x94c0, 0xf1c2, 0xf7c1, 0x019a, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x4792, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000b8880, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe758, 0xefea, 0x96c0, 0xf1ce, 0x27ed, 0x9fcc, 0x64e6, 0x96c0, 0x3611 }, 16, 0x000b88a0, 1},
++	{{0x80ff, 0x5195, 0x94c0, 0x64e6, 0x801b, 0x3611, 0x80ff, 0x94c0, 0xf6ce, 0x8011, 0x7f47, 0xf64e, 0x5195, 0x7cc7, 0x4195, 0x96c0 }, 16, 0x000b88c0, 1},
++	{{0xf5ce, 0x27e8, 0x9fcc, 0x26e9, 0x5590, 0x8417, 0x66e9, 0x92c2, 0x6f10, 0x96c2, 0xf646, 0x27ec, 0x9fec, 0x94c6, 0x80b1, 0x4694 }, 16, 0x000b88e0, 1},
++	{{0x96c0, 0x6f90, 0xf0ce, 0xf1cd, 0x94c0, 0xf044, 0xf143, 0x96c0, 0xf0c4, 0x27ea, 0x9ff4, 0x1592, 0x04c6, 0x3664, 0x8009, 0x26e9 }, 16, 0x000b8900, 1},
++	{{0x6c7c, 0x806e, 0x98c6, 0x04c2, 0x3664, 0x8009, 0x6466, 0x9cc0, 0x6469, 0xd315, 0xc1fe, 0x3308, 0x2000, 0x8000, 0x96c0, 0xd055 }, 16, 0x000b8920, 1},
++	{{0x6764, 0x8054, 0x94c6, 0xdf01, 0x6466, 0xd110, 0x6564, 0xdd01, 0x6e7d, 0x94c0, 0xd696, 0xd416, 0x2972, 0x6030, 0x7652, 0x6c7c }, 16, 0x000b8940, 1},
++	{{0x7273, 0x94c2, 0x7c62, 0x7d62, 0x9ac6, 0x6e52, 0xc781, 0x3284, 0x2b60, 0x800b, 0xd81c, 0xd72f, 0x92c2, 0x7b70, 0x94c1, 0xc490 }, 16, 0x000b8960, 1},
++	{{0xd41e, 0x92c3, 0x6db6, 0x94c7, 0xd3a1, 0xd413, 0x92c2, 0x7c41, 0x96c0, 0x74d0, 0xf5ce, 0xf4cd, 0x96c0, 0x64e1, 0xf542, 0xf441 }, 16, 0x000b8980, 1},
++	{{0x3284, 0x27f0, 0x800b, 0x27ea, 0x9fe8, 0x94c0, 0xf3c6, 0xf6c5, 0x039f, 0xe778, 0x4697, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000b89a0, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x32a4, 0x34c0, 0x800b, 0x3451, 0x74d0, 0x96c0, 0x30c8, 0x97c1 }, 16, 0x000b89c0, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3800, 0xa004, 0x77d6, 0xcc57, 0xe750, 0x3480, 0xa000, 0xe8ef }, 16, 0x000b89e0, 1},
++	{{0xc56c, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x3e00, 0xa002, 0x6d10, 0x6c10, 0x6f10, 0x7754, 0xf5c7, 0xc184, 0x9ac0, 0x6d7d, 0x3cc0 }, 16, 0x000b8a00, 1},
++	{{0x3668, 0x8009, 0xf244, 0x9ac0, 0x2700, 0x8081, 0x75d5, 0x290b, 0x8b64, 0x9ac0, 0x0afc, 0x9ff4, 0x79e1, 0x2b02, 0x8102, 0x7dc1 }, 16, 0x000b8a20, 1},
++	{{0xca43, 0x90c0, 0xea1c, 0x98c0, 0x5352, 0x90c0, 0x90c0, 0x90c0, 0x3e00, 0xa009, 0x6d10, 0x74d7, 0x76d0, 0x7655, 0xcd40, 0xf642 }, 16, 0x000b8a40, 1},
++	{{0x3800, 0xa004, 0x75d2, 0x0efc, 0x9ffc, 0xed18, 0x2d0f, 0x8004, 0x11bd, 0x3284, 0x29d0, 0x800b, 0x7451, 0x37d0, 0x11bf, 0x3284 }, 16, 0x000b8a60, 1},
++	{{0x29d0, 0x800b, 0x7451, 0x3c20, 0xa006, 0x65e9, 0x6cc3, 0x7a61, 0x79c1, 0xf2c2, 0x3620, 0xa000, 0x0afe, 0x9ffc, 0x3626, 0xb000 }, 16, 0x000b8a80, 1},
++	{{0xf0c4, 0x6d58, 0x3a26, 0xa000, 0x90c0, 0xf242, 0x08fe, 0x9ff4, 0x3806, 0xa044, 0x6e51, 0x0afc, 0x9ffc, 0x3626, 0xa000, 0xf444 }, 16, 0x000b8aa0, 1},
++	{{0x666a, 0x81ae, 0x3622, 0xa000, 0x0cfc, 0x9ff4, 0x3800, 0xaa00, 0x77d1, 0x6275, 0x7455, 0x3be1, 0x2e75, 0x7848, 0x27ea, 0x449b }, 16, 0x000b8ac0, 1},
++	{{0x8171, 0x3a00, 0xa200, 0x2700, 0x8930, 0x7656, 0xc94b, 0x96c0, 0xd7c3, 0xf6c4, 0xf0c4, 0x96c0, 0xca47, 0x0efe, 0x9ff4, 0x16c0 }, 16, 0x000b8ae0, 1},
++	{{0x3660, 0x8009, 0x069a, 0x08fe, 0x9ff4, 0x2465, 0x05c6, 0x3660, 0x8009, 0x4592, 0xc564, 0x90c0, 0x90c0, 0x3800, 0xa800, 0x7757 }, 16, 0x000b8b00, 1},
++	{{0xe770, 0xcc5f, 0x3620, 0xa000, 0xefe8, 0x9f71, 0x90c0, 0x90c0, 0x98c0, 0x3309, 0x2000, 0x8000, 0xe748, 0xd5c0, 0x98c0, 0xf342 }, 16, 0x000b8b20, 1},
++	{{0x3224, 0x2590, 0x800a, 0xf0c2, 0xe768, 0x9f71, 0x90c0, 0x90c0, 0x3124, 0x2590, 0x800a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8b40, 1},
++	{{0x1005, 0xa03b, 0x90c0, 0x2161, 0x8000, 0x98c0, 0xd110, 0xd210, 0x6466, 0xf5c1, 0x35d1, 0x6469, 0x98c0, 0x7941, 0x6664, 0x2b03 }, 16, 0x000b8b60, 1},
++	{{0x8022, 0x96c2, 0x3184, 0x2bb2, 0x800b, 0x98c0, 0x35fa, 0x9ffe, 0x7e61, 0x9346, 0x94c0, 0xd41a, 0x7a47, 0x3810, 0xa00d, 0x6039 }, 16, 0x000b8b80, 1},
++	{{0x60b1, 0x6970, 0x3400, 0xa844, 0x6058, 0x3400, 0xa840, 0x6cd0, 0x6031, 0x94c0, 0x9f70, 0xd41c, 0xc565, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8ba0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x3c80, 0xa000, 0x280f, 0x8032, 0x90c0, 0x290c, 0x8d82, 0x94c0, 0x9e20, 0x9f20, 0x3880, 0xa000, 0x5317 }, 16, 0x000b8bc0, 1},
++	{{0x270f, 0x8050, 0x98c0, 0x65ea, 0xe7ef, 0x290e, 0x8d6e, 0x96c0, 0x841d, 0x27ed, 0x9fc4, 0x9f43, 0x27e8, 0x9fb0, 0x90c0, 0x94d0 }, 16, 0x000b8be0, 1},
++	{{0x94a6, 0x90a4, 0x94c0, 0x9480, 0x9085, 0x9ac0, 0x27eb, 0x9fd8, 0x65ea, 0x27ee, 0x9fb0, 0x8469, 0x96c0, 0x9a43, 0x2a03, 0x800a }, 16, 0x000b8c00, 1},
++	{{0x90c0, 0x9cc0, 0x65ea, 0x6c10, 0x7753, 0x95a6, 0x27e8, 0x9fb0, 0x8447, 0xd5a2, 0x801f, 0x96c0, 0x9b46, 0x2b03, 0x800c, 0x90c0 }, 16, 0x000b8c20, 1},
++	{{0x90c0, 0x92d0, 0x97a0, 0x72e7, 0x92c2, 0x7841, 0x3184, 0x2c76, 0x800b, 0x94c0, 0x7b62, 0x94a0, 0x96c0, 0x72e4, 0x9f46, 0x94a0 }, 16, 0x000b8c40, 1},
++	{{0x90c0, 0x90c0, 0x96ce, 0x72e4, 0x7841, 0x94a0, 0x94c6, 0x72e4, 0x7841, 0x92c2, 0x7841, 0x92d0, 0x9083, 0x90c0, 0x90c0, 0x9ac0 }, 16, 0x000b8c60, 1},
++	{{0x27ed, 0x9fec, 0x65ea, 0x27e8, 0x9fc4, 0x8473, 0x96c0, 0x9a43, 0x2a03, 0x8014, 0x9ac0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8c80, 1},
++	{{0x9cc0, 0x65ea, 0x6c10, 0x74d3, 0x95a0, 0x27ea, 0x9fc4, 0x8447, 0xd5a2, 0x801f, 0x96c0, 0x9b41, 0x2b03, 0x800c, 0x90c0, 0x90c0 }, 16, 0x000b8ca0, 1},
++	{{0x92d0, 0x91a2, 0x72e1, 0x92c2, 0x7841, 0x3184, 0x2cf4, 0x800b, 0x94c0, 0x78e2, 0x96a2, 0x96c0, 0x72e6, 0x9f41, 0x96a2, 0x90c0 }, 16, 0x000b8cc0, 1},
++	{{0x90c0, 0x96ce, 0x72e6, 0x7841, 0x96a2, 0x94c6, 0x72e6, 0x7841, 0x92c2, 0x7841, 0x92d0, 0x9085, 0x90c0, 0x90c0, 0x9cc0, 0x65ea }, 16, 0x000b8ce0, 1},
++	{{0x27ef, 0x9fd8, 0x7753, 0x27e8, 0x9fec, 0x96c0, 0x7b61, 0x95a7, 0x8453, 0x98c0, 0xd2a1, 0x9b46, 0x2b03, 0x8020, 0x96c0, 0x94a0 }, 16, 0x000b8d00, 1},
++	{{0x27eb, 0x9fc4, 0x98c6, 0x27ea, 0x9fb0, 0x90c0, 0x6d10, 0x2103, 0x8020, 0x96c6, 0xd221, 0x929a, 0x90a7, 0x94d6, 0x94a0, 0x6f90 }, 16, 0x000b8d20, 1},
++	{{0x96c6, 0xd021, 0x979b, 0xea41, 0x94c6, 0xeb41, 0x6d10, 0x94c6, 0xd221, 0x929a, 0x92c2, 0x6e10, 0x92c2, 0x949b, 0x3600, 0xa004 }, 16, 0x000b8d40, 1},
++	{{0x6d90, 0x9754, 0x9ac0, 0x27ef, 0x9fec, 0x90c0, 0x27ee, 0x9fd8, 0x3668, 0xa000, 0x9386, 0x9387, 0x3e00, 0xa004, 0x6d10, 0x27e8 }, 16, 0x000b8d60, 1},
++	{{0x9fb0, 0x65ea, 0x27eb, 0x9fc4, 0x96c0, 0x79e1, 0x96a0, 0x8465, 0x98c0, 0x6769, 0x9b43, 0x2b03, 0x8030, 0x3807, 0xa004, 0x65e1 }, 16, 0x000b8d80, 1},
++	{{0x27ea, 0x9fd8, 0x3807, 0xa001, 0x9682, 0x95a3, 0x79c1, 0x9ac0, 0x27ee, 0x9fec, 0x66e9, 0x2103, 0x8034, 0x94c0, 0x90c0, 0x90c0 }, 16, 0x000b8da0, 1},
++	{{0x3807, 0xa001, 0x9586, 0x97a0, 0x7941, 0x94c0, 0x67e9, 0x95a3, 0x3413, 0xa004, 0x65e1, 0x3807, 0xa001, 0x9782, 0x66e9, 0x79c1 }, 16, 0x000b8dc0, 1},
++	{{0x90c0, 0x3403, 0xa004, 0x7941, 0x92c3, 0x959e, 0x3e00, 0xa004, 0x65e1, 0x6e90, 0x6c90, 0x6c10, 0x27ea, 0x9fd8, 0x3c00, 0xb004 }, 16, 0x000b8de0, 1},
++	{{0x65e9, 0x77d3, 0x6d10, 0x290c, 0x8940, 0x94c0, 0x2518, 0x8136, 0x94c0, 0x92ba, 0xea41, 0x6569, 0x8409, 0x7841, 0x73f0, 0x81f3 }, 16, 0x000b8e00, 1},
++	{{0x73e0, 0x98c6, 0x2518, 0x80b4, 0x90c0, 0x6f10, 0x3c00, 0xb000, 0x73f0, 0x6d93, 0x3102, 0x8001, 0xce40, 0x96c0, 0x849b, 0x27ef }, 16, 0x000b8e20, 1},
++	{{0x9fd8, 0x96c0, 0x9a43, 0x2a03, 0x800e, 0x94c0, 0xee1f, 0x90c0, 0x94c0, 0x90a6, 0xc481, 0x6469, 0x8075, 0x3c00, 0xb000, 0x73f2 }, 16, 0x000b8e40, 1},
++	{{0x6d9d, 0xca42, 0x27ed, 0x9fd8, 0x844d, 0x94c0, 0xd5a2, 0xed1a, 0x8021, 0x96c0, 0x9b43, 0x2b03, 0x800e, 0x90c0, 0x92c0, 0x90c0 }, 16, 0x000b8e60, 1},
++	{{0x92d0, 0x93a5, 0x71e0, 0x92c2, 0x7a41, 0x3184, 0x2eb4, 0x800b, 0x94c0, 0x79e2, 0x96a5, 0x96c0, 0x7360, 0x9f43, 0x96a5, 0x90c0 }, 16, 0x000b8e80, 1},
++	{{0x90c0, 0x96ce, 0x7360, 0x7a41, 0x96a5, 0x94c6, 0x7360, 0x7a41, 0x92c2, 0x7a41, 0x7271, 0x96c0, 0xd2d0, 0xd0d4, 0x8017, 0x70e4 }, 16, 0x000b8ea0, 1},
++	{{0x840d, 0x66e1, 0x72f0, 0x94c0, 0xd2d0, 0xd0d4, 0x92d0, 0x7941, 0x90c0, 0x90c0, 0x7755, 0x3e00, 0xa004, 0x65ea, 0x6c10, 0x6c90 }, 16, 0x000b8ec0, 1},
++	{{0x766e, 0x27ef, 0x9fd8, 0x96c6, 0x7a6a, 0x776e, 0x8437, 0x3e40, 0xa000, 0x7556, 0x3d07, 0x800a, 0x9b43, 0x2b03, 0x8010, 0x96a7 }, 16, 0x000b8ee0, 1},
++	{{0x7276, 0x800b, 0x7377, 0x8408, 0x92c3, 0xc581, 0x6e90, 0x92d0, 0xd2a1, 0x94c2, 0xd446, 0x78c1, 0x90c0, 0x7752, 0x96c0, 0x64e9 }, 16, 0x000b8f00, 1},
++	{{0x290b, 0x8940, 0x8013, 0x33e4, 0x3c48, 0x8001, 0x98c0, 0x909b, 0x3184, 0x2f42, 0x800b, 0x98c0, 0x969b, 0x3184, 0x2f42, 0x800b }, 16, 0x000b8f20, 1},
++	{{0x929c, 0x3e00, 0xb004, 0x6569, 0x77d2, 0x6e10, 0x6f10, 0x27ec, 0x9fec, 0x9cc0, 0x6d90, 0x2908, 0x8941, 0x6d10, 0x2518, 0x8134 }, 16, 0x000b8f40, 1},
++	{{0x94c0, 0x95bc, 0xec41, 0x66e9, 0x8409, 0x79c1, 0x73f3, 0x81f3, 0x73e3, 0x94c6, 0x80ab, 0x6e90, 0x9cc0, 0x73f3, 0x3705, 0x8001 }, 16, 0x000b8f60, 1},
++	{{0xca43, 0x27ed, 0x9fec, 0x3600, 0xa800, 0x6dbd, 0x8495, 0x96c0, 0x9a43, 0x2a03, 0x800a, 0xea1d, 0x94c0, 0x93a2, 0xc281, 0x65e9 }, 16, 0x000b8f80, 1},
++	{{0x8073, 0x3c00, 0xb000, 0x73f5, 0x6ca9, 0xcd45, 0x27ec, 0x9fec, 0x844b, 0x94c0, 0xd4a2, 0xec1d, 0x801f, 0x96c0, 0x9b41, 0x2b03 }, 16, 0x000b8fa0, 1},
++	{{0x800c, 0x90c0, 0x90c0, 0x92d0, 0x91a4, 0x70e3, 0x92c2, 0x7941, 0x3184, 0x2ffa, 0x800b, 0x94c0, 0x78e2, 0x90a4, 0x96c0, 0x7063 }, 16, 0x000b8fc0, 1},
++	{{0x9f41, 0x90a4, 0x90c0, 0x90c0, 0x96ce, 0x7063, 0x7941, 0x90a4, 0x94c6, 0x7063, 0x7941, 0x92c2, 0x7941, 0x7176, 0x96c0, 0xd253 }, 16, 0x000b8fe0, 1},
++	{{0xd352, 0x8017, 0x7362, 0x840d, 0x6661, 0x7273, 0x94c0, 0xd253, 0xd352, 0x92d0, 0x7ac1, 0x90c0, 0x90c0, 0x76d4, 0x3e00, 0xa004 }, 16, 0x000b9000, 1},
++	{{0x656a, 0x6c10, 0x6c90, 0x77ed, 0x27ea, 0x9fec, 0x96c6, 0x7bea, 0x76ed, 0x8437, 0x3e40, 0xa000, 0x7555, 0x3b03, 0x800a, 0x9b42 }, 16, 0x000b9020, 1},
++	{{0x2b03, 0x8010, 0x95a2, 0x73f5, 0x800b, 0x72f3, 0x8408, 0x92c3, 0xc681, 0x6f10, 0x92d0, 0xd321, 0x94c2, 0xd445, 0x78c1, 0x90c0 }, 16, 0x000b9040, 1},
++	{{0x76d2, 0x96c0, 0x64e9, 0x2908, 0x8941, 0x8013, 0x33e4, 0x3c48, 0x8001, 0x98c0, 0x9098, 0x3184, 0x3088, 0x800b, 0x98c0, 0x9598 }, 16, 0x000b9060, 1},
++	{{0x3184, 0x3088, 0x800b, 0x9298, 0x96c0, 0x6c10, 0x27e9, 0x9fb0, 0xe7e9, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000b9080, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3880, 0xa000, 0xede9, 0x270b, 0x8048, 0x3600, 0xa100, 0xe7eb, 0xe8e8, 0xc56e }, 16, 0x000b90a0, 1},
++	{{0x1005, 0xa004, 0x90c0, 0x94c0, 0x6c10, 0x9742, 0x9ac0, 0x290e, 0x8d6a, 0x90c0, 0x27eb, 0x9fe8, 0x5516, 0x92c8, 0x9083, 0x3880 }, 16, 0x000b90c0, 1},
++	{{0xa000, 0xebee, 0x2900, 0x841e, 0x96c0, 0x9365, 0x2b03, 0x801a, 0x38c0, 0xa000, 0xeb39, 0x2d0d, 0x8108, 0x3660, 0xa000, 0xeaeb }, 16, 0x000b90e0, 1},
++	{{0xe8eb, 0x94d0, 0x5098, 0x579d, 0x6dc3, 0x439a, 0x94c0, 0x6e10, 0x9744, 0x27ed, 0x9fe0, 0x92c8, 0x9485, 0x98c0, 0x2d00, 0x8846 }, 16, 0x000b9100, 1},
++	{{0x6c10, 0x9742, 0xe8ee, 0x96c0, 0xe83d, 0x27ec, 0x9fe0, 0x27ea, 0x9fe1, 0x94d0, 0x909c, 0x909a, 0x94c0, 0xec42, 0xea42, 0x96c0 }, 16, 0x000b9120, 1},
++	{{0xebe8, 0x2704, 0x8080, 0x97a3, 0x96c0, 0x67e9, 0x2300, 0x8081, 0x94d0, 0xd25f, 0x97a3, 0x67e9, 0x98c0, 0xd25f, 0xc281, 0x27ed }, 16, 0x000b9140, 1},
++	{{0x9fe1, 0x2669, 0x047c, 0x9fe0, 0x94c6, 0x804c, 0x6c10, 0x92c2, 0xf045, 0x98c0, 0x6c10, 0x9b43, 0x2b03, 0x800c, 0xe9e8, 0x97a1 }, 16, 0x000b9160, 1},
++	{{0x67e9, 0x90c0, 0x94c2, 0x2303, 0x8018, 0x73f8, 0x90c0, 0x94c3, 0x2303, 0x800e, 0x92d0, 0x727f, 0xd057, 0x90c0, 0x2469, 0x7650 }, 16, 0x000b9180, 1},
++	{{0x8014, 0x94c6, 0x7941, 0xf245, 0x94c0, 0xd523, 0x9085, 0x85c5, 0xc284, 0xf245, 0x9ac0, 0x2f00, 0x830a, 0x6d10, 0x2d00, 0x838a }, 16, 0x000b91a0, 1},
++	{{0x3680, 0xa000, 0xecee, 0xeaee, 0x3600, 0xa100, 0xea3f, 0xec3d, 0x3600, 0xa100, 0xc45c, 0xca49, 0x94c0, 0xc088, 0xc790, 0x3800 }, 16, 0x000b91c0, 1},
++	{{0xa008, 0x6a01, 0x689b, 0x9743, 0x3600, 0xa100, 0xcb44, 0xcf41, 0x90c0, 0x92d0, 0x421b, 0x429f, 0x3840, 0xa100, 0xf2c5, 0x2d0f }, 16, 0x000b91e0, 1},
++	{{0x8b64, 0x3a00, 0xa100, 0x656a, 0xcb41, 0x27ec, 0x9fe0, 0x94c0, 0xc944, 0x847f, 0x9ac0, 0x2d00, 0x8204, 0x90c0, 0x2f00, 0x8081 }, 16, 0x000b9200, 1},
++	{{0x98c0, 0x6c10, 0x6c90, 0x94a4, 0x9b43, 0x98c0, 0x2b03, 0x800e, 0x7a6a, 0x4419, 0x3907, 0x8014, 0x3420, 0xa000, 0x96a0, 0x3400 }, 16, 0x000b9220, 1},
++	{{0xa800, 0x7276, 0x8011, 0x3400, 0xa004, 0x7377, 0x840e, 0x3423, 0xa000, 0xc281, 0x3400, 0xa004, 0x6d10, 0x3400, 0xa004, 0x6569 }, 16, 0x000b9240, 1},
++	{{0x92d3, 0x78c1, 0x36a7, 0xa100, 0x5797, 0xef44, 0x3403, 0xa800, 0xd447, 0x64ea, 0x8409, 0x33e4, 0x3c48, 0x8001, 0x3961, 0x009b }, 16, 0x000b9260, 1},
++	{{0xe83f, 0x3600, 0xa100, 0x656a, 0xef3d, 0x8197, 0x3c20, 0xa000, 0x280f, 0x8030, 0x6c10, 0x27ed, 0x9fe5, 0x96c0, 0x5217, 0x27e8 }, 16, 0x000b9280, 1},
++	{{0x9fe4, 0x7961, 0x3175, 0x5516, 0x96c0, 0x7ac1, 0x2518, 0x8602, 0x9742, 0x4016, 0x94d0, 0x9098, 0x909d, 0x94c0, 0xe842, 0xed42 }, 16, 0x000b92a0, 1},
++	{{0x9ac0, 0x6c90, 0x27e8, 0x9fd8, 0x6d10, 0xc7a5, 0x96c0, 0x6d90, 0xc482, 0xc584, 0x94c0, 0xc810, 0xf741, 0x94c0, 0xf044, 0xf542 }, 16, 0x000b92c0, 1},
++	{{0x3640, 0xa000, 0xf443, 0xe9eb, 0x3820, 0xa000, 0xfd4f, 0x27e8, 0x9fd8, 0x3660, 0xa000, 0xf850, 0xfc51, 0x3264, 0x2c70, 0x800b }, 16, 0x000b92e0, 1},
++	{{0x94c0, 0xfa52, 0xc35f, 0x96c0, 0x7470, 0xf294, 0xc357, 0x96c0, 0x6569, 0xcd42, 0xc484, 0x3a40, 0xa000, 0x2101, 0x9999, 0x6c7d }, 16, 0x000b9300, 1},
++	{{0xfcd1, 0x98c3, 0xcc42, 0x3b80, 0x32e0, 0x8008, 0x94c0, 0xedfe, 0xfad2, 0x3647, 0xa000, 0xeb1c, 0xed1b, 0x94c7, 0x5095, 0x95bb }, 16, 0x000b9320, 1},
++	{{0x9ec7, 0x27e8, 0x9fda, 0xd621, 0x90c0, 0x6174, 0x057c, 0x9fe4, 0x98c0, 0x6d74, 0x7a61, 0x5b18, 0x8475, 0x9ac0, 0x2b03, 0x8036 }, 16, 0x000b9340, 1},
++	{{0x7a61, 0x27e9, 0x9fe5, 0x94c0, 0xeceb, 0x9b44, 0xecfe, 0x3420, 0xa000, 0xec1b, 0x5494, 0x7272, 0x90c0, 0x96c2, 0x3d80, 0x32e0 }, 16, 0x000b9360, 1},
++	{{0x8008, 0x90c0, 0x9ac6, 0x2103, 0x8038, 0x90c0, 0xeb1d, 0x90c0, 0x94c6, 0x5b18, 0x93bb, 0x92c2, 0x9399, 0x94c0, 0xeceb, 0xe941 }, 16, 0x000b9380, 1},
++	{{0xecfe, 0x3420, 0xa000, 0xec1b, 0x5594, 0x72f2, 0x90c0, 0x96d2, 0x3d80, 0x32e0, 0x8008, 0x90c0, 0x92c2, 0xeb1d, 0x92c2, 0x92bb }, 16, 0x000b93a0, 1},
++	{{0x92c2, 0x9299, 0x3800, 0xa100, 0x6d10, 0xefef, 0xcdac, 0x3680, 0xa000, 0xef68, 0xc9aa, 0x3680, 0xa000, 0x5417, 0xe8ef, 0x98c0 }, 16, 0x000b93c0, 1},
++	{{0x391f, 0x8001, 0xebef, 0xe83d, 0x27e9, 0x14d0, 0xeb39, 0x3a00, 0xa008, 0x77f4, 0x75d4, 0x50d3, 0x8481, 0x9ac0, 0x75f0, 0x74d0 }, 16, 0x000b93e0, 1},
++	{{0x9344, 0x2b03, 0x801a, 0x9ac0, 0x2500, 0x80b4, 0x90c0, 0x27eb, 0x9fe4, 0x7455, 0x3a00, 0xb008, 0x7671, 0x75f3, 0x71f7, 0x95bb }, 16, 0x000b9400, 1},
++	{{0x3800, 0xa814, 0x6d2c, 0x74fc, 0x6e4c, 0x3a06, 0xa001, 0x90c0, 0x64e9, 0x6d10, 0x6c7d, 0x841d, 0x3400, 0xa804, 0x75fb, 0x3400 }, 16, 0x000b9420, 1},
++	{{0xa004, 0x71e5, 0x8020, 0x92c2, 0xc481, 0x2e10, 0x3184, 0x3464, 0x800b, 0x3400, 0xa004, 0x7175, 0x800b, 0x72f4, 0x8408, 0x92c3 }, 16, 0x000b9440, 1},
++	{{0xc481, 0x6e10, 0x6669, 0x90d0, 0x92c3, 0x929b, 0xeb41, 0x94c0, 0x6c10, 0x9742, 0x27e8, 0x9fe8, 0x92c8, 0x9080, 0x98c0, 0x6c10 }, 16, 0x000b9460, 1},
++	{{0x6c90, 0xe8ef, 0x9144, 0x9ac0, 0x2903, 0x8036, 0x90c0, 0x2b03, 0x8064, 0x9ac0, 0x2a03, 0x803e, 0x90c0, 0x27ed, 0x9fd0, 0x1317 }, 16, 0x000b9480, 1},
++	{{0xe864, 0x98c0, 0x27e9, 0x9fc8, 0x77d3, 0xc015, 0x96c0, 0x5590, 0x27ed, 0x9fc8, 0x96c0, 0xc011, 0x27eb, 0x9fe4, 0x94a3, 0x6669 }, 16, 0x000b94a0, 1},
++	{{0x8055, 0x3820, 0xa000, 0x65ea, 0xe9ea, 0xecec, 0x8449, 0x9a47, 0x96c0, 0x767c, 0x511c, 0x9343, 0x34e9, 0x5295, 0x7261, 0x92c3 }, 16, 0x000b94c0, 1},
++	{{0x6c10, 0x92c2, 0xc081, 0x6469, 0x90c0, 0x94c7, 0x501c, 0x5191, 0x96c7, 0x7468, 0xd541, 0xe944, 0x7260, 0x92c3, 0x6c90, 0x92d2 }, 16, 0x000b94e0, 1},
++	{{0xc181, 0x64e9, 0x90c0, 0x90c0, 0x94d7, 0xe944, 0x5091, 0x92c3, 0xd540, 0x4295, 0x92d0, 0xed44, 0x90c0, 0x90c0, 0x96c0, 0x9342 }, 16, 0x000b9500, 1},
++	{{0x27e9, 0x9fcc, 0x96c0, 0xf1ce, 0x2b03, 0x801c, 0x1499, 0xec3c, 0x3271, 0xc381, 0x9ac0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b9520, 1},
++	{{0x9ad6, 0x5499, 0x90c0, 0x79c1, 0xcc43, 0xd0d4, 0x7271, 0x90c0, 0x9cc0, 0xd0d4, 0x6c10, 0x6f90, 0x9344, 0x2b03, 0x8020, 0x98c6 }, 16, 0x000b9540, 1},
++	{{0x27e8, 0x9fc8, 0x90c0, 0xcc43, 0x96c0, 0xcc4a, 0xed3d, 0x90c0, 0x3167, 0x5390, 0x800b, 0x71f0, 0xd053, 0x92c2, 0xcd47, 0x94d0 }, 16, 0x000b9560, 1},
++	{{0x7bc1, 0xe844, 0x90c0, 0x90c0, 0x98c0, 0x2b00, 0x842e, 0x70f5, 0xe8ee, 0x98c7, 0x2300, 0x8094, 0x90c0, 0x6d10, 0x96c6, 0xe83b }, 16, 0x000b9580, 1},
++	{{0x27ea, 0x9fe4, 0x94c6, 0x4190, 0xec1a, 0x96c6, 0x7075, 0x92bc, 0xf341, 0x98c7, 0x027c, 0x9fe8, 0x90c0, 0x6e10, 0x9cc1, 0x6c90 }, 16, 0x000b95a0, 1},
++	{{0x27ea, 0x9fe4, 0x6c90, 0x27ea, 0x9fe9, 0x96c2, 0xed1a, 0x27e9, 0x9fe9, 0x94c1, 0x949a, 0x90bd, 0x98c0, 0xc75f, 0x32e4, 0x3c8a }, 16, 0x000b95c0, 1},
++	{{0x8001, 0x3646, 0xa000, 0x9099, 0xe8eb, 0x3a40, 0xa000, 0x6c90, 0xfcd1, 0x2200, 0x8080, 0x98c0, 0xf241, 0x32e4, 0x3c8a, 0x8001 }, 16, 0x000b95e0, 1},
++	{{0x3420, 0xa000, 0xe8ec, 0x3820, 0xa000, 0xfdcf, 0x2e0c, 0x8004, 0x96c0, 0xebec, 0x117c, 0x9fe8, 0x3640, 0xa000, 0xeb62, 0xf8d0 }, 16, 0x000b9600, 1},
++	{{0x96c0, 0x5d13, 0x27e9, 0x9fe9, 0x96c0, 0x90b9, 0x2f09, 0x8002, 0x3600, 0xa100, 0xed1c, 0xe9ee, 0x94c0, 0x919d, 0xec54, 0x5813 }, 16, 0x000b9620, 1},
++	{{0x90c0, 0xe81c, 0x9098, 0x1011, 0x5513, 0x7861, 0x7075, 0x90c0, 0x3a01, 0xa100, 0x90c0, 0xeeee, 0x7ac1, 0x6d90, 0x96c3, 0xc481 }, 16, 0x000b9640, 1},
++	{{0x2a00, 0x8432, 0x92c2, 0x4513, 0x3483, 0xa000, 0xee3a, 0x3887, 0xa000, 0x949e, 0x2a00, 0x8432, 0x92c3, 0x4313, 0x3480, 0xa000 }, 16, 0x000b9660, 1},
++	{{0xe93a, 0x3480, 0xa000, 0x95b9, 0xd2a1, 0x3660, 0xa000, 0x9955, 0x9850, 0x96c2, 0x3384, 0x2bc0, 0x800b, 0x96c0, 0xc757, 0x2800 }, 16, 0x000b9680, 1},
++	{{0x842a, 0xeaee, 0x3680, 0xa000, 0x5117, 0xea38, 0x96c0, 0x331f, 0x8200, 0x93ba, 0x27e9, 0x76d3, 0x8083, 0x9cc0, 0x65ea, 0x3c13 }, 16, 0x000b96a0, 1},
++	{{0x805a, 0xe9ef, 0x2100, 0x80af, 0x96c0, 0x7651, 0xe976, 0x842b, 0x3620, 0xa000, 0x5611, 0xc585, 0x3400, 0xa804, 0x682e, 0x3400 }, 16, 0x000b96c0, 1},
++	{{0xa004, 0x7c6c, 0x3600, 0xa800, 0x3100, 0x805a, 0x6c7d, 0x74d4, 0x6d7c, 0x96c0, 0xecee, 0x2900, 0x8429, 0x94c0, 0x959a, 0xef76 }, 16, 0x000b96e0, 1},
++	{{0x96c0, 0xec39, 0x2100, 0x80af, 0x96c0, 0x7651, 0x97bc, 0x5217, 0x98c0, 0x67ea, 0x76d7, 0x3c17, 0x805a, 0x3600, 0xa004, 0x68ab }, 16, 0x000b9700, 1},
++	{{0x841f, 0x3600, 0xa004, 0x7cec, 0xc585, 0x3600, 0xa800, 0x3300, 0x805a, 0x6c7d, 0x74d4, 0x6d7c, 0x959c, 0x3880, 0xa000, 0x5117 }, 16, 0x000b9720, 1},
++	{{0x2d00, 0x842a, 0x98c0, 0x331d, 0x8400, 0xebee, 0xc185, 0x26e9, 0xeb3d, 0x94c0, 0x95bb, 0x8055, 0x32a4, 0x34f0, 0x800b, 0x7455 }, 16, 0x000b9740, 1},
++	{{0x9cc0, 0x2f00, 0x8429, 0x66e0, 0x3e10, 0x8005, 0xe9ee, 0x3468, 0xc185, 0x2e01, 0xe93f, 0x76ec, 0xd6a2, 0x94c2, 0x3104, 0x8005 }, 16, 0x000b9760, 1},
++	{{0xd054, 0x909b, 0x98c0, 0x95b9, 0x32a4, 0x34f0, 0x800b, 0x7455, 0x3e10, 0x8005, 0x7468, 0x6e01, 0x766c, 0xd622, 0x94c2, 0x3101 }, 16, 0x000b9780, 1},
++	{{0x8005, 0xd051, 0x9099, 0x2c10, 0x3c00, 0x20a0, 0x8008, 0x0016, 0x3d20, 0x33b6, 0x8009, 0x15d4, 0x08c6, 0x38d0, 0x8008, 0x3ec7 }, 16, 0x000b97a0, 1},
++	{{0x3b20, 0x33b4, 0x8009, 0x9ac0, 0x2808, 0x82b0, 0x90c0, 0x2b02, 0x8002, 0x5110, 0xd0a1, 0x840d, 0x9770, 0x90c0, 0x94c8, 0x453b }, 16, 0x000b97c0, 1},
++	{{0x453d, 0x96c0, 0xefee, 0x2900, 0x842a, 0x90c0, 0xef39, 0x95bf, 0x66e9, 0x90c0, 0x98c2, 0x3d00, 0x20a0, 0x8008, 0xc9ff, 0x8046 }, 16, 0x000b97e0, 1},
++	{{0x92c2, 0x4915, 0x3480, 0xa000, 0x5017, 0x311c, 0x8004, 0x96c0, 0x6669, 0x311c, 0x8010, 0x90c0, 0x98c3, 0x3800, 0x20a0, 0x8008 }, 16, 0x000b9800, 1},
++	{{0xcfff, 0x8422, 0x92c3, 0x4f10, 0x2669, 0x3f00, 0x20a0, 0x8008, 0x90c0, 0x98c1, 0x2400, 0x80b4, 0x90c0, 0x4517, 0x92c3, 0x6cb5 }, 16, 0x000b9820, 1},
++	{{0x92c3, 0x4117, 0x2900, 0x8429, 0x90c0, 0xee39, 0x90be, 0x6469, 0x90c0, 0x98c2, 0x3900, 0x20a2, 0x8008, 0xcbff, 0x8050, 0x92c2 }, 16, 0x000b9840, 1},
++	{{0x4b11, 0x3480, 0xa000, 0x5417, 0x9ac0, 0x391d, 0x8008, 0x90c0, 0x391c, 0x8010, 0x66e9, 0x90c0, 0x98c3, 0x3f00, 0x20a2, 0x8008 }, 16, 0x000b9860, 1},
++	{{0xcaff, 0x842a, 0x92c3, 0x4a17, 0x2669, 0x3a00, 0x20a2, 0x8008, 0x90c0, 0x94c3, 0x2500, 0x80b4, 0x94c7, 0x8414, 0x6e81, 0x92c3 }, 16, 0x000b9880, 1},
++	{{0x4512, 0x0012, 0x3184, 0x38ac, 0x800b, 0x4516, 0xc566, 0x90c0, 0x90c0, 0x96c0, 0x6c10, 0x27e8, 0x9fb8, 0xe7e8, 0x94c0, 0x9e21 }, 16, 0x000b98a0, 1},
++	{{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x96c0, 0x5d98, 0x2a03, 0x80b2, 0x1998, 0x1005, 0xa03f }, 16, 0x000b98c0, 1},
++	{{0x1a98, 0x1105, 0xa004, 0x5c98, 0x3420, 0xa000, 0x5318, 0x3800, 0xa101, 0x509a, 0xefec, 0x79e1, 0x3640, 0xa000, 0x529a, 0x9a43 }, 16, 0x000b98e0, 1},
++	{{0x549a, 0x569a, 0x3420, 0xa000, 0x5092, 0x3800, 0xa008, 0x6764, 0x6464, 0x5159, 0x139c, 0x7ce2, 0x559c, 0x579c, 0x3420, 0xa000 }, 16, 0x000b9900, 1},
++	{{0x519c, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f, 0x6e60, 0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f, 0x7e70 }, 16, 0x000b9920, 1},
++	{{0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0, 0x3a00, 0xa42f, 0x629d, 0x6315, 0x639f, 0x6191, 0x3800 }, 16, 0x000b9940, 1},
++	{{0xb8cc, 0x6ed5, 0x6fdf, 0xc543, 0x3600, 0xa844, 0x6fdb, 0xc341, 0x3820, 0xa844, 0x6d4f, 0x5159, 0xc147, 0x3800, 0xa841, 0x6fdc }, 16, 0x000b9960, 1},
++	{{0x7ce2, 0x7d43, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f, 0x6e60, 0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f }, 16, 0x000b9980, 1},
++	{{0x7e70, 0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0, 0x3a00, 0xa42f, 0x629d, 0x6315, 0x639f, 0x6191 }, 16, 0x000b99a0, 1},
++	{{0x3a00, 0xb8ce, 0x6ed5, 0x6fdf, 0xc543, 0x6565, 0x3830, 0xa844, 0x6fdb, 0xc341, 0x425d, 0x3820, 0xa844, 0x6d4f, 0x5159, 0xc147 }, 16, 0x000b99c0, 1},
++	{{0x3800, 0xa841, 0x6fdc, 0x7ce2, 0x7d43, 0x3420, 0xa000, 0xecef, 0x3400, 0xa004, 0x6565, 0x3420, 0xa000, 0x425d, 0x94c0, 0x4394 }, 16, 0x000b99e0, 1},
++	{{0xb561, 0x3640, 0xa000, 0xb762, 0xb163, 0x94c0, 0x9621, 0x9721, 0x94c0, 0x9f70, 0xf3c1, 0xc563, 0x94c0, 0x9620, 0x9720, 0x96c0 }, 16, 0x000b9a00, 1},
++	{{0x5d98, 0x2a03, 0x80b2, 0x1998, 0x1005, 0xa03f, 0x1a98, 0x1105, 0xa004, 0x5c98, 0x3420, 0xa000, 0x5318, 0x3800, 0xa101, 0x509a }, 16, 0x000b9a20, 1},
++	{{0xefec, 0x79e1, 0x3640, 0xa000, 0x529a, 0x9a43, 0x549a, 0x569a, 0x3420, 0xa000, 0x5092, 0x3800, 0xa008, 0x6764, 0x6464, 0x5199 }, 16, 0x000b9a40, 1},
++	{{0x139c, 0x7ce2, 0x559c, 0x579c, 0x3420, 0xa000, 0x519c, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f, 0x6e60 }, 16, 0x000b9a60, 1},
++	{{0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f, 0x7e70, 0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0, 0x3a00 }, 16, 0x000b9a80, 1},
++	{{0xa42f, 0x629d, 0x6315, 0x639f, 0x6191, 0x3800, 0xb8cc, 0x6ed5, 0x6fdf, 0xc543, 0x3600, 0xa844, 0x6fdb, 0xc341, 0x3820, 0xa840 }, 16, 0x000b9aa0, 1},
++	{{0x6fcf, 0x5199, 0xc147, 0x3820, 0xa000, 0x7fc4, 0x7ce2, 0xc247, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f }, 16, 0x000b9ac0, 1},
++	{{0x6e60, 0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f, 0x7e70, 0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0 }, 16, 0x000b9ae0, 1},
++	{{0x3a00, 0xa42f, 0x629d, 0x6315, 0x639f, 0x6191, 0x3a00, 0xb8ce, 0x6ed5, 0x6fdf, 0xc543, 0x7d46, 0x3810, 0xa845, 0x6fdb, 0xc341 }, 16, 0x000b9b00, 1},
++	{{0x6565, 0x3820, 0xa840, 0x6fcf, 0x5199, 0xc147, 0x3a60, 0xa000, 0x7fc4, 0x7ce2, 0xc247, 0x42dd, 0x3620, 0xa008, 0xecef, 0x7d46 }, 16, 0x000b9b20, 1},
++	{{0x3400, 0xa004, 0x6565, 0x3420, 0xa000, 0x42dd, 0x94c0, 0x4394, 0xb561, 0x3640, 0xa000, 0xb762, 0xb163, 0x94c0, 0x9621, 0x9721 }, 16, 0x000b9b40, 1},
++	{{0x94c0, 0x9f70, 0xf3c1, 0xc563, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x96c0, 0x5b98, 0x2a03, 0x805a, 0x1005 }, 16, 0x000b9b60, 1},
++	{{0xa03f, 0x96c0, 0x5998, 0x2b03, 0x806e, 0x5a98, 0x90c0, 0x1098, 0xedea, 0x3620, 0xa000, 0x5a98, 0xece8, 0x3420, 0xa000, 0x5318 }, 16, 0x000b9b80, 1},
++	{{0x3620, 0xa008, 0x5418, 0x7de2, 0x3820, 0xb009, 0x9a43, 0x76d4, 0x7e41, 0x3e00, 0xa00c, 0x7a48, 0x7ee2, 0x3703, 0x2008, 0x8000 }, 16, 0x000b9ba0, 1},
++	{{0xc050, 0x90c0, 0x36c0, 0xa000, 0xcc54, 0xe8ea, 0x92c0, 0x90c0, 0x3e40, 0xa000, 0x6e10, 0x6e90, 0x6f10, 0x6f90, 0x49d9, 0x9b45 }, 16, 0x000b9bc0, 1},
++	{{0x08d0, 0xeaed, 0x3a40, 0xa000, 0x6e10, 0x6e90, 0x5048, 0x505a, 0x3e40, 0xa4d0, 0x6393, 0x6312, 0x6291, 0x6210, 0x5348, 0x505a }, 16, 0x000b9be0, 1},
++	{{0x3e50, 0xa2e0, 0x6392, 0x6311, 0x6290, 0x6213, 0x5248, 0x505a, 0x3e40, 0xb070, 0x6391, 0x6310, 0x6293, 0x6212, 0x5148, 0x505a }, 16, 0x000b9c00, 1},
++	{{0x3e50, 0xa8b0, 0x6390, 0x6313, 0x6292, 0x6211, 0x5048, 0x505a, 0x364c, 0x36cd, 0x374e, 0x77cf, 0x0cdb, 0x5058, 0x0894, 0x3703 }, 16, 0x000b9c20, 1},
++	{{0x2000, 0x8000, 0x94c0, 0x9621, 0x9721, 0x94c0, 0x9f70, 0xf3c1, 0x98c0, 0x3cfa, 0x3fff, 0xbfff, 0xc563, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b9c40, 1},
++	{{0x3e00, 0xa10c, 0x74d7, 0x7456, 0x0dc6, 0x38d0, 0x8008, 0xe9ee, 0x3e00, 0xa100, 0x6f10, 0x6e10, 0x39e0, 0x3200, 0x800b, 0xeaef }, 16, 0x000b9c60, 1},
++	{{0x3c80, 0xa000, 0x2d08, 0x82b2, 0x6c10, 0x2500, 0x8100, 0x3a80, 0xa000, 0x5110, 0x3f20, 0x2f48, 0x800c, 0x0190, 0x3e20, 0x2f30 }, 16, 0x000b9c80, 1},
++	{{0x800c, 0x3c20, 0x2f60, 0x800c, 0x3a20, 0x2f18, 0x800c, 0x96c0, 0x499c, 0x290b, 0x8200, 0x0b9f, 0x33e1, 0x3000, 0x800b, 0x96c0 }, 16, 0x000b9ca0, 1},
++	{{0x439a, 0x2b0d, 0x8200, 0x0d9e, 0x3721, 0x2c88, 0x800c, 0x079e, 0x3221, 0x2878, 0x800c, 0x029f, 0x3321, 0x2670, 0x800c, 0x039a }, 16, 0x000b9cc0, 1},
++	{{0x3121, 0x2a80, 0x800c, 0x3800, 0xa800, 0x77d1, 0x419c, 0x4796, 0x0392, 0x4297, 0x0194, 0xee46, 0x94c0, 0xef46, 0xea46, 0x050e }, 16, 0x000b9ce0, 1},
++	{{0xec46, 0x050f, 0x450c, 0x050a, 0x4617, 0x3800, 0xa800, 0x7750, 0x4416, 0x4612, 0x3620, 0xa000, 0xeee9, 0x9f70, 0x3640, 0xa000 }, 16, 0x000b9d00, 1},
++	{{0x4414, 0xefea, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b9d20, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe748, 0xeee8, 0x94c0, 0xfcca, 0xf3c9, 0x90c0, 0x5594, 0x3b18, 0x8001 }, 16, 0x000b9d40, 1},
++	{{0x6469, 0x94c0, 0xf6c9, 0x8449, 0x25ea, 0xede9, 0x840f, 0x9f43, 0x90c0, 0x90c0, 0x92d0, 0x541e, 0x441d, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000b9d60, 1},
++	{{0x90c0, 0x2e0f, 0x82b0, 0x5017, 0x6469, 0x8419, 0x25ea, 0x3b20, 0x33b4, 0x8009, 0x840f, 0x9f43, 0x90c0, 0x90c0, 0x92d0, 0x5519 }, 16, 0x000b9d80, 1},
++	{{0x451b, 0x2c10, 0x31a4, 0x2022, 0x800b, 0x9ac0, 0x676a, 0x75d6, 0x6c10, 0xece9, 0xedee, 0x94c0, 0x79e1, 0x842b, 0x96c0, 0x9b43 }, 16, 0x000b9da0, 1},
++	{{0x2b03, 0x8018, 0x001c, 0x3a20, 0x2ed0, 0x800c, 0x96c0, 0x551d, 0x2103, 0x8012, 0x94d0, 0x6c10, 0x451a, 0x401c, 0x551d, 0x4512 }, 16, 0x000b9dc0, 1},
++	{{0x98c0, 0x3c20, 0x2f14, 0x800c, 0xf941, 0x3521, 0x2ed0, 0x800c, 0x0594, 0x3321, 0x2e90, 0x800c, 0x98c0, 0x0322, 0x2f10, 0x800c }, 16, 0x000b9de0, 1},
++	{{0xec50, 0x3284, 0x3b70, 0x800b, 0x0614, 0x3820, 0x2f10, 0x800c, 0x276a, 0x35d6, 0x3d20, 0x2e90, 0x800c, 0x94c0, 0x79e1, 0x841d }, 16, 0x000b9e00, 1},
++	{{0x9f43, 0x101d, 0x3820, 0x2f70, 0x800c, 0x2103, 0x800a, 0x94c8, 0x4098, 0x501d, 0x4090, 0x9ac0, 0x676a, 0xe8ee, 0x3a20, 0x2e90 }, 16, 0x000b9e20, 1},
++	{{0x800c, 0x8423, 0x96c0, 0x9b46, 0x2b03, 0x8010, 0x3c20, 0x2ed0, 0x800c, 0x90c0, 0x2e90, 0x1318, 0x5214, 0x94d0, 0x693d, 0x451a }, 16, 0x000b9e40, 1},
++	{{0x7d6f, 0x421c, 0x3d20, 0x2f5c, 0x800c, 0x3421, 0x2ed0, 0x800c, 0x0495, 0x3421, 0x2e90, 0x800c, 0x98c0, 0x0422, 0x2f58, 0x800c }, 16, 0x000b9e60, 1},
++	{{0xed50, 0x3284, 0x3b70, 0x800b, 0x0615, 0x3820, 0x2f58, 0x800c, 0x276a, 0x3556, 0x3820, 0x2f70, 0x800c, 0x94c0, 0x7961, 0x842b }, 16, 0x000b9e80, 1},
++	{{0x98c0, 0x3c20, 0x2e90, 0x800c, 0x9f42, 0xeae8, 0x149a, 0x511c, 0x96c0, 0x6cc4, 0x2103, 0x8012, 0x94d0, 0x509a, 0x571c, 0x2cc3 }, 16, 0x000b9ea0, 1},
++	{{0x4198, 0x4190, 0x9ac0, 0x676a, 0x3f20, 0x2ed0, 0x800c, 0xebee, 0x8419, 0x96c0, 0x9b46, 0x2b03, 0x800a, 0xecef, 0x131c, 0x501b }, 16, 0x000b9ec0, 1},
++	{{0x92d0, 0x6933, 0x7d6f, 0x421f, 0x3f20, 0x2f44, 0x800c, 0x3321, 0x2ed0, 0x800c, 0x0397, 0x3021, 0x2e90, 0x800c, 0x98c0, 0x0022 }, 16, 0x000b9ee0, 1},
++	{{0x2f40, 0x800c, 0xef50, 0x3284, 0x3b70, 0x800b, 0x0617, 0x3820, 0x2f40, 0x800c, 0x276a, 0x36d6, 0x3c20, 0x2f70, 0x800c, 0x94c0 }, 16, 0x000b9f00, 1},
++	{{0x7ae1, 0x842b, 0x98c0, 0x3d20, 0x2e90, 0x800c, 0x9f45, 0xebec, 0x139b, 0x511d, 0x96c0, 0x6c59, 0x2103, 0x8012, 0x94d0, 0x559b }, 16, 0x000b9f20, 1},
++	{{0x511d, 0x2c45, 0x409c, 0x4094, 0x276a, 0x3f20, 0x2ed0, 0x800c, 0x8421, 0x96c0, 0x9b46, 0x2b03, 0x800a, 0xecef, 0x111e, 0x531c }, 16, 0x000b9f40, 1},
++	{{0x2af4, 0xd893, 0x7eef, 0x94d0, 0x3427, 0x8005, 0x7fef, 0x471f, 0x3b20, 0x2f2c, 0x800c, 0x3121, 0x2ed0, 0x800c, 0x0193, 0x3721 }, 16, 0x000b9f60, 1},
++	{{0x2e90, 0x800c, 0x98c0, 0x0722, 0x2f28, 0x800c, 0xeb50, 0x3284, 0x3b70, 0x800b, 0x0613, 0x3820, 0x2f28, 0x800c, 0x9cc0, 0x676a }, 16, 0x000b9f80, 1},
++	{{0x77d6, 0xf9c1, 0x3c20, 0x2f70, 0x800c, 0x94c0, 0x7be1, 0x842b, 0x98c0, 0x3d20, 0x2e90, 0x800c, 0x9f47, 0xeeec, 0x129e, 0x541d }, 16, 0x000b9fa0, 1},
++	{{0x96c0, 0x6cc8, 0x2103, 0x8012, 0x94d0, 0x539e, 0x551d, 0x2ccd, 0x419c, 0x4194, 0x9ac0, 0x676a, 0xeae9, 0x3820, 0x2f70, 0x800c }, 16, 0x000b9fc0, 1},
++	{{0x8419, 0x96c0, 0x9b46, 0x2b03, 0x8008, 0x5398, 0x7dc8, 0x65e5, 0x92d0, 0x7dc8, 0x75db, 0x435a, 0x0dc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000b9fe0, 1},
++	{{0x2d0c, 0x82b0, 0x5414, 0x6669, 0x8419, 0x276a, 0x3e20, 0x33b4, 0x8009, 0x840f, 0x9f46, 0x90c0, 0x90c0, 0x92d0, 0x5019, 0x401e }, 16, 0x000ba000, 1},
++	{{0x6c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba020, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0xc1f3, 0x05c6, 0x3684, 0x8009, 0x98c0, 0xdc01, 0x3b19 }, 16, 0x000ba040, 1},
++	{{0x800c, 0x9f70, 0xdc19, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9cc0, 0x646a, 0xd190, 0xe748, 0x3b80, 0x3330, 0x8008, 0x98c0 }, 16, 0x000ba060, 1},
++	{{0x65e4, 0xc59e, 0x2121, 0x8688, 0x9ec7, 0x8438, 0x90c0, 0xd413, 0x90c0, 0x6e8d, 0x24c0, 0x83ca, 0x92c3, 0xf442, 0x96c0, 0x30c8 }, 16, 0x000ba080, 1},
++	{{0x8216, 0x7ec8, 0xcc40, 0x90c0, 0xec1b, 0x9cbc, 0xcc4a, 0x7472, 0xd445, 0x3c10, 0x9400, 0x3e10, 0x800a, 0x62f4, 0x6ef4, 0xf542 }, 16, 0x000ba0a0, 1},
++	{{0xf2c2, 0x3d48, 0xe768, 0x6565, 0x7d48, 0x94c0, 0x755a, 0x9f70, 0xd81a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba0c0, 1},
++	{{0x9cc0, 0x6e10, 0x6f90, 0x6f10, 0x6d90, 0xcd56, 0xce57, 0x9ac0, 0x74d7, 0x270b, 0x80a0, 0x7454, 0x9745, 0xe7eb, 0x96c0, 0xc94a }, 16, 0x000ba0e0, 1},
++	{{0x280a, 0x8104, 0x3a80, 0xa104, 0x7752, 0x7556, 0xeaef, 0xe9ee, 0x96c0, 0x4492, 0x27e8, 0x9fb0, 0x9ac0, 0x27ef, 0x9fd8, 0x90c0 }, 16, 0x000ba100, 1},
++	{{0x27ec, 0x9f88, 0x27e9, 0x9f60, 0x94d0, 0xc819, 0xc81c, 0x94c0, 0xc818, 0xc81f, 0x3a00, 0xb000, 0x7752, 0x7556, 0x2704, 0x8080 }, 16, 0x000ba120, 1},
++	{{0x9ac0, 0x7650, 0x77d1, 0xc942, 0x2000, 0x8081, 0x90c0, 0x5399, 0x71f4, 0x98d0, 0xd253, 0xd3d6, 0x7b41, 0x5399, 0x71f4, 0x9ac0 }, 16, 0x000ba140, 1},
++	{{0x6e90, 0x2a0e, 0x8016, 0xd3d6, 0xc181, 0x1316, 0x0778, 0x9f60, 0x9ac0, 0xd5a1, 0x7653, 0xcb42, 0x27ec, 0x9f62, 0x94c0, 0x7a61 }, 16, 0x000ba160, 1},
++	{{0x8483, 0x9cc0, 0x9944, 0x2903, 0x800e, 0x90c0, 0x90c0, 0x90c0, 0x9ec0, 0x6f10, 0x9a40, 0x2a03, 0x8010, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba180, 1},
++	{{0x98c0, 0x2b03, 0x8010, 0x6e10, 0x9b41, 0x94c0, 0x27ed, 0x9f60, 0x3420, 0xa000, 0x5215, 0x3400, 0xa004, 0x7165, 0x90c0, 0x96c2 }, 16, 0x000ba1a0, 1},
++	{{0xc481, 0x2003, 0x8010, 0x92d0, 0xed42, 0x90c0, 0x90c0, 0x3420, 0xa000, 0x549b, 0x3400, 0xa800, 0x7374, 0x800d, 0x6669, 0x3600 }, 16, 0x000ba1c0, 1},
++	{{0xa800, 0xd354, 0xd3d5, 0x92d0, 0x7ac1, 0x90c0, 0x90c0, 0x9ad0, 0x6e90, 0x2d00, 0x8204, 0x78c1, 0x471c, 0x90c0, 0xeb3d, 0x9ac0 }, 16, 0x000ba1e0, 1},
++	{{0x65ea, 0x7753, 0xefee, 0x27e8, 0x9f88, 0x94c0, 0xef6a, 0x844b, 0x96c0, 0xcc53, 0x27ed, 0x9f60, 0x1717, 0xc942, 0x5c1d, 0x90c0 }, 16, 0x000ba200, 1},
++	{{0xecfe, 0x98c0, 0xec19, 0x32a4, 0x2070, 0x800b, 0x5094, 0x246a, 0x7b61, 0x94c3, 0x3100, 0x80ff, 0x7c68, 0x73f0, 0x92c2, 0x6e90 }, 16, 0x000ba220, 1},
++	{{0x94c7, 0x676a, 0xc581, 0x94c0, 0x4518, 0x81d7, 0x3600, 0xa800, 0x7556, 0xcc5b, 0x9ac0, 0x65ea, 0x7653, 0xe9ee, 0x27ed, 0x9fb0 }, 16, 0x000ba240, 1},
++	{{0x96c0, 0xe968, 0x2718, 0x814e, 0x1511, 0xcc53, 0x3c00, 0xa001, 0x27ec, 0x9f60, 0x75d5, 0x27ef, 0x9f88, 0x2c90, 0x161f, 0x5014 }, 16, 0x000ba260, 1},
++	{{0x2f10, 0xd321, 0x2718, 0x8118, 0x3e00, 0xa003, 0x646a, 0x74d0, 0x77d4, 0x74d0, 0xc942, 0xc782, 0x98c0, 0x7cc2, 0xe0ec, 0x2718 }, 16, 0x000ba280, 1},
++	{{0x80f2, 0xcb41, 0x90c0, 0xeb19, 0x3620, 0xa000, 0x5493, 0x90c0, 0x3c00, 0xac00, 0x34e1, 0x8001, 0x90c0, 0x36e0, 0x8001, 0x3600 }, 16, 0x000ba2a0, 1},
++	{{0xa800, 0x30e1, 0x8001, 0x3400, 0xa004, 0xd811, 0x3600, 0xb004, 0xd440, 0x7454, 0x3400, 0xa004, 0x6461, 0x3600, 0xa004, 0x3610 }, 16, 0x000ba2c0, 1},
++	{{0x8080, 0x8045, 0x33a4, 0x2070, 0x800b, 0x3600, 0xa00c, 0x7c42, 0x76d0, 0x3480, 0xa000, 0xc840, 0x90c0, 0x98c0, 0xe819, 0x32a4 }, 16, 0x000ba2e0, 1},
++	{{0x2070, 0x800b, 0x5090, 0x3400, 0xa800, 0x6c81, 0x64ea, 0x94c3, 0x3301, 0x80ff, 0x7ce8, 0x3400, 0xa004, 0x71f1, 0x92c3, 0x7b41 }, 16, 0x000ba300, 1},
++	{{0x31a4, 0x237a, 0x800b, 0x3e00, 0xba02, 0x7454, 0x7556, 0x7657, 0x3610, 0x80ff, 0xece0, 0x8055, 0x33a4, 0x2070, 0x800b, 0x3800 }, 16, 0x000ba320, 1},
++	{{0xa004, 0x7550, 0x2100, 0x8100, 0x3400, 0xa040, 0x6e91, 0x7ec2, 0xcb45, 0x90c0, 0x98c0, 0xeb19, 0x32a4, 0x2070, 0x800b, 0x5093 }, 16, 0x000ba340, 1},
++	{{0x3400, 0xa800, 0x6c92, 0x64ea, 0x94c3, 0x3301, 0x80ff, 0x7ce8, 0x3400, 0xa004, 0x71f1, 0x92c3, 0x7b41, 0x7bc1, 0xd7a3, 0x8533 }, 16, 0x000ba360, 1},
++	{{0x3800, 0xb800, 0x7556, 0x7657, 0xece0, 0xd322, 0x92c3, 0x6f10, 0x98c6, 0x30a4, 0x239e, 0x800b, 0xc681, 0x4615, 0x4115, 0x96c0 }, 16, 0x000ba380, 1},
++	{{0x7a61, 0xec42, 0xed42, 0x666a, 0x2dff, 0x9ed3, 0xcc5b, 0x9ac0, 0x65ea, 0x7453, 0xebee, 0x27e9, 0x9fd8, 0x96c0, 0xeb66, 0x2718 }, 16, 0x000ba3a0, 1},
++	{{0x8122, 0x1713, 0xcc53, 0x3c00, 0xa001, 0x27e8, 0x9f60, 0x7457, 0x27ec, 0x9fb0, 0x27eb, 0x9f88, 0x111b, 0x5614, 0xd0a1, 0x2718 }, 16, 0x000ba3c0, 1},
++	{{0x80e8, 0x2769, 0x2c90, 0x5310, 0x2718, 0x80de, 0xd5a4, 0x84c7, 0x9cc0, 0x3613, 0x807c, 0xc682, 0x3705, 0x8002, 0xc352, 0x3c00 }, 16, 0x000ba3e0, 1},
++	{{0xa101, 0x6e2e, 0x7ec2, 0x75d0, 0xcc4c, 0x80b7, 0x3a00, 0xa100, 0x7dc2, 0x7e42, 0xcd45, 0xcb4f, 0x94c0, 0xc553, 0xcf44, 0xc683 }, 16, 0x000ba400, 1},
++	{{0x36e0, 0xa000, 0xed1b, 0xef1b, 0x36e0, 0xa000, 0x5195, 0xed1b, 0x32a4, 0x2070, 0x800b, 0x3600, 0xa800, 0x7451, 0x77d1, 0x32a4 }, 16, 0x000ba420, 1},
++	{{0x2070, 0x800b, 0x3600, 0xa004, 0x7550, 0x509d, 0x3800, 0xa200, 0x7650, 0x74d7, 0x7451, 0x3400, 0xa800, 0x6ea8, 0x66ea, 0x94c3 }, 16, 0x000ba440, 1},
++	{{0x3b05, 0x80ff, 0x7ee8, 0x3400, 0xa004, 0x7075, 0x98c7, 0x32a4, 0x2070, 0x800b, 0x78c1, 0x77d1, 0x32a4, 0x2070, 0x800b, 0x3600 }, 16, 0x000ba460, 1},
++	{{0xa004, 0x76d0, 0x508f, 0x3800, 0xb000, 0x74d7, 0x6f81, 0x7b61, 0x67ea, 0x94c3, 0x3f07, 0x80ff, 0x7fe8, 0x3400, 0xa004, 0x7077 }, 16, 0x000ba480, 1},
++	{{0x94c7, 0x676a, 0x78c1, 0x818b, 0x3a80, 0xb900, 0x7556, 0x7453, 0xcc44, 0xcb47, 0xd0a6, 0x92c3, 0x6f10, 0x98c6, 0x30a4, 0x24ca }, 16, 0x000ba4a0, 1},
++	{{0x800b, 0xc681, 0x4611, 0x6c90, 0x4111, 0x96c0, 0x7861, 0xe942, 0xec42, 0x246a, 0xe842, 0x2dff, 0x9f03, 0xcc5b, 0x2e90, 0xe8ee }, 16, 0x000ba4c0, 1},
++	{{0xe86e, 0x96c0, 0x5410, 0x280c, 0x800c, 0x5614, 0x7276, 0x2718, 0x8174, 0x9ac0, 0x2e09, 0x8004, 0x65ea, 0x27e8, 0x9f60, 0x94c0 }, 16, 0x000ba4e0, 1},
++	{{0xebe9, 0x84a3, 0x96c0, 0xeb68, 0x27ed, 0x9fd8, 0x96c0, 0x5713, 0x27ef, 0x9fb0, 0x1117, 0x5415, 0xd0a1, 0x8007, 0xd221, 0x8475 }, 16, 0x000ba500, 1},
++	{{0x276a, 0x2e10, 0x2c90, 0x3553, 0x5010, 0x8449, 0x96c0, 0x9a46, 0x2a03, 0x800a, 0x90c0, 0x3600, 0xa008, 0x656a, 0x6a38, 0x3680 }, 16, 0x000ba520, 1},
++	{{0xa000, 0xcb44, 0x842b, 0x96c0, 0x9b42, 0x2b03, 0x800c, 0xebfc, 0xeb19, 0x5313, 0x71e0, 0x92c2, 0x7a41, 0x94c2, 0x2003, 0x800e }, 16, 0x000ba540, 1},
++	{{0x92d0, 0xeb42, 0x90c0, 0x90c0, 0x92d0, 0x78c1, 0x90c0, 0x90c0, 0x75d2, 0x73f4, 0x92c2, 0x6c10, 0x92c3, 0xc081, 0xd021, 0x90c0 }, 16, 0x000ba560, 1},
++	{{0x96c2, 0xc081, 0x2e0b, 0x8504, 0x2418, 0x8116, 0x94c2, 0x4092, 0x4013, 0x96c0, 0x7ac1, 0xe842, 0xef42, 0x31f5, 0xed42, 0x8177 }, 16, 0x000ba580, 1},
++	{{0x9ac0, 0x7b61, 0x2e0f, 0x8004, 0x6e90, 0xc781, 0x676a, 0x846b, 0x2e10, 0x5116, 0x64ea, 0x8457, 0x5216, 0x9ac0, 0x34e1, 0x8002 }, 16, 0x000ba5a0, 1},
++	{{0x90c0, 0x34a3, 0x8002, 0x9ac0, 0x30e1, 0x8002, 0x90c0, 0x30a3, 0x8002, 0x9cc0, 0x36a3, 0x8002, 0xd891, 0x36e2, 0x8002, 0xd813 }, 16, 0x000ba5c0, 1},
++	{{0x94c0, 0xd4c2, 0xd443, 0x96c0, 0xd4c4, 0xd444, 0x7a41, 0x94c0, 0xcd41, 0xcb40, 0x90c0, 0x94c0, 0xedfc, 0xebfc, 0x94c0, 0xed1f }, 16, 0x000ba5e0, 1},
++	{{0xeb1f, 0x5115, 0x4113, 0x5216, 0x7174, 0x81af, 0x3ac1, 0x3bc1, 0x5314, 0x79e1, 0x71f5, 0x819b, 0x98c0, 0x6d10, 0x5316, 0x2e0a }, 16, 0x000ba600, 1},
++	{{0x8004, 0x96c0, 0x65ea, 0x27e8, 0x9f60, 0x8469, 0x1414, 0x5716, 0x3a61, 0x5118, 0x9ac0, 0x3480, 0x8007, 0x90c0, 0x3683, 0x8007 }, 16, 0x000ba620, 1},
++	{{0x3080, 0x8007, 0xda90, 0xd6c3, 0x3941, 0xd6c2, 0xc945, 0x90c0, 0xe9fc, 0xe91a, 0x4111, 0x5516, 0x72f2, 0x81d3, 0x31a4, 0x2692 }, 16, 0x000ba640, 1},
++	{{0x800b, 0x9ac0, 0x2e0b, 0x8004, 0x65ea, 0x27ec, 0x9f60, 0x841f, 0x34d5, 0x3ac1, 0x1410, 0x5016, 0x2880, 0x531c, 0xc941, 0x90c0 }, 16, 0x000ba660, 1},
++	{{0xe9fc, 0xe91b, 0x4311, 0x5116, 0x70f5, 0x81e7, 0x5310, 0x79c1, 0x4310, 0x98c0, 0x2e0b, 0x8504, 0x6c10, 0xc281, 0x4213, 0x96c0 }, 16, 0x000ba680, 1},
++	{{0xce5f, 0x27ec, 0x9f60, 0x94c0, 0xe7ec, 0xcd5e, 0x9f70, 0x3660, 0xa000, 0xefea, 0xeee9, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba6a0, 1},
++	{{0x96c0, 0x6d90, 0x9620, 0x9720, 0x2704, 0x8100, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe748, 0xebe8, 0x92c8, 0x9383, 0x3c80, 0xa000 }, 16, 0x000ba6c0, 1},
++	{{0x280e, 0x8108, 0x6d90, 0x2d00, 0x8514, 0x3c40, 0xa000, 0x2b00, 0x8520, 0x90c0, 0x2e08, 0x8518, 0x9ac0, 0x2002, 0x851c, 0x90c0 }, 16, 0x000ba6e0, 1},
++	{{0x2102, 0x8512, 0x94c0, 0xeee8, 0xece8, 0x94c0, 0xefe8, 0xeae8, 0x3680, 0xa000, 0xebe8, 0xee3d, 0x94c0, 0xec3b, 0xf491, 0x3620 }, 16, 0x000ba700, 1},
++	{{0xa000, 0xef39, 0xea62, 0x36a0, 0xa000, 0xeb38, 0x4316, 0x0394, 0x4410, 0x0312, 0x4317, 0x3680, 0xa100, 0x4393, 0x4396, 0x98c0 }, 16, 0x000ba720, 1},
++	{{0x0dc6, 0x38d0, 0x8008, 0xc19e, 0x98c0, 0x2e00, 0x850e, 0x77d1, 0xece8, 0x96c0, 0xc581, 0x2d0f, 0x84a2, 0x3620, 0xa000, 0x5717 }, 16, 0x000ba740, 1},
++	{{0xec3e, 0x3c00, 0xa800, 0x3ffb, 0x9f00, 0xede8, 0x2e00, 0x850c, 0x98c0, 0x2a00, 0x8510, 0x7de8, 0xc49e, 0x96c0, 0x6f7d, 0xed3e }, 16, 0x000ba760, 1},
++	{{0xebe8, 0x96c0, 0x74d7, 0xeb3a, 0xc29e, 0x98c0, 0x2f00, 0x850a, 0x6d7c, 0xeae8, 0x0514, 0xc685, 0x98c0, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000ba780, 1},
++	{{0xea3f, 0x94c0, 0xefe8, 0xc3a0, 0x9ac0, 0x2c0e, 0x84a2, 0x90c0, 0x2c00, 0x8508, 0x3820, 0xa000, 0x5716, 0x2e00, 0x8506, 0x3a00 }, 16, 0x000ba7a0, 1},
++	{{0xa800, 0x3f18, 0x80ff, 0xef3c, 0xc782, 0x3820, 0xa000, 0x6c7d, 0xece8, 0xc0a0, 0x3820, 0xa000, 0x7652, 0x4413, 0xc484, 0x3a60 }, 16, 0x000ba7c0, 1},
++	{{0xa000, 0x0cc6, 0x38d0, 0x8008, 0xc194, 0x3820, 0xa100, 0xc585, 0x280d, 0x8002, 0x3840, 0xa000, 0xec3e, 0x2c0b, 0x84a4, 0x3820 }, 16, 0x000ba7e0, 1},
++	{{0xa000, 0x5213, 0x2100, 0x8064, 0x3600, 0xa800, 0x35f8, 0x9f00, 0x7c68, 0x6c7d, 0x3554, 0x7653, 0x6e7c, 0x4615, 0x0dc6, 0x38d0 }, 16, 0x000ba800, 1},
++	{{0x8008, 0x90c0, 0x2d0e, 0x84a4, 0x3420, 0xa000, 0x5316, 0x3600, 0xa800, 0x3718, 0x80ff, 0x6c7d, 0x3600, 0xb000, 0x75d4, 0x7650 }, 16, 0x000ba820, 1},
++	{{0x6f7c, 0x4712, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0d, 0x84a6, 0x3420, 0xa000, 0x5615, 0x3600, 0xa800, 0x3df8, 0x9f00, 0x7c68 }, 16, 0x000ba840, 1},
++	{{0x6c7d, 0x3600, 0xb004, 0x7454, 0x7651, 0x3400, 0xa804, 0x6c7c, 0x3420, 0xa000, 0x4417, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0f }, 16, 0x000ba860, 1},
++	{{0x84a6, 0x5517, 0x3b18, 0x80ff, 0x6c7d, 0x3400, 0xa004, 0x74d4, 0x3400, 0xa804, 0x6d7c, 0x3420, 0xa000, 0x4514, 0x0dc6, 0x38d0 }, 16, 0x000ba880, 1},
++	{{0x8008, 0x90c0, 0x2d0b, 0x8490, 0x3420, 0xa000, 0x5513, 0x3600, 0xa804, 0x3b19, 0x8001, 0x34a0, 0xa000, 0x411d, 0x0ec6, 0x38d0 }, 16, 0x000ba8a0, 1},
++	{{0x8008, 0x90c0, 0x2e0e, 0x8490, 0x3420, 0xa000, 0x5516, 0x3600, 0xa804, 0x3b19, 0x8002, 0x3400, 0xa804, 0x74c1, 0x34a0, 0xa000 }, 16, 0x000ba8c0, 1},
++	{{0x411d, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0a, 0x8490, 0x3420, 0xa000, 0x5512, 0x3600, 0xa804, 0x3b19, 0x8004, 0x3400, 0xa004 }, 16, 0x000ba8e0, 1},
++	{{0x7ce2, 0x34a0, 0xa000, 0x411d, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0d, 0x8490, 0x3420, 0xa000, 0x5115, 0x3600, 0xa804, 0x331d }, 16, 0x000ba900, 1},
++	{{0x8008, 0x3400, 0xa004, 0x7ee3, 0x34a0, 0xa000, 0x451d, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0f, 0x8492, 0x3420, 0xa000, 0x5517 }, 16, 0x000ba920, 1},
++	{{0x34a0, 0xa000, 0x451d, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0c, 0x8496, 0x3420, 0xa000, 0x5114, 0x34a0, 0xa000, 0x411d, 0x0cc6 }, 16, 0x000ba940, 1},
++	{{0x38d0, 0x8008, 0x90c0, 0x2c0a, 0x8498, 0x3420, 0xa000, 0x5112, 0x34a0, 0xa000, 0x411d, 0x0fc6, 0x38d0, 0x8008, 0x3620, 0xa000 }, 16, 0x000ba960, 1},
++	{{0x2d0a, 0x8002, 0x9ac0, 0x2f0e, 0x849a, 0x90c0, 0x2a0d, 0x8002, 0x3420, 0xa000, 0x5116, 0x34a0, 0xa000, 0x4115, 0x3a40, 0xa100 }, 16, 0x000ba980, 1},
++	{{0x0ec6, 0x38d0, 0x8008, 0x5515, 0x3400, 0xa800, 0xd815, 0x96c0, 0x6461, 0x2e0b, 0x8494, 0x3a20, 0xa000, 0x5113, 0x32e4, 0x3c48 }, 16, 0x000ba9a0, 1},
++	{{0x8001, 0x3420, 0xa000, 0x4112, 0x3620, 0xa000, 0x5512, 0x409d, 0x3800, 0xa800, 0xd815, 0x2100, 0x8064, 0x32e4, 0x3c48, 0x8001 }, 16, 0x000ba9c0, 1},
++	{{0x6461, 0x3820, 0xa000, 0x6c90, 0x4095, 0x5510, 0x3600, 0xa004, 0xd2a1, 0xed50, 0x4115, 0x3626, 0xa000, 0xc1f7, 0xed48, 0x0995 }, 16, 0x000ba9e0, 1},
++	{{0xeaed, 0xea66, 0x4112, 0x96c2, 0x01c6, 0x3684, 0x8009, 0x3606, 0xa800, 0xdc81, 0x8034, 0x96c2, 0x01c2, 0x3684, 0x8009, 0x3400 }, 16, 0x000baa00, 1},
++	{{0xa004, 0xd2a2, 0x90c0, 0x3a62, 0xa000, 0x05c6, 0x3684, 0x8009, 0xc1fb, 0x3402, 0xa804, 0xde81, 0x3822, 0xa000, 0x05c2, 0x3684 }, 16, 0x000baa20, 1},
++	{{0x8009, 0x3840, 0xa004, 0x6e90, 0xc181, 0x5895, 0x3640, 0xa000, 0x5112, 0xf542, 0x3244, 0x33d0, 0x800b, 0x3420, 0xa000, 0xf141 }, 16, 0x000baa40, 1},
++	{{0x2c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000baa60, 1},
++	{{0x9ac0, 0x64e9, 0x0dc6, 0x38d0, 0x8008, 0xc19e, 0x98c0, 0x280c, 0x8112, 0x7651, 0xc581, 0x3c61, 0xa000, 0x2100, 0x84a2, 0x90c0 }, 16, 0x000baa80, 1},
++	{{0x2100, 0x84a8, 0x3a26, 0xa100, 0x90c0, 0xcb41, 0x2300, 0x84a2, 0x3a27, 0xa000, 0x90c0, 0xeaec, 0x2300, 0x84a8, 0x3600, 0xa100 }, 16, 0x000baaa0, 1},
++	{{0xeb1d, 0xc843, 0x94c0, 0x5313, 0x9620, 0x98c0, 0x37f8, 0x9f00, 0xc69e, 0xea62, 0x7c68, 0x2c7d, 0x4014, 0x34d4, 0x4414, 0x6d7c }, 16, 0x000baac0, 1},
++	{{0x4514, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0xe81b, 0x5010, 0x311a, 0x80ff, 0x2e7d, 0x4212, 0x4612, 0x94c0, 0x4612, 0x9621, 0x9f71 }, 16, 0x000baae0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xcd83, 0x280e, 0x8648, 0x3820, 0xa000, 0x5d16, 0x270c, 0x8020, 0x3a20 }, 16, 0x000bab00, 1},
++	{{0xa000, 0x0dc2, 0x3688, 0x8009, 0xe7ec, 0x36c0, 0xa100, 0xed8d, 0xeeed, 0x3880, 0xa000, 0xedfe, 0x2518, 0x8550, 0x3c20, 0xa000 }, 16, 0x000bab20, 1},
++	{{0x64e9, 0x3cc0, 0x3670, 0x8009, 0xc9ff, 0x9ac0, 0x2e0f, 0x8004, 0x90c0, 0x2e09, 0x8004, 0x3680, 0xa000, 0xed1c, 0xeaef, 0x3a80 }, 16, 0x000bab40, 1},
++	{{0xa000, 0x5b95, 0x34f9, 0x3fff, 0xbfff, 0x90c0, 0x9b61, 0x96c0, 0x8023, 0x2e09, 0x8002, 0x94c0, 0xcca0, 0xebe9, 0xc581, 0x0516 }, 16, 0x000bab60, 1},
++	{{0xeb3c, 0x1513, 0x5313, 0x0519, 0x30a4, 0x3082, 0x800b, 0x4311, 0x2e0b, 0x8004, 0xeceb, 0xec62, 0x1614, 0x30a4, 0x3082, 0x800b }, 16, 0x000bab80, 1},
++	{{0x4613, 0x96c0, 0x64e9, 0xcba2, 0xe9ef, 0xe97a, 0xea3b, 0x94c0, 0x5712, 0x84b4, 0x4717, 0x1011, 0xebee, 0x96c0, 0x6469, 0xeaee }, 16, 0x000baba0, 1},
++	{{0xeb70, 0x94c0, 0xea6c, 0x80a1, 0x1293, 0x39c8, 0x3c00, 0xbfff, 0x0292, 0xccff, 0x1d91, 0x34f9, 0x3fff, 0xbfff, 0x1193, 0xf442 }, 16, 0x000babc0, 1},
++	{{0x98c0, 0xecad, 0x3ac8, 0x3c04, 0xbfff, 0x801b, 0x39c8, 0x3c00, 0xbfff, 0x5092, 0x5591, 0xcb45, 0x90c0, 0xebad, 0x85f7, 0x94c0 }, 16, 0x000babe0, 1},
++	{{0xf542, 0xf045, 0x98c0, 0x6e90, 0x6f90, 0xf3c2, 0xf6c5, 0x98c0, 0x65e0, 0x3cce, 0x8410, 0x7ed0, 0x98c0, 0x36cc, 0x9410, 0x7dd0 }, 16, 0x000bac00, 1},
++	{{0x6761, 0x96c0, 0x65e1, 0x38ed, 0x8400, 0xd5c6, 0x1505, 0xa001, 0x90c0, 0x9ac6, 0xeaee, 0xc681, 0xd6c7, 0x90c0, 0x6c10, 0x9ac6 }, 16, 0x000bac20, 1},
++	{{0xea68, 0x90c0, 0x64e1, 0xd6c6, 0x65e1, 0xd4c3, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd445, 0xc581, 0xc282, 0x94c6, 0x4216, 0xd445 }, 16, 0x000bac40, 1},
++	{{0xc012, 0xef62, 0x2f09, 0x8002, 0x1511, 0x30a4, 0x3082, 0x800b, 0x4517, 0x98c0, 0xefe9, 0x3bc8, 0x3c00, 0xbfff, 0x94c0, 0xef62 }, 16, 0x000bac60, 1},
++	{{0xf445, 0x1417, 0x3ac8, 0x3c00, 0xbfff, 0x4411, 0x1c93, 0x3bc8, 0x3c04, 0xbfff, 0x90c0, 0x3480, 0xa000, 0xe9ac, 0x8019, 0x5693 }, 16, 0x000bac80, 1},
++	{{0x5592, 0xc055, 0x90c0, 0x3480, 0xa000, 0xe8ac, 0x85f3, 0x94c0, 0xf545, 0xf643, 0x98c0, 0x6e10, 0x6e90, 0xf7c5, 0xf3c3, 0x98c0 }, 16, 0x000baca0, 1},
++	{{0x67e0, 0x36c9, 0x8410, 0x7e50, 0x98c0, 0x3eca, 0x9410, 0x7fd0, 0x64e1, 0x96c0, 0x67e1, 0x34ec, 0x8400, 0xd7c1, 0x1505, 0xa001 }, 16, 0x000bacc0, 1},
++	{{0x90c0, 0x9ac6, 0xecee, 0x90c0, 0x67e0, 0xc581, 0xd645, 0x94c6, 0xec68, 0xd645, 0x2660, 0xc114, 0x307c, 0x64e0, 0x2518, 0x8386 }, 16, 0x000bace0, 1},
++	{{0x7064, 0x8409, 0x70ff, 0x2518, 0x837c, 0x3680, 0xa000, 0xe8ee, 0x5617, 0x3a80, 0xa000, 0xe87c, 0x3bc8, 0x3c00, 0xbfff, 0x3680 }, 16, 0x000bad00, 1},
++	{{0xa000, 0x5710, 0xeaee, 0x96c0, 0x6fdf, 0xea74, 0xc159, 0x3677, 0x0717, 0xf145, 0x666a, 0x92c2, 0x6c10, 0x92c2, 0x4017, 0x5317 }, 16, 0x000bad20, 1},
++	{{0x4311, 0x1f93, 0x5192, 0x3ac8, 0x3c04, 0xbfff, 0x3a80, 0xa000, 0xe9af, 0x3bc8, 0x3c00, 0xbfff, 0x8015, 0x5392, 0x5593, 0xc945 }, 16, 0x000bad40, 1},
++	{{0x90c0, 0xe9af, 0x85f7, 0x94c0, 0xf545, 0xf348, 0x98c0, 0x6d10, 0x6f90, 0xf6c5, 0xf3c8, 0x98c0, 0x6760, 0x36cb, 0x8410, 0x7d50 }, 16, 0x000bad60, 1},
++	{{0x98c0, 0x3ccd, 0x9410, 0x7f50, 0x65e1, 0x96c0, 0x6761, 0x3aea, 0x8400, 0xd743, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd547, 0xc381 }, 16, 0x000bad80, 1},
++	{{0x64e1, 0x96c6, 0x6c10, 0xd543, 0x6761, 0xd4c6, 0x1505, 0xa001, 0x96c0, 0xd442, 0xcba0, 0xe9ee, 0x94c6, 0x4d16, 0xc281, 0x94c6 }, 16, 0x000bada0, 1},
++	{{0xe93b, 0xd442, 0x1411, 0xc014, 0x2669, 0xc181, 0x2718, 0x82b6, 0x33a4, 0x2a80, 0x800b, 0x31a4, 0x3082, 0x800b, 0x96c0, 0x64e9 }, 16, 0x000badc0, 1},
++	{{0xcaa2, 0xebee, 0x9ac0, 0x2e09, 0x8002, 0x90c0, 0x2518, 0x812e, 0x94c0, 0xeb3a, 0xefee, 0x1513, 0xecee, 0x96c0, 0x66e9, 0xef7c }, 16, 0x000bade0, 1},
++	{{0xec7a, 0x94c0, 0x5517, 0x8017, 0x1714, 0x5211, 0x6edb, 0x2f29, 0x30a4, 0x2e26, 0x800b, 0x4611, 0x94c0, 0xcca0, 0xeae9, 0x90c0 }, 16, 0x000bae00, 1},
++	{{0xea3c, 0x5612, 0x4611, 0x94c0, 0xe942, 0xcca8, 0x94c0, 0xebe9, 0xefee, 0x94c0, 0xeb62, 0xef70, 0x1513, 0xebee, 0x0511, 0xeb6c }, 16, 0x000bae20, 1},
++	{{0x1597, 0xe93c, 0x1411, 0xe9ee, 0x9ac0, 0x6669, 0x3401, 0x2000, 0x801e, 0xe96c, 0x94c0, 0x5091, 0x8017, 0x7c41, 0x307c, 0x4091 }, 16, 0x000bae40, 1},
++	{{0x840d, 0x0491, 0x31a4, 0x2e6c, 0x800b, 0x4593, 0x98c0, 0x3bc8, 0x3c00, 0xbfff, 0xcaff, 0x98c0, 0xefee, 0x37f9, 0x3fff, 0xbfff }, 16, 0x000bae60, 1},
++	{{0x1993, 0xef6c, 0x1197, 0xf748, 0x98c0, 0xeaa9, 0x3bc8, 0x3c04, 0xbfff, 0x801b, 0x3ac8, 0x3c00, 0xbfff, 0x5093, 0x5792, 0xcd47 }, 16, 0x000bae80, 1},
++	{{0x90c0, 0xeda9, 0x85f7, 0x94c0, 0xf748, 0xf046, 0x98c0, 0x6e90, 0x6f90, 0xf2c8, 0xf4c6, 0x98c0, 0x6560, 0x38cc, 0x8410, 0x7ed0 }, 16, 0x000baea0, 1},
++	{{0x98c0, 0x34ce, 0x9410, 0x7d50, 0x6661, 0x96c0, 0x6561, 0x3ced, 0x8400, 0xd544, 0x1505, 0xa001, 0x90c0, 0x9ac6, 0xeaee, 0xc481 }, 16, 0x000baec0, 1},
++	{{0xd6c7, 0x90c0, 0x6c10, 0x9ac6, 0xea68, 0x90c0, 0x64e1, 0xd6c4, 0x6561, 0xd4c2, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd445, 0xc581 }, 16, 0x000baee0, 1},
++	{{0xc682, 0x94c6, 0x4616, 0xd445, 0x98c0, 0xc012, 0x31a4, 0x3082, 0x800b, 0x3a40, 0xa000, 0x3cc8, 0x3c00, 0xbfff, 0xc9ff, 0x31f9 }, 16, 0x000baf00, 1},
++	{{0x3fff, 0xbfff, 0x1a94, 0xf148, 0x3bc8, 0x3c04, 0xbfff, 0x3a80, 0xa000, 0xe9aa, 0x39c8, 0x3c00, 0xbfff, 0x8015, 0x5393, 0x5491 }, 16, 0x000baf20, 1},
++	{{0xcf44, 0x90c0, 0xefaa, 0x85f7, 0x94c0, 0xf448, 0xf347, 0x98c0, 0x6e90, 0x6c90, 0xf7c8, 0xf3c7, 0x98c0, 0x67e0, 0x36c8, 0x8410 }, 16, 0x000baf40, 1},
++	{{0x7ed0, 0x98c0, 0x3ece, 0x9410, 0x7fd0, 0x6461, 0x96c0, 0x67e1, 0x3ced, 0x8400, 0xd7c0, 0x1505, 0xa001, 0x90c0, 0x9ac6, 0xefee }, 16, 0x000baf60, 1},
++	{{0x90c0, 0x67e0, 0xc181, 0xd6c1, 0x94c6, 0xef68, 0xd6c1, 0x26e0, 0xc117, 0x307d, 0x64e0, 0x2518, 0x80e0, 0x7065, 0x8409, 0x70ff }, 16, 0x000baf80, 1},
++	{{0x2518, 0x80d6, 0x98c0, 0x2e0b, 0x8002, 0x6d90, 0xeaee, 0x2c90, 0x1013, 0xea7c, 0x2469, 0x1412, 0x39c8, 0x3c00, 0xbfff, 0x94c0 }, 16, 0x000bafa0, 1},
++	{{0xc15e, 0x8419, 0xeb42, 0x0313, 0x32a4, 0x2a80, 0x800b, 0x4316, 0x31a4, 0x3082, 0x800b, 0x98c0, 0x6ec0, 0xf648, 0x2b0c, 0x8002 }, 16, 0x000bafc0, 1},
++	{{0x34f5, 0x0513, 0x3ac8, 0x3c04, 0xbfff, 0x64ea, 0x92c2, 0x6f10, 0x92c2, 0x4613, 0x5513, 0x4514, 0x1b91, 0xec78, 0x1194, 0x39c8 }, 16, 0x000bafe0, 1},
++	{{0x3c00, 0xbfff, 0x3480, 0xa000, 0xe9ab, 0x8015, 0x5592, 0x5291, 0xc842, 0x90c0, 0xe8ab, 0x85f7, 0x94c0, 0xf248, 0xf544, 0x98c0 }, 16, 0x000bb000, 1},
++	{{0x6f10, 0x6f90, 0xf3c8, 0xf5c4, 0x98c0, 0x65e0, 0x3aca, 0x8410, 0x7f50, 0x98c0, 0x36cd, 0x9410, 0x7dd0, 0x6561, 0x96c0, 0x65e1 }, 16, 0x000bb020, 1},
++	{{0x3aee, 0x8400, 0xd5c2, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd747, 0xc281, 0x6c10, 0x96c6, 0x64e1, 0xd742, 0x65e1, 0xd4c3, 0x1505 }, 16, 0x000bb040, 1},
++	{{0xa001, 0x90c0, 0x94c6, 0xd446, 0xc681, 0x98c6, 0x30a4, 0x3082, 0x800b, 0xd446, 0xc017, 0x2e09, 0x8004, 0xebe9, 0xeb62, 0x5613 }, 16, 0x000bb060, 1},
++	{{0x4611, 0x96c0, 0x5916, 0x27ec, 0x9fe0, 0x94c0, 0xe7ec, 0xee44, 0x3620, 0xa000, 0xe9ae, 0x5016, 0x94c0, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000bb080, 1},
++	{{0x9621, 0x9721, 0x9f70, 0x96c3, 0x09c2, 0x3688, 0x8009, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xe748 }, 16, 0x000bb0a0, 1},
++	{{0x280f, 0x8622, 0x1417, 0xebef, 0x98c0, 0x6669, 0xeb62, 0x2e00, 0x851e, 0x94c0, 0x5213, 0x845d, 0xd121, 0x90c0, 0x98c2, 0x04c6 }, 16, 0x000bb0c0, 1},
++	{{0x3684, 0x8009, 0xc6f7, 0x94c6, 0x8028, 0xde06, 0x96c2, 0x04c2, 0x3684, 0x8009, 0xd122, 0x90c0, 0x98c2, 0x06c6, 0x3684, 0x8009 }, 16, 0x000bb0e0, 1},
++	{{0xc5fb, 0x92c2, 0xdf05, 0x96c2, 0x06c2, 0x3684, 0x8009, 0x98c0, 0x2f0c, 0x802e, 0x6d10, 0xc481, 0x2c90, 0x1894, 0xf242, 0x3244 }, 16, 0x000bb100, 1},
++	{{0x33d0, 0x800b, 0xf441, 0x2c10, 0x31a4, 0x32b4, 0x800b, 0x94c0, 0xebef, 0xf6c9, 0x96c0, 0xeb3e, 0x2a00, 0x8514, 0x96c0, 0x5193 }, 16, 0x000bb120, 1},
++	{{0x2b00, 0x8522, 0x98c0, 0x2202, 0x851a, 0x64ea, 0xedef, 0x94c0, 0xeeef, 0xecef, 0x98c6, 0xed3a, 0x02c6, 0x3680, 0x8009, 0x94c6 }, 16, 0x000bb140, 1},
++	{{0xee3b, 0x7941, 0x3e46, 0xa000, 0x90c0, 0xec3a, 0x02c2, 0x3680, 0x8009, 0x676a, 0x8471, 0x98c0, 0x9b46, 0x2b03, 0x800a, 0x90c0 }, 16, 0x000bb160, 1},
++	{{0x24e9, 0x5515, 0x94c0, 0x7ac1, 0x8458, 0x4515, 0x5411, 0x3674, 0x9f00, 0x800d, 0x3694, 0x80ff, 0x94c6, 0x8009, 0x6c90, 0xc181 }, 16, 0x000bb180, 1},
++	{{0x1b96, 0x5594, 0x90c0, 0xeb18, 0x92bb, 0x6e09, 0x0494, 0xd641, 0x4494, 0x5b96, 0x90c0, 0xeb18, 0x919b, 0x5396, 0x79c1, 0x96c0 }, 16, 0x000bb1a0, 1},
++	{{0x3613, 0x80ff, 0x4396, 0x92c2, 0x6f90, 0x92c2, 0x4796, 0x5794, 0x3617, 0x8095, 0x92c3, 0x6c90, 0x92c2, 0xc181, 0x92d0, 0xe942 }, 16, 0x000bb1c0, 1},
++	{{0x90c0, 0x90c0, 0xeeef, 0xee62, 0x5516, 0xd2a1, 0x8437, 0x24e9, 0xc0f7, 0x90c0, 0x96c3, 0x03c6, 0x3684, 0x8009, 0x96c7, 0x845a }, 16, 0x000bb1e0, 1},
++	{{0x0903, 0xa008, 0x96c3, 0x03c2, 0x3684, 0x8009, 0x07c6, 0x3684, 0x8009, 0x98c0, 0xdf80, 0x30a4, 0x3256, 0x800b, 0x07c2, 0x3684 }, 16, 0x000bb200, 1},
++	{{0x8009, 0xd2a2, 0x8433, 0x64e9, 0x90c0, 0x98c1, 0x05c6, 0x3684, 0x8009, 0xc3fb, 0x96c2, 0x02c6, 0x3684, 0x8009, 0x98c1, 0x0905 }, 16, 0x000bb220, 1},
++	{{0xa004, 0x90c0, 0xdd03, 0x96c3, 0x05c2, 0x3684, 0x8009, 0x96c2, 0x02c2, 0x3684, 0x8009, 0x33a4, 0x2b00, 0x800b, 0x1116, 0x0ac6 }, 16, 0x000bb240, 1},
++	{{0x38d0, 0x8008, 0xd0a2, 0x96c0, 0x8435, 0x2a0c, 0x82b0, 0x5514, 0xd2a2, 0x8429, 0x96c0, 0x676a, 0x2f0c, 0x802a, 0x841f, 0x96c0 }, 16, 0x000bb260, 1},
++	{{0x9b46, 0x2b03, 0x8012, 0x3d20, 0x33b4, 0x8009, 0x92c0, 0x90c0, 0x92d0, 0x5014, 0x3e10, 0x8147, 0x401d, 0x98c0, 0x2f0a, 0x802e }, 16, 0x000bb280, 1},
++	{{0x6c10, 0xc181, 0x188a, 0xf141, 0x3244, 0x33d0, 0x800b, 0x1112, 0xf042, 0x6c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000bb2a0, 1},
++	{{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0xc390, 0x94c0, 0x9e20, 0xc94e, 0x94c0 }, 16, 0x000bb2c0, 1},
++	{{0xe748, 0xeee8, 0x32e4, 0x3c8a, 0x8001, 0xf341, 0x98c0, 0x2e0c, 0x8002, 0x6e10, 0xc946, 0x0414, 0x3a80, 0x31a4, 0x8009, 0xec44 }, 16, 0x000bb2e0, 1},
++	{{0x0414, 0xedec, 0x1019, 0xed62, 0x0016, 0xec42, 0x1311, 0xe942, 0x4315, 0x55d2, 0x3b1b, 0x8001, 0x65e9, 0x90c0, 0x92c3, 0x5816 }, 16, 0x000bb300, 1},
++	{{0x90c0, 0x92c3, 0xe8fc, 0x92c3, 0x4816, 0x5111, 0x331c, 0x800f, 0x441c, 0x1411, 0xcc4e, 0x38cb, 0x8104, 0x32c4, 0x20c0, 0x800a }, 16, 0x000bb320, 1},
++	{{0x4314, 0x94c0, 0xcc46, 0xe768, 0x9e21, 0x94c0, 0xec42, 0x9621, 0x9f70, 0x4894, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb340, 1},
++	{{0x3c80, 0xa006, 0x7456, 0x2809, 0x800c, 0x74d7, 0xe8ef, 0x5d91, 0x90c0, 0x5f95, 0x90c0, 0x2f0b, 0x8004, 0x5493, 0x9ac0, 0x399b }, 16, 0x000bb360, 1},
++	{{0x8000, 0x90c0, 0x390d, 0x8001, 0x65e9, 0x849d, 0x96c0, 0x66e9, 0x395a, 0x8000, 0x8493, 0x2569, 0x5597, 0x96c0, 0x3b1e, 0x8010 }, 16, 0x000bb380, 1},
++	{{0x808d, 0x96c0, 0x6769, 0x3b08, 0x8020, 0x847d, 0x96c0, 0x6469, 0x3b5b, 0x8000, 0x8473, 0x96c0, 0x65e9, 0x390a, 0x8200, 0x8099 }, 16, 0x000bb3a0, 1},
++	{{0x6569, 0x94c0, 0x9f51, 0x9a51, 0x94c2, 0x0914, 0xa200, 0x94c2, 0x4493, 0xef68, 0x94c2, 0x5217, 0xea66, 0x92c2, 0x4212, 0x5393 }, 16, 0x000bb3c0, 1},
++	{{0x370d, 0x8100, 0x66e9, 0x90c0, 0x96c3, 0xe96a, 0x0913, 0xa080, 0x94c7, 0xede9, 0x4393, 0x94c7, 0xed66, 0x5710, 0x94c7, 0x845b }, 16, 0x000bb3e0, 1},
++	{{0x4711, 0x2e10, 0x1015, 0xe96a, 0x3861, 0xd420, 0x94c0, 0x4015, 0x804b, 0x4415, 0x5793, 0x0917, 0xa180, 0x4793, 0x1610, 0x30a4 }, 16, 0x000bb400, 1},
++	{{0x3456, 0x800b, 0x4611, 0x98c0, 0x32f8, 0x3fff, 0xbf7f, 0xe96a, 0xdd04, 0x4293, 0x5311, 0x39e1, 0xd5a0, 0x94c7, 0x4311, 0x6f10 }, 16, 0x000bb420, 1},
++	{{0x98c3, 0x4611, 0x33f8, 0x3fff, 0xbcff, 0x92c3, 0x5293, 0x92c3, 0xdd82, 0x92c3, 0x4393, 0x1693, 0xeb4a, 0x96c0, 0x3d0d, 0x8100 }, 16, 0x000bb440, 1},
++	{{0x5613, 0x96c0, 0x66e9, 0x3d1f, 0x8001, 0x96c0, 0x3d1e, 0x801f, 0x8035, 0x27e9, 0x77c6, 0x94c0, 0xd49f, 0x8029, 0x3551, 0x24e8 }, 16, 0x000bb460, 1},
++	{{0x64e6, 0x2566, 0x7ceb, 0x9ac0, 0x351a, 0x87ff, 0x90c0, 0x3e11, 0x85a9, 0x3e12, 0x85a9, 0x7d6b, 0x6cd8, 0x92c3, 0x64e4, 0x3c40 }, 16, 0x000bb480, 1},
++	{{0xb200, 0x7471, 0x77d1, 0x7750, 0xefe8, 0x9f71, 0x90c0, 0x90c0, 0x98c0, 0x38c0, 0x368c, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb4a0, 1},
++	{{0x94c0, 0x9220, 0x9320, 0x9420, 0x6d6c, 0x75fa, 0x6d70, 0x6d60, 0xda12, 0x6661, 0x6d74, 0x6ccc, 0x7452, 0x64e0, 0x9421, 0x94c0 }, 16, 0x000bb4c0, 1},
++	{{0x9221, 0x9321, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9530, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x9220, 0x7550, 0xd0a1 }, 16, 0x000bb4e0, 1},
++	{{0x8029, 0x34f1, 0x9fff, 0x8021, 0x9750, 0xd891, 0x6466, 0x6c50, 0x1005, 0xa001, 0x90c0, 0x90c0, 0x92c8, 0x7051, 0x7470, 0xdd11 }, 16, 0x000bb500, 1},
++	{{0x656a, 0x2518, 0x8006, 0x6464, 0x9221, 0x9531, 0x90c0, 0x90c0, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb520, 1},
++	{{0x9530, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x9220, 0x7478, 0x74f9, 0x3260, 0x3fff, 0x8000, 0xd0a1, 0x2518, 0x8026, 0x70fa, 0x2518 }, 16, 0x000bb540, 1},
++	{{0x8014, 0x9750, 0x6c50, 0xd891, 0x92c8, 0x7051, 0x7470, 0x2118, 0x8010, 0x7061, 0x92c3, 0x7079, 0x6c10, 0x92c2, 0x7841, 0x9221 }, 16, 0x000bb560, 1},
++	{{0x9531, 0x90c0, 0x90c0, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9750, 0x1005, 0xa001, 0xd810, 0xd891, 0x92c8, 0x7051, 0x7470 }, 16, 0x000bb580, 1},
++	{{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9530, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x94c0, 0x9220, 0x9320 }, 16, 0x000bb5a0, 1},
++	{{0x7550, 0xd991, 0x9750, 0x6466, 0x64e6, 0x1005, 0xa001, 0x90c0, 0x90c0, 0x92c8, 0x7053, 0xd818, 0x6468, 0x92c3, 0x6c51, 0x6568 }, 16, 0x000bb5c0, 1},
++	{{0x92c3, 0x6464, 0x94c0, 0x9221, 0x9321, 0x9531, 0x90c0, 0x90c0, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb5e0, 1},
++	{{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb600, 1},
++	{{0xfffe, 0x000a, 0x000c, 0xfff6, 0xffff, 0xfffd, 0x0010, 0xfff0, 0x000c, 0x000a, 0xfff4, 0xffff, 0x0005, 0x0026, 0xfff4, 0x0031 }, 16, 0x000bf000, 1},
++	{{0xffa8, 0x004e, 0xff6a, 0x0113, 0xfe58, 0x0273, 0xfc44, 0x069d, 0xf4da, 0x199b, 0x2e6c, 0x995b, 0x1e2a, 0xdac1, 0x27d5, 0xe6c7 }, 16, 0x000bf020, 1},
++	{{0x2576, 0xe6e1, 0x1083, 0x05b4, 0x0797, 0x0789, 0xfe41, 0xf10c, 0x0325, 0xfc82, 0x0094, 0xfeed, 0x062a, 0xfbbd, 0x0926, 0xf621 }, 16, 0x000bf040, 1},
++	{{0xfff5, 0xf8c4, 0x0190, 0xfb4e, 0xfee9, 0xf9d1, 0x0005, 0xff24, 0x0788, 0x035d, 0x07c8, 0x039c, 0x03ee, 0xfe80, 0x009a, 0xfc47 }, 16, 0x000bf060, 1},
++	{{0xfff6, 0xfde7, 0xff09, 0xfbcc, 0xff37, 0xff13, 0x01e1, 0x0209, 0x01c4, 0xfd68, 0x0044, 0xfe82, 0x0042, 0xfe7d, 0xfebb, 0xfe5e }, 16, 0x000bf080, 1},
++	{{0x01e0, 0x0169, 0x02c1, 0x0013, 0xff5b, 0x0097, 0x01bf, 0x015e, 0xff3e, 0xfd80, 0xfe46, 0xff38, 0x00ab, 0x00b7, 0x0018, 0xff39 }, 16, 0x000bf0a0, 1},
++	{{0x006c, 0x0066, 0x0147, 0x0040, 0xff6a, 0xff6f, 0xffd5, 0x005c, 0xfff8, 0xff7e, 0xff44, 0x000c, 0x0018, 0x004f, 0xffd9, 0xff7c }, 16, 0x000bf0c0, 1},
++	{{0xff81, 0xffae, 0x0039, 0xffab, 0xffa4, 0xff8f, 0x000b, 0x0051, 0x00ab, 0x007d, 0xffd6, 0x0033, 0x0030, 0x00be, 0x0035, 0xffe2 }, 16, 0x000bf0e0, 1},
++	{{0xff46, 0xffa2, 0xffc7, 0xffd9, 0xffd5, 0xff3f, 0xff1d, 0xff3c, 0xffd1, 0xffc1, 0x0006, 0xffd7, 0xfff8, 0xffe6, 0x0002, 0x0026 }, 16, 0x000bf100, 1},
++	{{0x0007, 0x004d, 0x0054, 0x006d, 0x0025, 0xfffe, 0xffe8, 0xfff9, 0xffe1, 0xffb4, 0xffa0, 0xff82, 0xff7b, 0xff88, 0xff97, 0xffbd }, 16, 0x000bf120, 1},
++	{{0xffc4, 0xffb7, 0xff74, 0xffcd, 0xffd1, 0x0003, 0xffee, 0xfffb, 0xfff3, 0xffed, 0x000f, 0x0047, 0x0056, 0x002e, 0x0028, 0xffe4 }, 16, 0x000bf140, 1},
++	{{0xffa6, 0xff9e, 0xff9c, 0xff91, 0xff88, 0xff7f, 0xffad, 0xffbe, 0xffcd, 0xffdf, 0xffcf, 0xffa6, 0xffad, 0xffe2, 0x0004, 0xfffb }, 16, 0x000bf160, 1},
++	{{0xfff1, 0xffed, 0xfffb, 0x0011, 0x0016, 0xfff0, 0xffe4, 0xffb2, 0xffba, 0xffc8, 0xffc8, 0xffc8, 0xffc9, 0xffa3, 0xffbe, 0xffc2 }, 16, 0x000bf180, 1},
++	{{0xffd4, 0xffe5, 0xffe3, 0xffcb, 0xffde, 0xffe4, 0xffef, 0x0002, 0x0005, 0xffde, 0xfff5, 0xfff4, 0xfff9, 0xffde, 0xffb7, 0xffce }, 16, 0x000bf1a0, 1},
++	{{0xffb7, 0xffec, 0xffeb, 0xffd4, 0xffcf, 0xffcf, 0xffbd, 0xffd1, 0xffdf, 0xffcc, 0xffed, 0xfff2, 0xfff1, 0x000d, 0x001d, 0x0015 }, 16, 0x000bf1c0, 1},
++	{{0xffe7, 0x000f, 0xffee, 0xffe1, 0xfff2, 0xffdb, 0xffd6, 0xffce, 0xffdb, 0xffd7, 0xffe5, 0xffdc, 0xffc2, 0xffc8, 0xffcd, 0x0026 }, 16, 0x000bf1e0, 1},
++	{{0x0073, 0xffba, 0xfff2, 0xffe6, 0x000c, 0xfff6, 0xffda, 0xfff8, 0xffce, 0xffdc, 0x0000, 0x0032, 0xffe0, 0x001e, 0xffd6, 0x002f }, 16, 0x000bf200, 1},
++	{{0x005c, 0xffee, 0x000e, 0x0033, 0xffa6, 0xffd6, 0x00df, 0x0013, 0x003c, 0xff5e, 0xfa90, 0x043f, 0xfdb3, 0x0574, 0xfd1e, 0x02f5 }, 16, 0x000bf220, 1},
++	{{0xfea4, 0x0322, 0xffcc, 0xfdca, 0x00a2, 0xfb86, 0x0116, 0xfdde, 0x009c, 0xff8b, 0x0147, 0xffe6, 0x0093, 0x009f, 0xff83, 0x01a7 }, 16, 0x000bf240, 1},
++	{{0xff8c, 0x0065, 0xff4e, 0xffd9, 0x00dd, 0x009e, 0x00ef, 0x000b, 0xffda, 0xffd1, 0xff7c, 0xff37, 0xff70, 0xfed0, 0xfef6, 0xffb6 }, 16, 0x000bf260, 1},
++	{{0xffca, 0x009b, 0x0073, 0x00e0, 0x00d8, 0x004a, 0x0099, 0xffee, 0x0005, 0xffe8, 0xffcb, 0xffea, 0xffea, 0x000c, 0x0002, 0x0059 }, 16, 0x000bf280, 1},
++	{{0xffbb, 0xfff4, 0xff94, 0x0004, 0xffee, 0xffe0, 0xffbb, 0xff90, 0xffeb, 0x0063, 0x003c, 0xffe5, 0x004c, 0x0008, 0x004e, 0x0079 }, 16, 0x000bf2a0, 1},
++	{{0xffb8, 0x0025, 0xff9a, 0xffd7, 0x0020, 0xff70, 0x004f, 0xff88, 0x004c, 0x000c, 0xfff6, 0x0038, 0xffa4, 0x002c, 0x0021, 0x0038 }, 16, 0x000bf2c0, 1},
++	{{0x0004, 0xfff4, 0x0000, 0x003e, 0x0055, 0x0031, 0xffdf, 0xffdf, 0xffd3, 0xfffd, 0xff97, 0xfffc, 0xff60, 0xffeb, 0xffa2, 0xfffd }, 16, 0x000bf2e0, 1},
++	{{0x0039, 0xffd6, 0x0055, 0xffcb, 0x008b, 0x002a, 0x0039, 0x002b, 0x0053, 0xffeb, 0x0046, 0xffd6, 0x0077, 0xfffb, 0xff8b, 0x0058 }, 16, 0x000bf300, 1},
++	{{0xff3c, 0x0063, 0xff0e, 0x005a, 0xff81, 0x0001, 0xff84, 0xfff8, 0x005a, 0xffd6, 0x001c, 0xffe7, 0x007c, 0xffcc, 0x0078, 0xfff2 }, 16, 0x000bf320, 1},
++	{{0x0066, 0xffd6, 0x005f, 0xfff3, 0xff9d, 0xffff, 0x007f, 0xfff5, 0xffca, 0xffff, 0xffc2, 0x0047, 0xff5c, 0x003a, 0xffc3, 0x000f }, 16, 0x000bf340, 1},
++	{{0xff94, 0xfffe, 0x0032, 0xfff6, 0x000d, 0x0005, 0xffcc, 0x000d, 0x0087, 0xfff8, 0xfffd, 0xffed, 0x0025, 0xffda, 0x0069, 0xffdc }, 16, 0x000bf360, 1},
++	{{0xffdc, 0x0024, 0xffc4, 0x0007, 0x0009, 0xfffc, 0xfff7, 0x002d, 0xff7a, 0x0029, 0x0002, 0x0012, 0xffec, 0xfffc, 0xfff8, 0xffd9 }, 16, 0x000bf380, 1},
++	{{0x0063, 0xffd6, 0x0017, 0xffec, 0x0056, 0xffe5, 0x0007, 0x0003, 0xffca, 0x002e, 0xffc0, 0x0007, 0xffb5, 0xffff, 0x0037, 0xffc9 }, 16, 0x000bf3a0, 1},
++	{{0x0062, 0xffe8, 0x003c, 0x0016, 0xffcb, 0x0025, 0xffce, 0x003c, 0xffb0, 0x001b, 0xffce, 0x000b, 0x008b, 0xffdb, 0xfff1, 0xfff7 }, 16, 0x000bf3c0, 1},
++	{{0xffdc, 0x0038, 0xffbf, 0xfff4, 0xffdc, 0xfff0, 0x0029, 0xffdc, 0x0099, 0xffd7, 0x0076, 0xffcf, 0x0041, 0xffea, 0x000a, 0xffc7 }, 16, 0x000bf3e0, 1},
++	{{0xff46, 0x0045, 0xffe7, 0xffea, 0x004c, 0xfffb, 0x000e, 0x006e, 0x003d, 0x0080, 0xfed2, 0x0057, 0xff3d, 0x0097, 0xffb4, 0x0062 }, 16, 0x000bf400, 1},
++	{{0xff8e, 0x00d5, 0xff34, 0x0074, 0x019a, 0xfed4, 0x00e9, 0x003a, 0xfe16, 0xfe86, 0xfdf9, 0xfb2a, 0x0b7f, 0x00f9, 0xfe1d, 0x00c9 }, 16, 0x000bf420, 1},
++	{{0xfbc0, 0x07e8, 0xfe7e, 0xfe95, 0x0067, 0xf66c, 0x002c, 0xfdbd, 0x00df, 0x026f, 0x00ed, 0x01d1, 0xffa3, 0x02b6, 0xfff2, 0x01a5 }, 16, 0x000bf440, 1},
++	{{0x00f8, 0xfed9, 0xffde, 0x001b, 0x01cb, 0x00a7, 0x0045, 0xfe90, 0xfed2, 0xff58, 0xfefe, 0xff27, 0xfdb9, 0xfecd, 0xfde5, 0xffb0 }, 16, 0x000bf460, 1},
++	{{0x0115, 0x00c4, 0x01e0, 0x01bd, 0x012d, 0x00aa, 0x00ca, 0x00f3, 0x0038, 0xffaf, 0xff4a, 0xff07, 0xff4b, 0xffec, 0x00b3, 0xffbb }, 16, 0x000bf480, 1},
++	{{0xffe4, 0xffe9, 0xffbd, 0xfffc, 0xff74, 0xffaa, 0xff2e, 0xff63, 0x0008, 0x018d, 0xff5e, 0x00f6, 0x0042, 0x0055, 0x0013, 0x00da }, 16, 0x000bf4a0, 1},
++	{{0xff8f, 0xffe0, 0xffe7, 0xff78, 0x002e, 0xff66, 0x002f, 0xffa8, 0xffd2, 0x00b1, 0xffa8, 0x0051, 0xffe4, 0x0048, 0x000c, 0xffe6 }, 16, 0x000bf4c0, 1},
++	{{0x0002, 0xffd1, 0x009e, 0xffee, 0x0028, 0xffba, 0xffd7, 0x0052, 0xfff4, 0xff78, 0x001e, 0xff7a, 0x004a, 0xff12, 0x006d, 0x004e }, 16, 0x000bf4e0, 1},
++	{{0x005b, 0xffc9, 0xffd0, 0x0042, 0x0006, 0x008a, 0x0032, 0xffd3, 0x000e, 0x0075, 0x006e, 0xffd3, 0xffd1, 0xffc8, 0x0037, 0xffc6 }, 16, 0x000bf500, 1},
++	{{0x005a, 0xfec9, 0x0036, 0xff04, 0x007e, 0x0028, 0x0033, 0x0002, 0xff7f, 0x00e5, 0xff98, 0x0087, 0xffd8, 0x0029, 0x0012, 0xffa2 }, 16, 0x000bf520, 1},
++	{{0xff70, 0x017e, 0xff5c, 0x0048, 0x0041, 0xffc8, 0x0066, 0xff9a, 0x0038, 0xfec3, 0x0017, 0xff5e, 0xffe9, 0x0083, 0x0027, 0xffe6 }, 16, 0x000bf540, 1},
++	{{0x0006, 0x001b, 0x0006, 0x00c1, 0xff78, 0x0041, 0x0001, 0xffd0, 0x0000, 0x000e, 0x001a, 0x000e, 0x003a, 0x004e, 0xffc0, 0x0008 }, 16, 0x000bf560, 1},
++	{{0x005e, 0xfea4, 0x0074, 0xff9f, 0x0031, 0xff7d, 0xffee, 0x004e, 0x0007, 0x0066, 0xff59, 0x00ec, 0xffd3, 0x006c, 0xfff9, 0xff78 }, 16, 0x000bf580, 1},
++	{{0x0026, 0xffe3, 0x000f, 0x0062, 0x0000, 0xffc8, 0x002f, 0xffb0, 0x0058, 0xff81, 0xffb5, 0x003f, 0xffc3, 0x0029, 0xffed, 0x005f }, 16, 0x000bf5a0, 1},
++	{{0x000e, 0xffe0, 0xffc0, 0x0017, 0xffb2, 0x010c, 0xffac, 0x0076, 0xffb4, 0xffde, 0x006b, 0xff2e, 0x0063, 0xff8f, 0xffed, 0x005c }, 16, 0x000bf5c0, 1},
++	{{0xfffe, 0xff81, 0x0041, 0xff37, 0x008e, 0xffb3, 0xffd1, 0x011d, 0xffa2, 0xffed, 0xffd2, 0x0043, 0xffee, 0x00c2, 0xfff6, 0x0037 }, 16, 0x000bf5e0, 1},
++	{{0xffd9, 0x0082, 0x003e, 0x002c, 0xff99, 0x00a7, 0xfec8, 0x0174, 0xff13, 0xffa4, 0x0008, 0xff9e, 0x007a, 0xff92, 0x00d5, 0xffa8 }, 16, 0x000bf600, 1},
++	{{0x0156, 0xfefa, 0x0095, 0xffe3, 0x0030, 0xffcd, 0xff85, 0xff77, 0x002e, 0xfe46, 0xf637, 0x109f, 0xfadb, 0x05b4, 0xff8e, 0xfe8b }, 16, 0x000bf620, 1},
++	{{0xfff4, 0x01e7, 0xffac, 0xfc1a, 0xfdb6, 0xfcf7, 0xfe93, 0x0043, 0xff80, 0x0052, 0x01f5, 0xff5a, 0x00b0, 0x0269, 0x00d2, 0x0158 }, 16, 0x000bf640, 1},
++	{{0x0222, 0x010d, 0x0034, 0x00af, 0x01f2, 0x0076, 0xff77, 0xfe8f, 0xfe2d, 0xfdd8, 0xfeca, 0xfe0c, 0xfdb1, 0xfeec, 0xfda8, 0x00ce }, 16, 0x000bf660, 1},
++	{{0x0021, 0x010d, 0x022d, 0x0152, 0x0199, 0x01b7, 0x00d4, 0x00c1, 0x0089, 0xffff, 0x0049, 0xff76, 0xff54, 0x0070, 0xff28, 0x0068 }, 16, 0x000bf680, 1},
++	{{0xfe78, 0xff3a, 0x00dd, 0xfda3, 0x004d, 0xfecf, 0xffd2, 0x002c, 0xff3f, 0x0181, 0x0031, 0x013e, 0x002d, 0x00ca, 0xffd0, 0x00be }, 16, 0x000bf6a0, 1},
++	{{0xfec9, 0x01a9, 0xfeb7, 0x0022, 0xffc9, 0xff50, 0xffe4, 0xfff6, 0xffd1, 0x0031, 0xff21, 0x0038, 0x00b4, 0xff07, 0x013b, 0xfee8 }, 16, 0x000bf6c0, 1},
++	{{0x012a, 0xfffd, 0x003f, 0x00ac, 0xffa3, 0x0073, 0xffa6, 0xfffa, 0x0023, 0xff37, 0xfffd, 0xff92, 0xffcc, 0xff65, 0xfff7, 0x0000 }, 16, 0x000bf6e0, 1},
++	{{0x0034, 0xffac, 0x0038, 0xffa9, 0x006f, 0x00c4, 0x0053, 0xffc1, 0x005c, 0x0092, 0x0070, 0x009d, 0xff55, 0x00c6, 0xff76, 0xfff7 }, 16, 0x000bf700, 1},
++	{{0xfeed, 0x00b5, 0xfe16, 0x00c0, 0xfede, 0x00d9, 0xfed8, 0x00a0, 0xffb5, 0xfff4, 0x0091, 0xff30, 0x00f6, 0x0065, 0x001f, 0x0098 }, 16, 0x000bf720, 1},
++	{{0xff72, 0xff46, 0x010c, 0xff8d, 0x00a7, 0xff0e, 0x00a6, 0x00de, 0xfdaf, 0x0231, 0xfe17, 0x0149, 0xfecb, 0xffe9, 0x0033, 0xffc3 }, 16, 0x000bf740, 1},
++	{{0xffa3, 0xffe8, 0x0103, 0xfeea, 0x0153, 0xff00, 0x00bc, 0xff5b, 0x01a4, 0xfe5b, 0x0165, 0xfe61, 0x01de, 0xff3c, 0x0087, 0x0026 }, 16, 0x000bf760, 1},
++	{{0xff72, 0x009e, 0xfe76, 0x0182, 0xfe79, 0x00e1, 0xff48, 0xffc4, 0xffec, 0xfffb, 0xffe6, 0xffcc, 0x008f, 0x0057, 0xffa5, 0x0025 }, 16, 0x000bf780, 1},
++	{{0x00ca, 0xff2d, 0x0135, 0xff33, 0x00e3, 0x0036, 0xff95, 0x0057, 0xfee2, 0x00cd, 0xfe12, 0x01d4, 0xfe71, 0xfffe, 0x00d7, 0xff53 }, 16, 0x000bf7a0, 1},
++	{{0x0114, 0xffac, 0xff8d, 0x004e, 0xffa3, 0xff16, 0x01e4, 0xff24, 0x0082, 0xffb7, 0x0083, 0xff8b, 0x00e2, 0xffc8, 0xfec7, 0x017c }, 16, 0x000bf7c0, 1},
++	{{0xfe10, 0x011f, 0xfe2b, 0x0070, 0x00c0, 0xffbf, 0xff42, 0x01f5, 0xfeb9, 0xff95, 0x0195, 0xfe88, 0x02f9, 0xfe40, 0x0080, 0xffd0 }, 16, 0x000bf7e0, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20c0, 0x800a, 0xeee8, 0x32a4, 0x34b0, 0x800b, 0xefe8, 0x98c0, 0x09c6 }, 16, 0x000c3000, 1},
++	{{0x2100, 0x8009, 0xeae8, 0x96c0, 0xe8ee, 0x2f0b, 0x8080, 0x98c0, 0xca4e, 0x3244, 0x3eb0, 0x800a, 0x96c0, 0x5f93, 0x2909, 0x80a8 }, 16, 0x000c3020, 1},
++	{{0x96c0, 0x6c90, 0xee44, 0xca46, 0x4196, 0x98c0, 0x09c6, 0x2100, 0x8009, 0xe8ea, 0x32a4, 0x32d0, 0x800b, 0xe948, 0x94c0, 0x6f90 }, 16, 0x000c3040, 1},
++	{{0x9770, 0x3b80, 0x2462, 0x8009, 0x3980, 0x2460, 0x8009, 0x2b02, 0x8002, 0x90c0, 0x94c8, 0x4739, 0x473b, 0x94c0, 0xc683, 0x90c0 }, 16, 0x000c3060, 1},
++	{{0x3457, 0x0cc6, 0x2100, 0x8009, 0x3264, 0x3890, 0x800a, 0x2c09, 0x8038, 0x3457, 0x08c6, 0x2100, 0x8009, 0x3264, 0x3c90, 0x800a }, 16, 0x000c3080, 1},
++	{{0x2809, 0x8044, 0x3224, 0x3ef0, 0x800c, 0x7457, 0x3457, 0x0ec6, 0x2100, 0x8009, 0x3264, 0x3400, 0x800a, 0x2e09, 0x8030, 0x3457 }, 16, 0x000c30a0, 1},
++	{{0x0dc6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2d09, 0x80dc, 0x3b61, 0x7bc1, 0x676a, 0x81ab, 0x3224, 0x3ef0, 0x800c, 0xc083 }, 16, 0x000c30c0, 1},
++	{{0x98c0, 0x0ac6, 0x2100, 0x8009, 0xc083, 0x3264, 0x3400, 0x800a, 0x2a09, 0x8028, 0x98c0, 0x0cc6, 0x38d0, 0x8008, 0xe8ef, 0x32c4 }, 16, 0x000c30e0, 1},
++	{{0x3c20, 0x800a, 0x2c09, 0x8200, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000c3100, 1},
++	{{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xefe9, 0x270a, 0x80d8, 0xe7ea, 0x94c0, 0xfdfd, 0xfafe, 0x98c0, 0xf847 }, 16, 0x000c3120, 1},
++	{{0x32c4, 0x20c0, 0x800a, 0x1615, 0x5712, 0x96c0, 0x5c90, 0x280e, 0x8024, 0x3820, 0xa000, 0x5896, 0x2e0b, 0x805c, 0x3660, 0xa000 }, 16, 0x000c3140, 1},
++	{{0x5993, 0xf849, 0x32a4, 0x34b0, 0x800b, 0x3640, 0xa000, 0xfc48, 0xf94a, 0x98c0, 0x0d26, 0x3534, 0x8009, 0xfcc8, 0x98c0, 0x0bc6 }, 16, 0x000c3160, 1},
++	{{0x2100, 0x8009, 0xeae8, 0x94c0, 0xed41, 0xff41, 0x98c0, 0x0d22, 0x3534, 0x8009, 0xf9c7, 0x96c0, 0xfa4b, 0x2b0b, 0x80d4, 0x11db }, 16, 0x000c3180, 1},
++	{{0xe8ec, 0x54d3, 0xda94, 0x98c0, 0xde99, 0x3264, 0x2420, 0x800a, 0x4594, 0x94c0, 0xfcc8, 0xf9ff, 0xf94c, 0x3800, 0xa100, 0x5011 }, 16, 0x000c31a0, 1},
++	{{0x2c0e, 0x82be, 0x3264, 0x2120, 0x800a, 0x36c0, 0xa000, 0x5116, 0xfe4d, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0x90c0, 0x3600, 0xa100 }, 16, 0x000c31c0, 1},
++	{{0x5194, 0x4016, 0x9ac0, 0x331c, 0x8002, 0x90c0, 0x331a, 0x8001, 0x6669, 0x2718, 0x8cca, 0x96c0, 0x6569, 0x330b, 0x8200, 0x8013 }, 16, 0x000c31e0, 1},
++	{{0x3364, 0x2480, 0x800a, 0x98c0, 0xfcc8, 0x3124, 0x3ebc, 0x800c, 0x3ca0, 0xa000, 0x6e10, 0x2502, 0x82ba, 0x65e9, 0xeaee, 0x9ac0 }, 16, 0x000c3200, 1},
++	{{0x2302, 0x8296, 0x90c0, 0x2718, 0x881c, 0x3820, 0xa000, 0xe8ee, 0x2b00, 0x828e, 0x3660, 0xa000, 0xe83b, 0xeeee, 0x9ac0, 0x2d00 }, 16, 0x000c3220, 1},
++	{{0x824c, 0x90c0, 0x2302, 0x8210, 0x3640, 0xa100, 0xee3b, 0xea3d, 0x3820, 0xa000, 0xebee, 0x2900, 0x827e, 0x96c0, 0xeb3d, 0x2f00 }, 16, 0x000c3240, 1},
++	{{0x8216, 0x96c0, 0xfb51, 0x2502, 0x8212, 0x3660, 0xa000, 0xedee, 0xebee, 0x9ac0, 0x2702, 0x8226, 0x90c0, 0x2402, 0x8222, 0x94c0 }, 16, 0x000c3260, 1},
++	{{0xeb39, 0xed3f, 0x3660, 0xa000, 0xe9ee, 0xefee, 0x36c0, 0xa000, 0x5192, 0xe93f, 0x3820, 0xa000, 0xef3c, 0x25a0, 0x9fdf, 0x38e0 }, 16, 0x000c3280, 1},
++	{{0xa100, 0xde81, 0xecee, 0xefee, 0x36e0, 0xa100, 0xec3b, 0xef3d, 0x3620, 0xa100, 0xfa52, 0x4592, 0x94c0, 0xf84e, 0xfe4f, 0x94c0 }, 16, 0x000c32a0, 1},
++	{{0xc383, 0xf850, 0x94c0, 0xfd53, 0xfb54, 0x36c0, 0xa000, 0xeae9, 0xfc55, 0x3420, 0xa000, 0xff56, 0x96c0, 0x7454, 0xf9d0, 0xf457 }, 16, 0x000c32c0, 1},
++	{{0x3264, 0x3240, 0x800a, 0x3640, 0xa000, 0xf358, 0xfa59, 0x94c0, 0xfcd6, 0xf8c8, 0x94c0, 0xf4d7, 0xf9d0, 0x4014, 0x5090, 0x310d }, 16, 0x000c32e0, 1},
++	{{0x8008, 0x66e9, 0x94c0, 0xfbd5, 0x8051, 0x9ac0, 0xd222, 0x32f8, 0x3fff, 0xbff7, 0xc5f7, 0x94c0, 0xdd00, 0x841b, 0x4290, 0x0dc6 }, 16, 0x000c3300, 1},
++	{{0x2100, 0x8009, 0x90c0, 0x2d0b, 0x80d6, 0x51d3, 0xde81, 0x4513, 0x3454, 0x0cc6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2c09 }, 16, 0x000c3320, 1},
++	{{0x80dc, 0x3a20, 0xa000, 0xfad9, 0x3024, 0x33f8, 0x800c, 0x94c0, 0xf4d7, 0xf3d8, 0x90c0, 0x1113, 0x3264, 0x2140, 0x800a, 0xf15a }, 16, 0x000c3340, 1},
++	{{0x98c0, 0x6469, 0x6e90, 0xfbcf, 0xfcd5, 0x94c0, 0xf1da, 0xf4d7, 0x96c3, 0x5093, 0x22a0, 0x9fff, 0x3a47, 0xa000, 0x90c0, 0xfad9 }, 16, 0x000c3360, 1},
++	{{0x0900, 0xa020, 0x98c7, 0x7454, 0x4093, 0x90c0, 0xdd00, 0x92c3, 0x4293, 0x5214, 0x96c0, 0x7161, 0x2200, 0x8200, 0x94c0, 0xfdd4 }, 16, 0x000c3380, 1},
++	{{0x8037, 0x3680, 0xa000, 0x4592, 0xf8d3, 0x4597, 0x4595, 0x4290, 0x0bc6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2b09, 0x80dc }, 16, 0x000c33a0, 1},
++	{{0x3a20, 0xa000, 0xfad9, 0x3024, 0x33f8, 0x800c, 0x94c0, 0xf4d7, 0xf3d8, 0x96c0, 0x7454, 0xf9d1, 0xfcd6, 0xfdcc, 0x1211, 0x5514 }, 16, 0x000c33c0, 1},
++	{{0x1115, 0xf502, 0x3264, 0x3160, 0x800a, 0xf201, 0x94c0, 0xf4d7, 0xf3d8, 0x3420, 0xa000, 0xfad9, 0x98c0, 0x79e1, 0x7a41, 0xf9d0 }, 16, 0x000c33e0, 1},
++	{{0xfbcf, 0x96c0, 0x65ea, 0xfdd5, 0xfcd6, 0x1111, 0xf9d1, 0x98c0, 0x3e51, 0x8020, 0x5293, 0xfbd2, 0x9ac0, 0x2d0d, 0x808c, 0xdc82 }, 16, 0x000c3400, 1},
++	{{0x2909, 0x808c, 0x1593, 0xf8d3, 0x98c0, 0xdc9d, 0xfbcf, 0x2c0c, 0x808c, 0x94c0, 0xfd55, 0xfdd4, 0x94c0, 0xf951, 0xf9d0, 0x94c0 }, 16, 0x000c3420, 1},
++	{{0xfc56, 0xfcd2, 0x9ac0, 0x2808, 0x808c, 0x90c0, 0x2d0d, 0x808c, 0x9ac0, 0x2b0b, 0x808c, 0x90c0, 0x2909, 0x808c, 0x96c0, 0xfb4f }, 16, 0x000c3440, 1},
++	{{0x2f0f, 0x808c, 0x3840, 0xa100, 0x4194, 0x2a0a, 0x808c, 0x96c0, 0xf950, 0x2cff, 0x9e6b, 0x94c0, 0xfd54, 0xf853, 0x3820, 0xa000 }, 16, 0x000c3460, 1},
++	{{0xfecd, 0x2402, 0x8052, 0x9ac0, 0x2f00, 0x804e, 0x90c0, 0x2d00, 0x8050, 0x38a0, 0xa000, 0xefee, 0x2900, 0x8044, 0x36e0, 0xa000 }, 16, 0x000c3480, 1},
++	{{0xef3c, 0xe8ee, 0x36c0, 0xa100, 0x5217, 0xefee, 0x3880, 0xa000, 0xef3f, 0x2302, 0x8134, 0x3640, 0xa000, 0xe83d, 0xefee, 0x3820 }, 16, 0x000c34a0, 1},
++	{{0xa000, 0xf9ca, 0x2d00, 0x824c, 0x36a0, 0xa000, 0xedee, 0xef39, 0x36e0, 0xa000, 0xed3b, 0xe9ee, 0x9ac0, 0x2402, 0x81c0, 0x90c0 }, 16, 0x000c34c0, 1},
++	{{0x2b00, 0x8040, 0x3600, 0xa100, 0xe93d, 0x4715, 0x3660, 0xa100, 0xedee, 0xedee, 0x1310, 0xed3b, 0x36e0, 0xa000, 0xed3c, 0xe8e9 }, 16, 0x000c34e0, 1},
++	{{0x0217, 0x4311, 0x3680, 0xa000, 0x4217, 0x4315, 0x36c0, 0xa000, 0x4615, 0xff5b, 0x32c4, 0x3dd0, 0x800a, 0xf95c, 0x3a40, 0xa000 }, 16, 0x000c3500, 1},
++	{{0x6d90, 0xfecd, 0x2502, 0x82b2, 0x9ac0, 0x2302, 0x8286, 0x90c0, 0x2402, 0x8276, 0x3660, 0xa000, 0xedee, 0xebee, 0x3820, 0xa000 }, 16, 0x000c3520, 1},
++	{{0xed3d, 0x2800, 0x822c, 0x3640, 0xa000, 0xfd5f, 0xeb3c, 0x3660, 0xa000, 0xedee, 0xfad2, 0x3660, 0xa100, 0xed3b, 0xecee, 0x3880 }, 16, 0x000c3540, 1},
++	{{0xa000, 0xec38, 0x2302, 0x8284, 0x3a00, 0xa100, 0x31f8, 0x3ffd, 0xbff7, 0x5292, 0x3840, 0xa000, 0xdc82, 0xe8ee, 0xfb60, 0x96c0 }, 16, 0x000c3560, 1},
++	{{0xf00c, 0x2b00, 0x8282, 0x94c0, 0xf05d, 0xc083, 0x38e0, 0xa004, 0x7450, 0xe83b, 0xedee, 0x3680, 0xa100, 0x4192, 0xed3b, 0x94c0 }, 16, 0x000c3580, 1},
++	{{0xfe5e, 0xfd61, 0xf862, 0x98c0, 0xf8df, 0x3d20, 0x3538, 0x8009, 0x94c0, 0xf9dc, 0xc28e, 0x1110, 0xf363, 0x3e40, 0xa000, 0x331d }, 16, 0x000c35a0, 1},
++	{{0x8003, 0x5011, 0x331c, 0x801c, 0xf064, 0x3a60, 0xa000, 0x7ec1, 0x7e62, 0xfc65, 0xfd66, 0x2ea8, 0xcb45, 0x90c0, 0xeb1d, 0x5213 }, 16, 0x000c35c0, 1},
++	{{0x2832, 0x3264, 0x2400, 0x800a, 0xd41d, 0x94c0, 0xf8e2, 0xf9dc, 0x3264, 0x2120, 0x800a, 0x1110, 0x4011, 0x3840, 0xa000, 0x7650 }, 16, 0x000c35e0, 1},
++	{{0xfde6, 0xfde1, 0xf8e2, 0x3600, 0xa100, 0x5015, 0x5115, 0x3264, 0x2120, 0x800a, 0x4410, 0x3a20, 0xa004, 0x7550, 0x6e90, 0xfce5 }, 16, 0x000c3600, 1},
++	{{0xfbe0, 0x3640, 0xa000, 0xf9de, 0xfde6, 0x3680, 0xa000, 0x5114, 0x5293, 0x1491, 0xf3e3, 0x3840, 0xa000, 0x7453, 0xc682, 0xf444 }, 16, 0x000c3620, 1},
++	{{0x36e0, 0xa000, 0x4215, 0xf645, 0x96c0, 0xf242, 0x057c, 0x9ff7, 0x3264, 0x3750, 0x800a, 0xf101, 0x98c0, 0xf3e3, 0x3224, 0x3f40 }, 16, 0x000c3640, 1},
++	{{0x800c, 0x7453, 0x94c0, 0xf9dc, 0xf8e2, 0x3640, 0xa000, 0xfde1, 0xfde6, 0x9ac0, 0x2808, 0x808c, 0x90c0, 0x2909, 0x808c, 0x94c0 }, 16, 0x000c3660, 1},
++	{{0xf862, 0xf8e0, 0x3620, 0xa000, 0xf0e4, 0xf95c, 0x3820, 0xa004, 0x7861, 0xf9de, 0xfce5, 0x3c00, 0xa001, 0x2d0d, 0x808c, 0x646a }, 16, 0x000c3680, 1},
++	{{0x2808, 0x808c, 0x96c0, 0xf3e3, 0x2909, 0x808c, 0x3aa0, 0xa000, 0x79c1, 0xfd61, 0x2c0c, 0x808c, 0x96c0, 0xf95e, 0x2cff, 0x9eef }, 16, 0x000c36a0, 1},
++	{{0x3840, 0xa100, 0xf860, 0x2d0d, 0x808c, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0x3820, 0xa000, 0xffdb, 0x2900, 0x82ac, 0x3640, 0xa000 }, 16, 0x000c36c0, 1},
++	{{0x5394, 0xe8ee, 0x3c20, 0xa000, 0x3718, 0x8200, 0xebee, 0x2d00, 0x8056, 0x3880, 0xa000, 0x6469, 0xe839, 0x5117, 0x94c0, 0x5010 }, 16, 0x000c36e0, 1},
++	{{0x8427, 0x96c0, 0x3118, 0x80ff, 0xeb3d, 0x3264, 0x2350, 0x800a, 0xfb41, 0x3660, 0xa000, 0xffdb, 0xfecd, 0x90c0, 0x3480, 0xa000 }, 16, 0x000c3700, 1},
++	{{0x4017, 0x96c0, 0xc9b2, 0x2d00, 0x82b6, 0x3660, 0xa000, 0xebee, 0xe8ee, 0x94c0, 0xeb3d, 0xe839, 0x3680, 0xa000, 0x5317, 0x5490 }, 16, 0x000c3720, 1},
++	{{0x1293, 0xc582, 0x94c0, 0xc181, 0xf545, 0x96c0, 0xf244, 0x017c, 0x9ff7, 0x94c0, 0xf442, 0xf301, 0x94c0, 0xe9eb, 0xc083, 0x3264 }, 16, 0x000c3740, 1},
++	{{0x3750, 0x800a, 0xfb67, 0x3640, 0xa000, 0xfbe7, 0xfad2, 0x3660, 0xa000, 0xfecd, 0xffdb, 0x3600, 0xa100, 0x5393, 0x5592, 0x3a60 }, 16, 0x000c3760, 1},
++	{{0xa000, 0x3708, 0x8004, 0xccb6, 0xedee, 0x9ac0, 0xdc1d, 0x6e90, 0xfcc8, 0x2900, 0x82a6, 0x36c0, 0xa000, 0x4092, 0xed3c, 0x36c0 }, 16, 0x000c3780, 1},
++	{{0xa000, 0x5317, 0xf8c9, 0x3640, 0xa000, 0x4315, 0xe8ee, 0x1194, 0xe839, 0x98c0, 0x331a, 0x8080, 0x5010, 0xfacb, 0x3e40, 0xa000 }, 16, 0x000c37a0, 1},
++	{{0x7640, 0x2809, 0x85b4, 0x6569, 0x2160, 0x9fff, 0x8015, 0x4410, 0x5217, 0x69a8, 0x7def, 0x0317, 0x3024, 0x38ac, 0x800c, 0x4511 }, 16, 0x000c37c0, 1},
++	{{0x96c0, 0x7c41, 0xf868, 0xf969, 0x3284, 0x2100, 0x800a, 0x7841, 0x3820, 0xa000, 0x74d0, 0xf8e8, 0xffdb, 0xc083, 0x4110, 0x3480 }, 16, 0x000c37e0, 1},
++	{{0xa000, 0x5417, 0x6a24, 0x3e6f, 0x3224, 0x3f40, 0x800c, 0x4417, 0x94c0, 0xfcc8, 0xf9e9, 0x1217, 0x3264, 0x20b0, 0x800a, 0x0211 }, 16, 0x000c3800, 1},
++	{{0xe8ec, 0x3820, 0xa000, 0xfecd, 0x2900, 0x8062, 0x3860, 0x22f4, 0x8009, 0x3660, 0xa100, 0xedee, 0xefee, 0x3600, 0xa100, 0xed39 }, 16, 0x000c3820, 1},
++	{{0xef66, 0x0015, 0x3244, 0x3310, 0x800b, 0x3480, 0xa000, 0x5117, 0x3620, 0xa000, 0xf9ca, 0xfcc8, 0x3640, 0xa000, 0xfacb, 0xfad2 }, 16, 0x000c3840, 1},
++	{{0x3680, 0xa000, 0x51d1, 0xfbe7, 0x3820, 0xa000, 0x331c, 0x8001, 0xc2ef, 0x2669, 0x09c6, 0x2100, 0x8009, 0x94c0, 0xf4dd, 0x8025 }, 16, 0x000c3860, 1},
++	{{0x4417, 0x5293, 0x3400, 0xa004, 0xdd02, 0x3420, 0xa000, 0x4293, 0x5194, 0x0901, 0xb000, 0x0194, 0x3124, 0x38ac, 0x800c, 0x2909 }, 16, 0x000c3880, 1},
++	{{0x80d4, 0x52d9, 0x55d1, 0xda95, 0xde9a, 0x4594, 0x3600, 0xa100, 0x5293, 0x5392, 0x96c0, 0x351c, 0x8010, 0xe8ea, 0x6669, 0x90c0 }, 16, 0x000c38a0, 1},
++	{{0x94c1, 0xc190, 0xc1ef, 0x94c1, 0xdc9b, 0xdc83, 0x3480, 0xa000, 0x4192, 0x5517, 0x7ec8, 0x66e5, 0x7ec8, 0x36dd, 0x32a4, 0x3360 }, 16, 0x000c38c0, 1},
++	{{0x800b, 0xd89d, 0x3a60, 0xa000, 0x7c48, 0x6e10, 0xfecd, 0xfad2, 0x3e00, 0xa002, 0x6465, 0x2702, 0x8042, 0x7654, 0x2800, 0x8212 }, 16, 0x000c38e0, 1},
++	{{0x3860, 0xa000, 0x7c48, 0xeaee, 0xedee, 0x3c40, 0xa000, 0x7458, 0xea3f, 0x3298, 0x23df, 0xbfcd, 0x96c0, 0x4052, 0x2702, 0x822a }, 16, 0x000c3900, 1},
++	{{0x0057, 0xed38, 0x36c0, 0xa000, 0x5592, 0xe9ee, 0x3820, 0xa000, 0xdd05, 0xc383, 0xe93f, 0x3680, 0xa000, 0x4292, 0xfe6a, 0x98c0 }, 16, 0x000c3920, 1},
++	{{0x3422, 0x3554, 0x8009, 0xff6b, 0x96c0, 0xfd6c, 0x90c0, 0x90c0, 0x3800, 0xa800, 0x74d4, 0xfaec, 0xfdcc, 0x94c0, 0xf8c8, 0xf36d }, 16, 0x000c3940, 1},
++	{{0x3640, 0xa000, 0x5012, 0xfc6e, 0x0011, 0xf96f, 0x3600, 0xa100, 0x5515, 0xcf44, 0x3264, 0x2870, 0x800a, 0xf501, 0x3600, 0xa100 }, 16, 0x000c3960, 1},
++	{{0xfeeb, 0xcf4c, 0x3a00, 0xa800, 0x7454, 0x3264, 0x3d70, 0x800a, 0x5116, 0x3620, 0xa000, 0xfcee, 0xf8ce, 0x3264, 0x22a0, 0x800a }, 16, 0x000c3980, 1},
++	{{0x3480, 0xa000, 0x4014, 0x3264, 0x21c0, 0x800a, 0xf8ce, 0x98c0, 0xf8ce, 0x3460, 0x3c20, 0x8032, 0x3680, 0xa000, 0xcf4c, 0xffd2 }, 16, 0x000c39a0, 1},
++	{{0x3800, 0xa004, 0x7a41, 0x5010, 0xf8ea, 0x9cc0, 0x3485, 0x8000, 0xfaec, 0x3682, 0x8000, 0xf3ed, 0x9cc0, 0x79e1, 0x3085, 0x8000 }, 16, 0x000c39c0, 1},
++	{{0x5190, 0x2808, 0x808c, 0x98c0, 0xda15, 0x65ea, 0xf86a, 0xf8ce, 0x3820, 0xa000, 0xd642, 0xf9ef, 0xfcee, 0x3a40, 0xa000, 0xde01 }, 16, 0x000c39e0, 1},
++	{{0x5397, 0x2a0a, 0x808c, 0x3a00, 0xa200, 0x2808, 0x808c, 0xde1b, 0xecef, 0x0494, 0xf84e, 0x96c0, 0x813a, 0x2909, 0x808c, 0x3680 }, 16, 0x000c3a00, 1},
++	{{0xa000, 0xec54, 0xfa6c, 0x3a40, 0xa000, 0x3938, 0x8000, 0xfbe7, 0xfecd, 0x90c0, 0x5193, 0xdc19, 0x4093, 0x3a40, 0xa000, 0x2a00 }, 16, 0x000c3a20, 1},
++	{{0x82ba, 0x6e90, 0xebee, 0x38a0, 0xa000, 0xeaee, 0x2e00, 0x8296, 0x98c0, 0xeb3a, 0x34f8, 0x3fbf, 0xb7bf, 0x96c0, 0x5093, 0x2702 }, 16, 0x000c3a40, 1},
++	{{0x828a, 0x9ac0, 0x2900, 0x828e, 0xde00, 0x2800, 0x8286, 0x3a80, 0xa000, 0xea3e, 0x3180, 0x2000, 0x8001, 0x3860, 0xa000, 0xdc9c }, 16, 0x000c3a60, 1},
++	{{0xeeee, 0xeaee, 0x3620, 0xa000, 0xefee, 0x4193, 0x3620, 0xa000, 0xedea, 0xef39, 0x3640, 0xa000, 0xc483, 0xee3f, 0x3640, 0xa000 }, 16, 0x000c3a80, 1},
++	{{0xea38, 0xfa70, 0x3455, 0x1216, 0xfb71, 0x0212, 0xf572, 0x94c0, 0xf473, 0xfd74, 0x3264, 0x3910, 0x800a, 0xfa75, 0x94c0, 0xfdf4 }, 16, 0x000c3aa0, 1},
++	{{0xfbf1, 0x94c0, 0xf5f2, 0xf4f3, 0x1315, 0xfaf5, 0x25e9, 0x1397, 0x3000, 0x2040, 0x8840, 0x94c0, 0xdc03, 0x801b, 0x1393, 0x3278 }, 16, 0x000c3ac0, 1},
++	{{0x3fff, 0xbffe, 0xdc1b, 0x4093, 0x5197, 0xdd19, 0xdd00, 0x4293, 0x9ac0, 0x7a61, 0x7ac1, 0xf8c8, 0x2f0f, 0x808c, 0x2d0d, 0x808c }, 16, 0x000c3ae0, 1},
++	{{0x5090, 0x3108, 0x8400, 0x6469, 0x90c0, 0x98c6, 0x2e0e, 0x808c, 0x90c0, 0x5116, 0x94c6, 0x666a, 0x4112, 0x96c0, 0x818b, 0x2a0a }, 16, 0x000c3b00, 1},
++	{{0x808c, 0x3640, 0xa000, 0x5293, 0xfecd, 0x3c20, 0xa000, 0x359c, 0x8000, 0xfaf0, 0x2e00, 0x82b6, 0x3a40, 0xa000, 0x6669, 0xe9ee }, 16, 0x000c3b20, 1},
++	{{0x2a00, 0x8040, 0x96c0, 0xe93e, 0x2f00, 0x820a, 0x98c7, 0x5391, 0x3581, 0x2000, 0x8000, 0x98c1, 0xde9b, 0x3578, 0x3fff, 0xbfff }, 16, 0x000c3b40, 1},
++	{{0x3646, 0xa000, 0xde83, 0xeeee, 0x0591, 0xee3a, 0x3ac0, 0xa000, 0x5312, 0x0ac6, 0x38d0, 0x8008, 0x3820, 0xa000, 0xeaee, 0x2900 }, 16, 0x000c3b60, 1},
++	{{0x817e, 0x3680, 0xa000, 0xea48, 0xea3f, 0x36c0, 0xa000, 0x5112, 0xefee, 0x98c0, 0x331d, 0x8001, 0xef39, 0xece8, 0x3640, 0xa000 }, 16, 0x000c3b80, 1},
++	{{0x66e9, 0xf8c9, 0x3646, 0xa000, 0x6d10, 0x995e, 0x94c3, 0x2202, 0x8286, 0x90c0, 0x3423, 0xa000, 0xe93a, 0x92c3, 0x5211, 0x693d }, 16, 0x000c3ba0, 1},
++	{{0x0216, 0xda92, 0x26e1, 0x1312, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea48, 0x5112, 0x331c, 0x8002, 0x6669, 0x3646, 0xa100, 0x6d10 }, 16, 0x000c3bc0, 1},
++	{{0x9a5e, 0x94c3, 0x2a00, 0x81fa, 0x90c0, 0x3483, 0xa000, 0xea3a, 0x3483, 0xa000, 0x5212, 0x69bd, 0x7473, 0xd890, 0x6dc5, 0x4356 }, 16, 0x000c3be0, 1},
++	{{0x1117, 0x0ac6, 0x38d0, 0x8008, 0x3620, 0xa000, 0x280f, 0x85b6, 0xea48, 0x5212, 0x3518, 0x8004, 0x6469, 0x3646, 0xa100, 0x6e90 }, 16, 0x000c3c00, 1},
++	{{0x9a5e, 0x94c3, 0x2a00, 0x816e, 0x90c0, 0x3483, 0xa000, 0xea3a, 0x3483, 0xa000, 0x5512, 0x6a25, 0xd914, 0x6561, 0x6ddd, 0x4356 }, 16, 0x000c3c20, 1},
++	{{0x5294, 0x9ac0, 0x351d, 0x8020, 0x90c0, 0x350c, 0x8200, 0x66e9, 0x84c3, 0x3ca0, 0xa000, 0x6669, 0x2a00, 0x8050, 0x74d6, 0xeaee }, 16, 0x000c3c40, 1},
++	{{0x96c0, 0x8047, 0x2702, 0x8052, 0x36c0, 0xa000, 0xea3a, 0xe9ee, 0x3680, 0xa000, 0x5612, 0xeaef, 0x3640, 0xa000, 0x4617, 0xe93f }, 16, 0x000c3c60, 1},
++	{{0x1511, 0xea62, 0x0512, 0xf701, 0x32a4, 0x2c10, 0x800a, 0x3420, 0xa000, 0xe8e8, 0x98c0, 0xfbf1, 0x3024, 0x3cf2, 0x800c, 0x3640 }, 16, 0x000c3c80, 1},
++	{{0xa000, 0xfcc8, 0xfecd, 0x38a0, 0xa000, 0xeaee, 0x2a00, 0x8286, 0x9ac0, 0x2702, 0x816e, 0x90c0, 0x2900, 0x81fa, 0x36c0, 0xa000 }, 16, 0x000c3ca0, 1},
++	{{0xea3a, 0xedee, 0x36c0, 0xa000, 0x5712, 0xeaee, 0x3640, 0xa000, 0x4717, 0xea3f, 0x1012, 0xed39, 0x3620, 0xa000, 0xe8e8, 0xf001 }, 16, 0x000c3cc0, 1},
++	{{0x32a4, 0x2c10, 0x800a, 0x5115, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0xfbf1, 0x90c0, 0x1194, 0xef42, 0x96c0, 0x331f, 0x8020, 0x5617 }, 16, 0x000c3ce0, 1},
++	{{0x67e9, 0x8411, 0x4616, 0x5394, 0x370e, 0x8200, 0x6769, 0x2718, 0x81ae, 0x5494, 0x391f, 0x8010, 0x96c0, 0x67e9, 0x390f, 0x8020 }, 16, 0x000c3d00, 1},
++	{{0x842d, 0x96c0, 0x67e9, 0x390a, 0x8040, 0x8423, 0x96c0, 0x6569, 0x391c, 0x8020, 0x8019, 0x2669, 0x5293, 0x96c0, 0x350c, 0x8001 }, 16, 0x000c3d20, 1},
++	{{0x8013, 0x6669, 0x92c3, 0x6e90, 0x92c3, 0x4516, 0x5694, 0x9ac0, 0x3d2d, 0x8000, 0x90c0, 0x3d0c, 0x8800, 0x66e9, 0x841d, 0x2669 }, 16, 0x000c3d40, 1},
++	{{0x5293, 0x96c0, 0x355b, 0x8000, 0x8027, 0x96c0, 0x65e9, 0x351e, 0x8020, 0x8417, 0x6769, 0x8413, 0x3244, 0x3dd0, 0x800a, 0xe8ec }, 16, 0x000c3d60, 1},
++	{{0x3420, 0xa000, 0xfecd, 0x90c0, 0x38a0, 0xa000, 0xeaee, 0x2a00, 0x82b2, 0x3860, 0x27e0, 0x8009, 0x3a80, 0xa000, 0xea3a, 0x3244 }, 16, 0x000c3d80, 1},
++	{{0x3390, 0x800b, 0x3480, 0xa000, 0x5112, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0x3820, 0xa000, 0xf9ca, 0x2a00, 0x82a4, 0x3640, 0xa000 }, 16, 0x000c3da0, 1},
++	{{0x5194, 0xefee, 0x96c0, 0x331c, 0x8100, 0xef3a, 0x2669, 0x5017, 0x96c7, 0x7c41, 0x74c0, 0x8422, 0x94c7, 0x7841, 0x4117, 0x3284 }, 16, 0x000c3dc0, 1},
++	{{0x2100, 0x800a, 0x2160, 0x9fff, 0x3660, 0xa000, 0xf9ca, 0xfecd, 0x4017, 0x1117, 0x5516, 0x3640, 0xa000, 0x6a25, 0xeaee, 0x3e6f }, 16, 0x000c3de0, 1},
++	{{0xea62, 0x0416, 0xca4e, 0x3480, 0xa000, 0x57d1, 0x3f18, 0x8002, 0x6469, 0x90c0, 0x92c3, 0xf48c, 0x98c7, 0x3264, 0x2120, 0x800a }, 16, 0x000c3e00, 1},
++	{{0x4416, 0x1016, 0x5112, 0x3620, 0xa000, 0xfecd, 0xca46, 0x3420, 0xa000, 0xcab6, 0x36e0, 0xa000, 0xe8ee, 0xefee, 0x3640, 0xa100 }, 16, 0x000c3e20, 1},
++	{{0x4012, 0xe83a, 0x3600, 0xa100, 0xef64, 0x5010, 0x3264, 0x2120, 0x800a, 0x5117, 0x3820, 0xa000, 0xfecd, 0x2a00, 0x8216, 0x96c0 }, 16, 0x000c3e40, 1},
++	{{0x4017, 0x2102, 0x8226, 0x3620, 0xa000, 0xeeee, 0xc783, 0x98c0, 0x3f20, 0x355a, 0x8009, 0xee3a, 0x36a0, 0xa000, 0xee39, 0x90c0 }, 16, 0x000c3e60, 1},
++	{{0x3680, 0xa000, 0x5496, 0x5096, 0x3820, 0xa100, 0x6c7c, 0x5196, 0xfe4d, 0x3264, 0x33a0, 0x800a, 0x3454, 0x4496, 0x3840, 0xa000 }, 16, 0x000c3e80, 1},
++	{{0x7be1, 0xfecd, 0x4017, 0x27ea, 0xef54, 0x81d6, 0x3ca0, 0xa000, 0x2e0e, 0x808c, 0x90c0, 0x2e0e, 0x808c, 0xfcc8, 0x3264, 0x2760 }, 16, 0x000c3ea0, 1},
++	{{0x800a, 0xe8ec, 0x96c0, 0xfcc8, 0x16f8, 0x9f00, 0x94c0, 0xf9cc, 0xf641, 0x3264, 0x2440, 0x800a, 0xe8ec, 0x27ec, 0x9f28, 0xe7ec }, 16, 0x000c3ec0, 1},
++	{{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x98c0, 0x6c90, 0x7750, 0x9620, 0x9720, 0x98c0, 0x3721, 0x3694 }, 16, 0x000c3ee0, 1},
++	{{0x8009, 0xc49c, 0x2b80, 0xe748, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf441, 0xc847, 0x33c4, 0x20c0, 0x800a, 0x94c0, 0xd722, 0xcb47 }, 16, 0x000c3f00, 1},
++	{{0x90c0, 0x9ac7, 0x2b0a, 0x8018, 0x90c0, 0x2400, 0x9000, 0x94c7, 0x4892, 0x4493, 0xe768, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000c3f20, 1},
++	{{0x96c0, 0xd422, 0xcd57, 0xc79c, 0x3a20, 0xa000, 0x3421, 0x3694, 0x8009, 0xcc56, 0x3880, 0xa104, 0x6a03, 0xe9ef, 0xe8ee, 0x3a07 }, 16, 0x000c3f40, 1},
++	{{0xa100, 0x90c0, 0xc844, 0x3e10, 0x808c, 0x94c3, 0xcb40, 0xcc40, 0x9ac6, 0x280f, 0x8018, 0x90c0, 0x2602, 0x8268, 0x3620, 0xa000 }, 16, 0x000c3f60, 1},
++	{{0x5c97, 0xeaef, 0x1290, 0xea74, 0x3680, 0xa000, 0x5d94, 0x5392, 0x3c80, 0xa000, 0x6e3d, 0x30e0, 0x3fff, 0x8001, 0xeaef, 0x9cc1 }, 16, 0x000c3f80, 1},
++	{{0x6c7d, 0x2d0e, 0x8270, 0x6c7d, 0x2d0e, 0x8038, 0x3680, 0xa000, 0x9d5e, 0x9c56, 0x94c7, 0x9b56, 0xeb1e, 0x3a01, 0xa100, 0x90c0 }, 16, 0x000c3fa0, 1},
++	{{0xed68, 0x2900, 0x804e, 0x3823, 0xa000, 0xec1d, 0x2900, 0x8284, 0x3a26, 0xa000, 0xec3e, 0x3673, 0x9fef, 0xed50, 0x1115, 0x3018 }, 16, 0x000c3fc0, 1},
++	{{0x2001, 0xbffe, 0x3e06, 0xa100, 0x90c0, 0xea70, 0x90c0, 0x6c7c, 0x36cb, 0x9608, 0x3c00, 0xa104, 0x3462, 0x8001, 0x7e4e, 0x5712 }, 16, 0x000c3fe0, 1},
++	{{0xe91e, 0x3e00, 0xa004, 0x3062, 0x8001, 0x5513, 0x3660, 0x8001, 0x5611, 0x3a06, 0xa400, 0x7e68, 0x3617, 0x80ff, 0xd992, 0x9ac0 }, 16, 0x000c4000, 1},
++	{{0x66e6, 0xd5c0, 0x7bc1, 0xeeef, 0x802f, 0x3880, 0xa000, 0x7475, 0xef6c, 0x4712, 0x5597, 0x2c41, 0x35e8, 0x3fff, 0xbfff, 0x2468 }, 16, 0x000c4020, 1},
++	{{0x4097, 0x80b3, 0x0597, 0x3144, 0x20f4, 0x800c, 0x2d10, 0x0292, 0xee6c, 0x3620, 0xa000, 0x5590, 0x5796, 0x3a00, 0xa805, 0x3b07 }, 16, 0x000c4040, 1},
++	{{0x8001, 0x75d7, 0xef68, 0x3e20, 0xa00c, 0x7fc9, 0x7dc8, 0x5217, 0x35e0, 0x3000, 0x807f, 0x3a00, 0xa20d, 0x67e1, 0x65e1, 0x3500 }, 16, 0x000c4060, 1},
++	{{0x8003, 0x3820, 0xb848, 0x6cdb, 0x74f0, 0x4017, 0x3640, 0xa000, 0x7ce9, 0x5296, 0x3400, 0xa004, 0x7751, 0x3400, 0xa004, 0x7f49 }, 16, 0x000c4080, 1},
++	{{0x3400, 0xa804, 0x71f6, 0x3606, 0xa008, 0x7ccc, 0xd2d7, 0x3602, 0xa004, 0x7ec1, 0x64e1, 0x3402, 0xa004, 0x66e1, 0x3402, 0xa800 }, 16, 0x000c40a0, 1},
++	{{0x6cc5, 0x92c2, 0x7cec, 0x73f1, 0xd059, 0x92c3, 0x7c41, 0x3403, 0xa004, 0x6e51, 0x3403, 0xa040, 0x6cd7, 0x3607, 0xb008, 0x7ce2 }, 16, 0x000c40c0, 1},
++	{{0x7171, 0x6d7d, 0x3423, 0xa000, 0x4217, 0x4590, 0x3480, 0xa000, 0x4212, 0x4296, 0x98c0, 0x65e1, 0x5794, 0x2d0e, 0x824e, 0x7273 }, 16, 0x000c40e0, 1},
++	{{0x92c3, 0x6e10, 0x92c2, 0xc481, 0x6669, 0x90c0, 0x92c2, 0xc1ef, 0x94c6, 0x802a, 0xdc87, 0x92c2, 0x4194, 0x0907, 0xa010, 0x4794 }, 16, 0x000c4100, 1},
++	{{0x5216, 0x7d44, 0x3518, 0x87f0, 0x7370, 0x90c0, 0x94c3, 0x5794, 0xc1ef, 0x92c3, 0xdc87, 0x92c3, 0x4194, 0x94c0, 0xcd5f, 0xcc5e }, 16, 0x000c4120, 1},
++	{{0x9f70, 0x3660, 0xa000, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3421, 0x3694, 0x8009, 0xc39c, 0x6a13, 0x94c0, 0xc844 }, 16, 0x000c4140, 1},
++	{{0x9f71, }, 1, 0x000c4160, 1},
++	{{0xf947, 0x0000, 0x0009, 0xe140, 0x2cf9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0100, 0x5434, 0x0008, 0x4000 }, 16, 0x00080128, 1},
++	{{0x0101, 0xd520, 0x0009, 0xe100, 0x0100, 0x0800, 0x000b, 0xf000, 0x0100, 0x1162, 0x000c, 0x3000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080148, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080168, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080188, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000801a8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000801c8, 1},
++	{{0x0000, 0x0000, 0x0000, 0x0000, 0x0800, 0x9331, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, 12, 0x000801e8, 1},
++};
++const unsigned short zl_firmwareBlockSize = 16;
++const unsigned long programBaseAddress = 0x00080200;
++const unsigned long executionAddress = 0x0009e140;
++const unsigned char haveProgramBaseAddress = 1;
++const unsigned short firmwareStreamLen = 4704;
+diff --git a/sound/soc/codecs/zl380tw_firmware.h b/sound/soc/codecs/zl380tw_firmware.h
+new file mode 100644
+index 00000000..ba6b1fc4
+--- /dev/null
++++ b/sound/soc/codecs/zl380tw_firmware.h
+@@ -0,0 +1,27 @@
++#ifndef __ZL380TW_FIRMWARE_H_
++#define __ZL380TW_FIRMWARE_H_
++
++#define ZL380XX_FWR_BLOCK_SIZE 16
++typedef struct {
++    unsigned short buf[ZL380XX_FWR_BLOCK_SIZE];     /*the firmware data block to send to the device*/
++    unsigned char numWords;     /*the number of words within the block of data stored in buf[]*/
++    unsigned long targetAddr;   /*the target base address to write to register 0x00c of the device*/
++    unsigned char useTargetAddr; /*this value is either 0 or 1. When 1 the tarGetAddr must be written to the device*/
++} twFwr;
++
++typedef struct {
++    twFwr *st_Fwr;
++    unsigned char havePrgmBase;
++    unsigned long prgmBase;
++    unsigned long execAddr;            /*The execution start address of the firmware in RAM*/
++    unsigned short twFirmwareStreamLen; /*The number of blocks within the firmware*/
++    unsigned long byteCount;           /*The total number of bytes within the firmware - NOT USED*/
++} twFirmware;
++
++extern const twFwr st_twFirmware[];
++extern const unsigned short firmwareStreamLen;
++extern const unsigned long programBaseAddress; 
++extern const unsigned long executionAddress;
++extern const unsigned char haveProgramBaseAddress;
++extern const unsigned short zl_firmwareBlockSize;
++#endif
+diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile
+index 926cbf3e..2c5a1973 100644
+--- a/tools/lib/lk/Makefile
++++ b/tools/lib/lk/Makefile
+@@ -1,5 +1,8 @@
+ include ../../scripts/Makefile.include
+ 
++CC = $(CROSS_COMPILE)gcc
++AR = $(CROSS_COMPILE)ar
++
+ # guard against environment variables
+ LIB_H=
+ LIB_OBJS=
diff --git a/br-ext-chip-ambarella/board/s3l/kernel/patches/11_fix_yylloc_for_modern_computers.patch b/br-ext-chip-ambarella/board/s3l/kernel/patches/0011-fix-yylloc-for-modern-computers.patch
similarity index 100%
rename from br-ext-chip-ambarella/board/s3l/kernel/patches/11_fix_yylloc_for_modern_computers.patch
rename to br-ext-chip-ambarella/board/s3l/kernel/patches/0011-fix-yylloc-for-modern-computers.patch
diff --git a/br-ext-chip-ambarella/board/s3l/kernel/patches/00_s3l_kernel-3.10.104_sdk-Vwriteme.patch b/br-ext-chip-ambarella/board/s3l/kernel/patches/00_s3l_kernel-3.10.104_sdk-Vwriteme.patch
deleted file mode 100644
index 792d6005..00000000
--- a/br-ext-chip-ambarella/board/s3l/kernel/patches/00_s3l_kernel-3.10.104_sdk-Vwriteme.patch
+++ /dev/null
@@ -1 +0,0 @@
-#
diff --git a/br-ext-chip-ambarella/board/s3l/kernel/s3l.generic.config b/br-ext-chip-ambarella/board/s3l/kernel/s3l.generic.config
index 792d6005..ee1c94a4 100644
--- a/br-ext-chip-ambarella/board/s3l/kernel/s3l.generic.config
+++ b/br-ext-chip-ambarella/board/s3l/kernel/s3l.generic.config
@@ -1 +1,2461 @@
 #
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.104 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_KERNEL_XZ=y
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
+CONFIG_PLAT_AMBARELLA_CORTEX=y
+# CONFIG_PLAT_AMBARELLA_CORTEX_SMP is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
+CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
+CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2E is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+# CONFIG_PLAT_AMBARELLA_S3 is not set
+CONFIG_PLAT_AMBARELLA_S3L=y
+
+#
+# Generic Platform Configuration
+#
+CONFIG_AMBARELLA_CALC_PLL=y
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
+
+#
+# Sys file system support
+#
+# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0x00208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
+CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=16
+CONFIG_AMBARELLA_EXT_GPIO_NUM=16
+CONFIG_AMBARELLA_SREF_FIFO_EXEC=y
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_KUSER_HELPERS is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+# CONFIG_CACHE_PL310_EARLY_BRESP is not set
+CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
+# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
+# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+# CONFIG_PL310_ERRATA_753970 is not set
+# CONFIG_ARM_ERRATA_754322 is not set
+# CONFIG_PL310_ERRATA_769419 is not set
+# CONFIG_ARM_ERRATA_775420 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_WLAN_UPDATE_SEQ is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_GRE is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_FW_LOADER_USER_HELPER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLOCK_AMBRO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_SPINAND_AMBARELLA is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=y
+CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+CONFIG_MICREL_PHY_KSZ80X1R=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_ATH_CARDS=m
+# CONFIG_ATH_DEBUG is not set
+# CONFIG_ATH9K is not set
+# CONFIG_ATH9K_HTC is not set
+# CONFIG_CARL9170 is not set
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_SDIO=m
+# CONFIG_ATH6KL_USB is not set
+# CONFIG_ATH6KL_DEBUG is not set
+# CONFIG_AR5523 is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+# CONFIG_MWIFIEX_USB is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=m
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+# CONFIG_SPI_SLAVE_AMBARELLA is not set
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=m
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_FONT_AUTOSELECT=y
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+CONFIG_SND_AMBARELLA_CODEC=m
+CONFIG_SND_SOC_AK4642_AMB=m
+CONFIG_SND_SOC_AK4951_AMB=m
+CONFIG_SND_SOC_AK4954_AMB=m
+CONFIG_SND_SOC_AK7719_DSP=m
+# CONFIG_SND_SOC_AK7755 is not set
+# CONFIG_SND_SOC_TLV320ADC3xxx is not set
+# CONFIG_SND_SOC_ES8388 is not set
+# CONFIG_SND_SOC_ES8374 is not set
+# CONFIG_SND_SOC_WM8974_AMB is not set
+# CONFIG_SND_SOC_WM8940_AMB is not set
+# CONFIG_SND_SOC_ZL380TW is not set
+# CONFIG_SND_SOC_RT5670 is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=m
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEFAULT_PERSIST is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=m
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_U1960 is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_AMB_STREAM is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_MULTI_RNDIS=y
+# CONFIG_USB_G_MULTI_CDC is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_AMBARELLA_EMMC_BOOT is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_AMBARELLA_VIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTR is not set
+CONFIG_SQUASHFS_ZLIB=y
+# CONFIG_SQUASHFS_LZO is not set
+CONFIG_SQUASHFS_XZ=y
+# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V2 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LKDTM is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/br-ext-chip-ambarella/configs/unknown_unknown_s3l_openipc_defconfig b/br-ext-chip-ambarella/configs/unknown_unknown_s3l_openipc_defconfig
index 313c21a3..c5cfbacf 100644
--- a/br-ext-chip-ambarella/configs/unknown_unknown_s3l_openipc_defconfig
+++ b/br-ext-chip-ambarella/configs/unknown_unknown_s3l_openipc_defconfig
@@ -34,15 +34,16 @@ BR2_LINUX_KERNEL_EXT_AMBARELLA_PATCHER_LIST="$(BR2_EXTERNAL_AMBARELLA_PATH)/boar
 
 # Filesystem
 # BR2_TARGET_TZ_INFO is not set
-BR2_TARGET_ROOTFS_CPIO=y
+# BR2_TARGET_ROOTFS_CPIO=y
 BR2_TARGET_ROOTFS_SQUASHFS=y
 BR2_TARGET_ROOTFS_SQUASHFS4_XZ=y
+BR2_TARGET_ROOTFS_UBI=y
 BR2_ROOTFS_OVERLAY="$(TOPDIR)/../general/overlay"
 BR2_ROOTFS_POST_BUILD_SCRIPT="$(TOPDIR)/../scripts/executing_commands_for_$(BR2_TOOLCHAIN_BUILDROOT_LIBC).sh"
 
 # OpenIPC configuration
 BR2_TOOLCHAIN_BUILDROOT_VENDOR="openipc"
-BR2_TARGET_GENERIC_ISSUE="Welcome to OpenIPC v2.1"
+BR2_TARGET_GENERIC_ISSUE="Welcome to OpenIPC v2.2"
 BR2_TARGET_GENERIC_HOSTNAME="openipc-s3l"
 BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../general/package/all-patches"
 
@@ -51,7 +52,7 @@ BR2_PACKAGE_BUSYBOX_CONFIG="$(TOPDIR)/../general/package/busybox/busybox.config"
 BR2_PACKAGE_DROPBEAR_OPENIPC=y
 # BR2_PACKAGE_FDK_AAC_OPENIPC is not set
 BR2_PACKAGE_FWPRINTENV_OPENIPC=y
-# BR2_PACKAGE_AMBARELLA_OSDRV_S3L is not set
+BR2_PACKAGE_AMBARELLA_OSDRV_S3L=y
 BR2_PACKAGE_HASERL=y
 BR2_PACKAGE_HISI_GPIO=y
 BR2_PACKAGE_IPCTOOL=y
@@ -95,5 +96,5 @@ BR2_PACKAGE_LINUX_FIRMWARE_OPENIPC_MT7601U=y
 # BR2_PACKAGE_RTL8188EU is not set
 
 # WIREGUARD
-BR2_PACKAGE_WIREGUARD_LINUX_COMPAT=y
-BR2_PACKAGE_WIREGUARD_TOOLS=y
+# BR2_PACKAGE_WIREGUARD_LINUX_COMPAT=y
+# BR2_PACKAGE_WIREGUARD_TOOLS=y
diff --git a/br-ext-chip-ambarella/external.mk b/br-ext-chip-ambarella/external.mk
index 989ae8a8..20a64454 100644
--- a/br-ext-chip-ambarella/external.mk
+++ b/br-ext-chip-ambarella/external.mk
@@ -1,4 +1,5 @@
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/linux/linux-ext-ambarella_patcher.mk
+include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/ambarella-osdrv-s3l.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella_patcher/ambarella_patcher.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/aura-httpd/aura-httpd.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/dropbear-openipc/dropbear-openipc.mk
@@ -15,7 +16,7 @@ include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/libsrt-openipc/libsrt-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/libwebsockets-openipc/libwebsockets-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/linux-firmware-openipc/linux-firmware-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/majestic-fonts/majestic-fonts.mk
-include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/majestic/majestic.mk
+#include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/majestic/majestic.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/mbedtls-openipc/mbedtls-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/microbe-web/microbe-web.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/motors/motors.mk
@@ -24,4 +25,4 @@ include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/opus-openipc/opus-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/rtl8188fu-openipc/rtl8188fu-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/uacme-openipc/uacme-openipc.mk
 include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/vtund-openipc/vtund-openipc.mk
-include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/yaml-cli/yaml-cli.mk
\ No newline at end of file
+include $(BR2_EXTERNAL_AMBARELLA_PATH)/package/yaml-cli/yaml-cli.mk
diff --git a/br-ext-chip-ambarella/linux/linux-ext-ingenic_patcher.mk b/br-ext-chip-ambarella/linux/linux-ext-ambarella_patcher.mk
similarity index 100%
rename from br-ext-chip-ambarella/linux/linux-ext-ingenic_patcher.mk
rename to br-ext-chip-ambarella/linux/linux-ext-ambarella_patcher.mk
diff --git a/br-ext-chip-ambarella/package/ambarella-osdrv-s3l b/br-ext-chip-ambarella/package/ambarella-osdrv-s3l
new file mode 120000
index 00000000..d7c65156
--- /dev/null
+++ b/br-ext-chip-ambarella/package/ambarella-osdrv-s3l
@@ -0,0 +1 @@
+../../general/package/ambarella-osdrv-s3l
\ No newline at end of file
diff --git a/br-ext-chip-ambarella/package/ambarella_patcher b/br-ext-chip-ambarella/package/ambarella_patcher
new file mode 120000
index 00000000..5262f77d
--- /dev/null
+++ b/br-ext-chip-ambarella/package/ambarella_patcher
@@ -0,0 +1 @@
+../../general/package/ambarella_patcher
\ No newline at end of file
diff --git a/building.sh b/building.sh
index 30d9d493..09bd5d95 100755
--- a/building.sh
+++ b/building.sh
@@ -73,6 +73,13 @@ sdk() {
 
 #################################################################################
 
+ambarella-s3l() {
+  soc="s3l"
+  fresh && make PLATFORM=ambarella BOARD=unknown_unknown_${soc}_openipc all && rename
+}
+
+#################################################################################
+
 ak3918ev200() {
   soc="ak3918ev200"
   fresh && make PLATFORM=anyka BOARD=unknown_unknown_${soc}_openipc all && rename
@@ -419,6 +426,11 @@ xm550() {
 #################################################################################
 
 # Build firmware
+#######
+#
+ambarella-s3l                   # testing..
+#
+#######
 #
 # ak3918ev200                   # testing..
 #
diff --git a/general/package/ambarella-osdrv-s3l/Config.in b/general/package/ambarella-osdrv-s3l/Config.in
new file mode 100644
index 00000000..c974e3b3
--- /dev/null
+++ b/general/package/ambarella-osdrv-s3l/Config.in
@@ -0,0 +1,6 @@
+config BR2_PACKAGE_AMBARELLA_OSDRV_S3L
+	bool "ambarella-osdrv-s3l"
+	help
+	  ambarella-osdrv-s3l - Ambarella kernel modules and libs
+
+	  https://openipc.org
diff --git a/general/package/ambarella-osdrv-s3l/ambarella-osdrv-s3l.mk b/general/package/ambarella-osdrv-s3l/ambarella-osdrv-s3l.mk
new file mode 100644
index 00000000..a7b1de4a
--- /dev/null
+++ b/general/package/ambarella-osdrv-s3l/ambarella-osdrv-s3l.mk
@@ -0,0 +1,34 @@
+################################################################################
+#
+# ambarella-osdrv-s3l
+#
+################################################################################
+
+AMBARELLA_OSDRV_S3L_VERSION =
+AMBARELLA_OSDRV_S3L_SITE =
+AMBARELLA_OSDRV_S3L_LICENSE = MIT
+AMBARELLA_OSDRV_S3L_LICENSE_FILES = LICENSE
+
+
+define AMBARELLA_OSDRV_S3L_INSTALL_TARGET_CMDS
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/etc/init.d
+	$(INSTALL) -m 755 -t $(TARGET_DIR)/etc/init.d $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/files/script/S95ambarella
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/etc/sensors
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/etc/sensors $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/files/sensor/config/*.cfg
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/lib/modules/3.10.104/ambarella	
+	$(INSTALL) -m 644 -t $(TARGET_DIR)/lib/modules/3.10.104/ambarella $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/files/kmod/*.ko
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/bin
+	$(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/files/script/load_ambarella
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib/sensors
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib/sensors $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/files/sensor/*.so
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib
+
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib/ $(BR2_EXTERNAL_AMBARELLA_PATH)/package/ambarella-osdrv-s3l/files/lib/xxx.so
+endef
+
+$(eval $(generic-package))
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/adv7441a.ko b/general/package/ambarella-osdrv-s3l/files/kmod/adv7441a.ko
new file mode 100644
index 00000000..0c58cd9f
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/adv7441a.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ambad.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ambad.ko
new file mode 100644
index 00000000..db4a39ac
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ambad.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ambdbus.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ambdbus.ko
new file mode 100644
index 00000000..66a15121
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ambdbus.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ambdd.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ambdd.ko
new file mode 100644
index 00000000..f8c390ab
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ambdd.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ambhdmi.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ambhdmi.ko
new file mode 100644
index 00000000..4d8e01c5
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ambhdmi.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ambtve.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ambtve.ko
new file mode 100644
index 00000000..8537d259
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ambtve.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ar0230.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ar0230.ko
new file mode 100644
index 00000000..13ba99dc
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ar0230.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ar0237.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ar0237.ko
new file mode 100644
index 00000000..60c6da7d
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ar0237.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/dsp.ko b/general/package/ambarella-osdrv-s3l/files/kmod/dsp.ko
new file mode 100644
index 00000000..610e4cf3
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/dsp.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/dsplog.ko b/general/package/ambarella-osdrv-s3l/files/kmod/dsplog.ko
new file mode 100644
index 00000000..68ca7f0f
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/dsplog.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/hw_timer.ko b/general/package/ambarella-osdrv-s3l/files/kmod/hw_timer.ko
new file mode 100644
index 00000000..a0c67882
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/hw_timer.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/iav.ko b/general/package/ambarella-osdrv-s3l/files/kmod/iav.ko
new file mode 100644
index 00000000..7cd5bb26
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/iav.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imgproc.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imgproc.ko
new file mode 100644
index 00000000..620ef433
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imgproc.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx172.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx172.ko
new file mode 100644
index 00000000..b2616921
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx172.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx178.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx178.ko
new file mode 100644
index 00000000..92c996a6
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx178.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx226.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx226.ko
new file mode 100644
index 00000000..054a4db5
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx226.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx274_mipi.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx274_mipi.ko
new file mode 100644
index 00000000..34886f8f
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx274_mipi.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx290.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx290.ko
new file mode 100644
index 00000000..398da0b7
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx290.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx290_mipi.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx290_mipi.ko
new file mode 100644
index 00000000..c8542620
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx290_mipi.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx326.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx326.ko
new file mode 100644
index 00000000..153d2f9a
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx326.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/imx326_mipi.ko b/general/package/ambarella-osdrv-s3l/files/kmod/imx326_mipi.ko
new file mode 100644
index 00000000..4532b317
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/imx326_mipi.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/it66121.ko b/general/package/ambarella-osdrv-s3l/files/kmod/it66121.ko
new file mode 100644
index 00000000..cf8ee9e7
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/it66121.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ov2718_mipi.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ov2718_mipi.ko
new file mode 100644
index 00000000..2c198828
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ov2718_mipi.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/ov4689_mipi.ko b/general/package/ambarella-osdrv-s3l/files/kmod/ov4689_mipi.ko
new file mode 100644
index 00000000..51fcd99c
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/ov4689_mipi.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/kmod/vout.ko b/general/package/ambarella-osdrv-s3l/files/kmod/vout.ko
new file mode 100644
index 00000000..c5f24d2f
Binary files /dev/null and b/general/package/ambarella-osdrv-s3l/files/kmod/vout.ko differ
diff --git a/general/package/ambarella-osdrv-s3l/files/lib/.gitkeep b/general/package/ambarella-osdrv-s3l/files/lib/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/general/package/ambarella-osdrv-s3l/files/script/S95ambarella b/general/package/ambarella-osdrv-s3l/files/script/S95ambarella
new file mode 100755
index 00000000..48637f76
--- /dev/null
+++ b/general/package/ambarella-osdrv-s3l/files/script/S95ambarella
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+DAEMON="majestic"
+PIDFILE="/var/run/$DAEMON.pid"
+
+DAEMON_ARGS="-s"
+
+# shellcheck source=/dev/null
+[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"
+
+load_majestic() {
+	printf 'Starting %s: ' "$DAEMON"
+	[ -f /usr/bin/$DAEMON ] || echo -en "DISABLED, "
+	# shellcheck disable=SC2086 # we need the word splitting
+	start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/usr/bin/$DAEMON" \
+		-- $DAEMON_ARGS
+	status=$?
+	if [ "$status" -eq 0 ]; then
+		echo "OK"
+	else
+		echo "FAIL"
+	fi
+	return "$status"
+}
+
+# The daemon does not create a pidfile, and use "-m" to instruct start-stop-daemon to create one.
+start() {
+	logger -s -p daemon.info -t anyka "Check MAC for Xiongmai devices"
+	if [ "$(fw_printenv -n ethaddr)" = "00:00:23:34:45:66" ]; then
+		logger -s -p daemon.info -t anyka "The eth0 interface has a lousy MAC, let's try to change it.."
+		XMMAC="$(ipcinfo --xm_mac)" && [ -n "${XMMAC}" ] && fw_setenv ethaddr ${XMMAC} && reboot -f || logger -s -p daemon.info -t anyka "It is not possible to install a new MAC on the eth0 interface.."
+	else
+		logger -s -p daemon.info -t anyka "The eth0 interface has a correct MAC - $(fw_printenv -n ethaddr)"
+	fi
+	#
+	logger -s -p daemon.info -t anyka "Loading of kernel modules and initialization of the video system has started"
+	export TZ=$(cat /etc/TZ)
+	#load_anyka
+	#
+	#load_majestic
+}
+
+stop() {
+	printf 'Stopping %s: ' "$DAEMON"
+	[ -f /usr/bin/$DAEMON ] || echo -en "DISABLED, "
+	start-stop-daemon -K -q -p "$PIDFILE"
+	status=$?
+	if [ "$status" -eq 0 ]; then
+		rm -f "$PIDFILE"
+		echo "OK"
+	else
+		echo "FAIL"
+	fi
+	return "$status"
+}
+
+restart() {
+	stop
+	sleep 1
+	reload
+}
+
+reload() {
+	load_majestic
+}
+
+case "$1" in
+	start|stop|restart|reload)
+		"$1";;
+	*)
+		echo "Usage: $0 {start|stop|restart|reload}"
+		exit 1
+esac
diff --git a/general/package/ambarella-osdrv-s3l/files/script/load_ambarella b/general/package/ambarella-osdrv-s3l/files/script/load_ambarella
new file mode 100755
index 00000000..e69de29b
diff --git a/general/package/ambarella-osdrv-s3l/files/sensor/.gitkeep b/general/package/ambarella-osdrv-s3l/files/sensor/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/general/package/ambarella_patcher/Config.in b/general/package/ambarella_patcher/Config.in
new file mode 100644
index 00000000..555f039e
--- /dev/null
+++ b/general/package/ambarella_patcher/Config.in
@@ -0,0 +1,3 @@
+
+config BR2_PACKAGE_AMBARELLA_PATCHER
+	bool
diff --git a/general/package/ambarella_patcher/ambarella_patcher.mk b/general/package/ambarella_patcher/ambarella_patcher.mk
new file mode 100644
index 00000000..f1c0809d
--- /dev/null
+++ b/general/package/ambarella_patcher/ambarella_patcher.mk
@@ -0,0 +1,13 @@
+################################################################################
+#
+# ambarella_patcher
+#
+################################################################################
+
+AMBARELLA_PATCHER_VERSION = 0.1
+AMBARELLA_PATCHER_INSTALL_TARGET = NO
+AMBARELLA_PATCHER_INSTALL_STAGING = NO
+AMBARELLA_PATCHER_SITE =
+AMBARELLA_PATCHER_SOURCE =
+
+$(eval $(generic-package))
diff --git a/general/package/ambarella_patcher/apply.sh b/general/package/ambarella_patcher/apply.sh
new file mode 100755
index 00000000..5478ba2b
--- /dev/null
+++ b/general/package/ambarella_patcher/apply.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+function log() {
+    echo "--- $@"
+}
+
+function apply_patch() {
+    DST=$1
+    SRC=$2
+
+    if [[ -d $SRC ]]; then
+        if [[ ${SRC:${#SRC}-1} != '/' ]]; then
+            log Apply \"$SRC\" as overlay directory
+            cp -r $SRC/* $DST/
+        else
+            log Apply \"$SRC\" as patches directory
+            for P in $SRC/*.patch; do
+                patch -d $DST -p1 < $P
+            done
+        fi
+    else
+        log Apply \"$SRC\" as single patch
+        patch -d $DST -p1 < $SRC
+    fi
+}
+
+function apply_patches() {
+    log Gonna apply "$@"
+    while [[ $# -ge 1 ]]; do
+        apply_patch $DST $1
+        shift
+    done
+}
+
+DST=$1
+shift
+
+if [ -f $DST/.ambarella-patched ]; then
+    log Patched already
+    exit
+fi
+
+apply_patches $@
+touch $DST/.ambarella-patched