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 = <ð_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 = <ð_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 = <ð_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 = <ð_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 = <ð_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, §); ++ 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 = ¶m->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, ¶m); ++} ++ ++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 = ®_set_6050, ++ .config = &chip_config_6050, ++ }, ++ { ++ .whoami = INV_MPU6500_WHOAMI_VALUE, ++ .name = "MPU6500", ++ .reg = ®_set_6500, ++ .config = &chip_config_6050, ++ }, ++ { ++ .whoami = INV_MPU6000_WHOAMI_VALUE, ++ .name = "MPU6000", ++ .reg = ®_set_6050, ++ .config = &chip_config_6050, ++ }, ++ { ++ .whoami = INV_MPU9150_WHOAMI_VALUE, ++ .name = "MPU9150", ++ .reg = ®_set_6050, ++ .config = &chip_config_6050, ++ }, ++ { ++ .whoami = INV_MPU9250_WHOAMI_VALUE, ++ .name = "MPU9250", ++ .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, ®val); ++ 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, ×tamp, 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, ×tamp, 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)®)|(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)®)|(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", ®)) ++ 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", ®)) ++ 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(¬ify, (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(¬ify_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